This is an automated email from the ASF dual-hosted git repository. mercyblitz pushed a commit to branch 2.7.8-dev in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/2.7.8-dev by this push: new bc48b41 2.7.8 release (#6403) bc48b41 is described below commit bc48b4145d6b796ad938c3099e5b90b02234809e Author: Mercy Ma <mercybl...@gmail.com> AuthorDate: Wed Jul 1 15:45:00 2020 +0800 2.7.8 release (#6403) * Polish apache/dubbo#6296 : Adding the new methods into MetadataReport to manipulate the exported URLs for service introspection * Polish apache/dubbo#6296 : Adding the new methods into MetadataReport to manipulate the exported URLs for service introspection * Polish apache/dubbo#6171 : [Feature] Introducing the composite implementation of MetadataService * Revert "fix wrong check of InvokerListener when export a service (fix issue_6269) (#6271)" This reverts commit 91989cae508f8482f31ac335879da4a5975661c8. * Revert "fix wrong check of InvokerListener when export a service (fix issue_6269) (#6271)" This reverts commit 91989cae508f8482f31ac335879da4a5975661c8. * Revert the MetadataReport * Polish apache/dubbo#6305 : [Refactor] ServiceConfig and ReferenceConfig publish the ServiceDefinition based on the Dubbo Event * Polish apache/dubbo#6198 : [Issue] Fixing NacosDynamicConfiguration#publishConfig bug * Polish apache/dubbo#6310 : Refactoring MetadataReport's methods * Polish apache/dubbo#6198 : [Issue] Fixing NacosDynamicConfiguration#publishConfig bug * Polish apache/dubbo#6198 : [Issue] Fixing NacosDynamicConfiguration#publishConfig bug * Polish apache/dubbo#6315 : [Refactor] Refactoring the implementation of MetadataReport based on The Config-Center infrastructure Deprecated List : - NacosMetadataReport - ZookeeperMetadataReport * Polish apache/dubbo#6315 : Refactoring by TreePathDynamicConfiguration * Polish apache/dubbo#6315 : Refactoring ConsulDynamicConfiguration by TreePathDynamicConfiguration * Polish apache/dubbo#6315 : Reset the config base path to be "metadata" for ConfigCenterBasedMetadataReportFactory * Polish apache/dubbo#6315 : Bugfix * Polish apache/dubbo#6315 : Bugfix * Polish apache/dubbo#6315 : Correct words * sync wait netty server to finish shutdown (#6281) * Polish apache/dubbo#6333 : [Refactor] Using mandatory implementation of Service Instance registration instead of the event * maybe we can remove null judge in this case (#6321) * update * update * Polish apache/dubbo#6336 : [Refactor] org.apache.dubbo.metadata.ServiceNameMapping * Polish apache/dubbo#6170 : [Feature] Introducing the externalized configuration for ServiceNameMapping * Polish apache/dubbo#6342 : [Enhancement] Introducing the composite ServiceNameMapping * Refactor * fix method name typo in JValidator.java (#6344) * [Dubbo-6340]fix application cannot exit when use consul registry (#6341) * fix application cannot exit when use consul registry * make consul registry suppor ACL (#6313) * make consul registry suppor ACL * Polish apache/dubbo#6172 : [Feature] Adding the "services" attribute methods into @DubboReference * Polish apache/dubbo#6173 : [Feature] Adding the "services" attribute into <dubbo:reference> element * Polish apache/dubbo#6346 : [Issue] Merging all subscribied URLs from the multiple services * Polish apache/dubbo#6346 : [Issue] Merging all subscribied URLs from the multiple services * fix publish null value when use consul config center (#6351) * fix publish null value when use consul config center * Polish apache/dubbo#6252 * Polish apache/dubbo#6356 & apache/dubbo#6171 * Polish apache/dubbo#6356 & apache/dubbo#6171 * Polish apache/dubbo#6224 : Filter chain was not invoked with local calls since v2.7.6 * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : Adding META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter * fix the priority of ListenableRouter were not effective (#6148) fixes #4822 * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * when the url is generic, the log level should be info (#6363) * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * fix NPE when check=false is set and provider is empty. (#6376) fixes #6228 * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * fix #6306. support TypeBuilder sort (#6365) * fix #6306. support TypeBuilder sort * fix #6306. support TypeBuilder sort * fix #6306. support TypeBuilder sort * remove unused import * add license for test file * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * enhance ClusterInvoker & ExtensionLoader (#6343) - Introduce ClusterInvoker to better support multiple registries subscription - Wrapper sort and enable/disable - some small fixes * Polish apache/dubbo#6322 : [Enhancement] Fix the issues of test-cases after refactoring * Fixed the test-cases * Polish apache/dubbo#6389 : [Issue] Resolving the issues with ConsulServiceDiscovery Co-authored-by: tswstarplanet <tswstarpla...@apache.org> Co-authored-by: Nine <nine.yang.cod...@gmail.com> Co-authored-by: 陈哈哈 <chenyongjia...@outlook.com> Co-authored-by: luoning810 <18311333...@163.com> Co-authored-by: cvictory <shenglic...@gmail.com> Co-authored-by: ken.lj <ken.lj...@gmail.com> --- .../src/main/java/org/apache/dubbo/common/URL.java | 39 +- .../org/apache/dubbo/common/convert/Converter.java | 17 + .../convert/multiple/MultiValueConverter.java | 28 + .../test/java/org/apache/dubbo/common/URLTest.java | 1793 ++++++++++---------- .../convert/ConverterTest.java} | 39 +- .../convert/StringToBooleanConverterTest.java | 5 +- .../convert/StringToCharArrayConverterTest.java | 5 +- .../convert/StringToCharacterConverterTest.java | 5 +- .../convert/StringToDoubleConverterTest.java | 5 +- .../convert/StringToFloatConverterTest.java | 5 +- .../convert/StringToIntegerConverterTest.java | 5 +- .../convert/StringToLongConverterTest.java | 5 +- .../convert/StringToOptionalConverterTest.java | 5 +- .../convert/StringToShortConverterTest.java | 5 +- .../convert/StringToStringConverterTest.java | 5 +- .../convert/multiple/MultiValueConverterTest.java | 72 + .../multiple/StringToArrayConverterTest.java | 4 +- .../StringToBlockingDequeConverterTest.java | 4 +- .../StringToBlockingQueueConverterTest.java | 4 +- .../multiple/StringToCollectionConverterTest.java | 5 +- .../multiple/StringToDequeConverterTest.java | 4 +- .../multiple/StringToListConverterTest.java | 4 +- .../StringToNavigableSetConverterTest.java | 6 +- .../multiple/StringToQueueConverterTest.java | 3 +- .../convert/multiple/StringToSetConverterTest.java | 3 +- .../multiple/StringToSortedSetConverterTest.java | 6 +- .../StringToTransferQueueConverterTest.java | 6 +- .../dubbo/registry/consul/ConsulParameter.java | 87 + .../registry/consul/ConsulServiceDiscovery.java | 89 +- 29 files changed, 1265 insertions(+), 998 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java index c39f042..6ab3a89 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java @@ -57,6 +57,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY; import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.convert.Converter.convertIfPossible; +import static org.apache.dubbo.common.utils.StringUtils.isBlank; /** * URL - Uniform Resource Locator (Immutable, ThreadSafe) @@ -621,6 +623,41 @@ class URL implements Serializable { return Arrays.asList(strArray); } + /** + * Get parameter + * + * @param key the key of parameter + * @param valueType the type of parameter value + * @param <T> the type of parameter value + * @return get the parameter if present, or <code>null</code> + * @since 2.7.8 + */ + public <T> T getParameter(String key, Class<T> valueType) { + return getParameter(key, valueType, null); + } + + /** + * Get parameter + * + * @param key the key of parameter + * @param valueType the type of parameter value + * @param defaultValue the default value if parameter is absent + * @param <T> the type of parameter value + * @return get the parameter if present, or <code>defaultValue</code> will be used. + * @since 2.7.8 + */ + public <T> T getParameter(String key, Class<T> valueType, T defaultValue) { + String value = getParameter(key); + T result = null; + if (!isBlank(value)) { + result = convertIfPossible(value, valueType); + } + if (result == null) { + result = defaultValue; + } + return result; + } + private Map<String, Number> getNumbers() { // concurrent initialization is tolerant if (numbers == null) { @@ -1435,7 +1472,7 @@ class URL implements Serializable { private void append(StringBuilder target, String parameterName, boolean first) { String parameterValue = this.getParameter(parameterName); - if (!StringUtils.isBlank(parameterValue)) { + if (!isBlank(parameterValue)) { if (!first) { target.append(":"); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/convert/Converter.java b/dubbo-common/src/main/java/org/apache/dubbo/common/convert/Converter.java index 5bc2d4d..e36fdf2 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/convert/Converter.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/convert/Converter.java @@ -88,4 +88,21 @@ public interface Converter<S, T> extends Prioritized { .findFirst() .orElse(null); } + + /** + * Convert the value of source to target-type value if possible + * + * @param source the value of source + * @param targetType the target type + * @param <T> the target type + * @return <code>null</code> if can't be converted + * @since 2.7.8 + */ + static <T> T convertIfPossible(Object source, Class<T> targetType) { + Converter converter = getConverter(source.getClass(), targetType); + if (converter != null) { + return (T) converter.convert(source); + } + return null; + } } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/convert/multiple/MultiValueConverter.java b/dubbo-common/src/main/java/org/apache/dubbo/common/convert/multiple/MultiValueConverter.java index 298b459..637d1a8 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/convert/multiple/MultiValueConverter.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/convert/multiple/MultiValueConverter.java @@ -16,11 +16,13 @@ */ package org.apache.dubbo.common.convert.multiple; +import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.common.extension.SPI; import org.apache.dubbo.common.lang.Prioritized; import java.util.Collection; +import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader; import static org.apache.dubbo.common.utils.TypeUtils.findActualTypeArgument; /** @@ -61,4 +63,30 @@ public interface MultiValueConverter<S> extends Prioritized { return findActualTypeArgument(getClass(), MultiValueConverter.class, 0); } + /** + * Find the {@link MultiValueConverter} instance from {@link ExtensionLoader} with the specified source and target type + * + * @param sourceType the source type + * @param targetType the target type + * @return <code>null</code> if not found + * @see ExtensionLoader#getSupportedExtensionInstances() + * @since 2.7.8 + */ + static MultiValueConverter<?> find(Class<?> sourceType, Class<?> targetType) { + return getExtensionLoader(MultiValueConverter.class) + .getSupportedExtensionInstances() + .stream() + .filter(converter -> converter.accept(sourceType, targetType)) + .findFirst() + .orElse(null); + } + + static <T> T convertIfPossible(Object source, Class<?> multiValueType, Class<?> elementType) { + Class<?> sourceType = source.getClass(); + MultiValueConverter converter = find(sourceType, multiValueType); + if (converter != null) { + return (T) converter.convert(source, multiValueType, elementType); + } + return null; + } } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java index dc96595..5ba606d 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java @@ -1,893 +1,900 @@ -/* - * 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.dubbo.common; - -import org.apache.dubbo.common.utils.CollectionUtils; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.function.Predicate; - -import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -public class URLTest { - - @Test - public void test_valueOf_noProtocolAndHost() throws Exception { - URL url = URL.valueOf("/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertNull(url.getHost()); - assertNull(url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - - url = URL.valueOf("context/path?version=1.0.0&application=morgan"); - // ^^^^^^^ Caution , parse as host - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("context", url.getHost()); - assertEquals(0, url.getPort()); - assertEquals("path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - } - - private void assertURLStrDecoder(URL url) { - String fullURLStr = url.toFullString(); - URL newUrl = URLStrParser.parseEncodedStr(URL.encode(fullURLStr)); - assertEquals(URL.valueOf(fullURLStr), newUrl); - - URL newUrl2 = URLStrParser.parseDecodedStr(fullURLStr); - assertEquals(URL.valueOf(fullURLStr), newUrl2); - } - - @Test - public void test_valueOf_noProtocol() throws Exception { - URL url = URL.valueOf("10.20.130.230"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230", url.getAddress()); - assertEquals(0, url.getPort()); - assertNull(url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("10.20.130.230:20880"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertNull(url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("10.20.130.230/context/path"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230", url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("10.20.130.230:20880/context/path"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - } - - @Test - public void test_valueOf_noHost() throws Exception { - URL url = URL.valueOf("file:///home/user1/router.js"); - assertURLStrDecoder(url); - assertEquals("file", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertNull(url.getHost()); - assertNull(url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("home/user1/router.js", url.getPath()); - assertEquals(0, url.getParameters().size()); - - // Caution!! - url = URL.valueOf("file://home/user1/router.js"); - // ^^ only tow slash! - assertURLStrDecoder(url); - assertEquals("file", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("home", url.getHost()); - assertEquals(0, url.getPort()); - assertEquals("user1/router.js", url.getPath()); - assertEquals(0, url.getParameters().size()); - - - url = URL.valueOf("file:/home/user1/router.js"); - assertURLStrDecoder(url); - assertEquals("file", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertNull(url.getHost()); - assertNull(url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("home/user1/router.js", url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("file:///d:/home/user1/router.js"); - assertURLStrDecoder(url); - assertEquals("file", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertNull(url.getHost()); - assertNull(url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("d:/home/user1/router.js", url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("file:///home/user1/router.js?p1=v1&p2=v2"); - assertURLStrDecoder(url); - assertEquals("file", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertNull(url.getHost()); - assertNull(url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("home/user1/router.js", url.getPath()); - assertEquals(2, url.getParameters().size()); - Map<String, String> params = new HashMap<String, String>(); - params.put("p1", "v1"); - params.put("p2", "v2"); - assertEquals(params, url.getParameters()); - - url = URL.valueOf("file:/home/user1/router.js?p1=v1&p2=v2"); - assertURLStrDecoder(url); - assertEquals("file", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertNull(url.getHost()); - assertNull(url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("home/user1/router.js", url.getPath()); - assertEquals(2, url.getParameters().size()); - params = new HashMap<String, String>(); - params.put("p1", "v1"); - params.put("p2", "v2"); - assertEquals(params, url.getParameters()); - } - - @Test - public void test_valueOf_WithProtocolHost() throws Exception { - URL url = URL.valueOf("dubbo://10.20.130.230"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230", url.getAddress()); - assertEquals(0, url.getPort()); - assertNull(url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("dubbo://10.20.130.230:20880/context/path"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertNull(url.getUsername()); - assertNull(url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertNull(url.getPath()); - assertEquals(0, url.getParameters().size()); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880?version=1.0.0"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertNull(url.getPath()); - assertEquals(1, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&noValue"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(3, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - assertEquals("noValue", url.getParameter("noValue")); - } - - // TODO Do not want to use spaces? See: DUBBO-502, URL class handles special conventions for special characters. - @Test - public void test_valueOf_spaceSafe() throws Exception { - URL url = URL.valueOf("http://1.2.3.4:8080/path?key=value1 value2"); - assertURLStrDecoder(url); - assertEquals("http://1.2.3.4:8080/path?key=value1 value2", url.toString()); - assertEquals("value1 value2", url.getParameter("key")); - } - - @Test - public void test_noValueKey() throws Exception { - URL url = URL.valueOf("http://1.2.3.4:8080/path?k0&k1=v1"); - - assertURLStrDecoder(url); - assertTrue(url.hasParameter("k0")); - - // If a Key has no corresponding Value, then the Key also used as the Value. - assertEquals("k0", url.getParameter("k0")); - } - - @Test - public void test_valueOf_Exception_noProtocol() throws Exception { - try { - URL.valueOf("://1.2.3.4:8080/path"); - fail(); - } catch (IllegalStateException expected) { - assertEquals("url missing protocol: \"://1.2.3.4:8080/path\"", expected.getMessage()); - } - - try { - String encodedURLStr = URL.encode("://1.2.3.4:8080/path"); - URLStrParser.parseEncodedStr(encodedURLStr); - fail(); - } catch (IllegalStateException expected) { - assertEquals("url missing protocol: \"://1.2.3.4:8080/path\"", URL.decode(expected.getMessage())); - } - - try { - URLStrParser.parseDecodedStr("://1.2.3.4:8080/path"); - fail(); - } catch (IllegalStateException expected) { - assertEquals("url missing protocol: \"://1.2.3.4:8080/path\"", expected.getMessage()); - } - } - - @Test - public void test_getAddress() throws Exception { - URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url1); - assertEquals("10.20.130.230:20880", url1.getAddress()); - } - - @Test - public void test_getAbsolutePath() throws Exception { - URL url = new URL("p1", "1.2.2.2", 33); - assertURLStrDecoder(url); - assertNull(url.getAbsolutePath()); - - url = new URL("file", null, 90, "/home/user1/route.js"); - assertURLStrDecoder(url); - assertEquals("/home/user1/route.js", url.getAbsolutePath()); - } - - @Test - public void test_equals() throws Exception { - URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url1); - - Map<String, String> params = new HashMap<String, String>(); - params.put("version", "1.0.0"); - params.put("application", "morgan"); - URL url2 = new URL("dubbo", "admin", "hello1234", "10.20.130.230", 20880, "context/path", params); - - assertURLStrDecoder(url2); - assertEquals(url1, url2); - } - - @Test - public void test_toString() throws Exception { - URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url1); - assertThat(url1.toString(), anyOf( - equalTo("dubbo://10.20.130.230:20880/context/path?version=1.0.0&application=morgan"), - equalTo("dubbo://10.20.130.230:20880/context/path?application=morgan&version=1.0.0")) - ); - } - - @Test - public void test_toFullString() throws Exception { - URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url1); - assertThat(url1.toFullString(), anyOf( - equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"), - equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&version=1.0.0")) - ); - } - - @Test - public void test_set_methods() throws Exception { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url); - - url = url.setHost("host"); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("host", url.getHost()); - assertEquals("host:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - - url = url.setPort(1); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("host", url.getHost()); - assertEquals("host:1", url.getAddress()); - assertEquals(1, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - - url = url.setPath("path"); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("host", url.getHost()); - assertEquals("host:1", url.getAddress()); - assertEquals(1, url.getPort()); - assertEquals("path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - - url = url.setProtocol("protocol"); - - assertURLStrDecoder(url); - assertEquals("protocol", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("host", url.getHost()); - assertEquals("host:1", url.getAddress()); - assertEquals(1, url.getPort()); - assertEquals("path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - - url = url.setUsername("username"); - - assertURLStrDecoder(url); - assertEquals("protocol", url.getProtocol()); - assertEquals("username", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("host", url.getHost()); - assertEquals("host:1", url.getAddress()); - assertEquals(1, url.getPort()); - assertEquals("path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - - url = url.setPassword("password"); - - assertURLStrDecoder(url); - assertEquals("protocol", url.getProtocol()); - assertEquals("username", url.getUsername()); - assertEquals("password", url.getPassword()); - assertEquals("host", url.getHost()); - assertEquals("host:1", url.getAddress()); - assertEquals(1, url.getPort()); - assertEquals("path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - } - - @Test - public void test_removeParameters() throws Exception { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&k1=v1&k2=v2"); - assertURLStrDecoder(url); - - url = url.removeParameter("version"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(3, url.getParameters().size()); - assertEquals("morgan", url.getParameter("application")); - assertEquals("v1", url.getParameter("k1")); - assertEquals("v2", url.getParameter("k2")); - assertNull(url.getParameter("version")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&k1=v1&k2=v2"); - url = url.removeParameters("version", "application", "NotExistedKey"); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("v1", url.getParameter("k1")); - assertEquals("v2", url.getParameter("k2")); - assertNull(url.getParameter("version")); - assertNull(url.getParameter("application")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&k1=v1&k2=v2"); - url = url.removeParameters(Arrays.asList("version", "application")); - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("v1", url.getParameter("k1")); - assertEquals("v2", url.getParameter("k2")); - assertNull(url.getParameter("version")); - assertNull(url.getParameter("application")); - } - - @Test - public void test_addParameter() throws Exception { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); - url = url.addParameter("k1", "v1"); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("morgan", url.getParameter("application")); - assertEquals("v1", url.getParameter("k1")); - } - - @Test - public void test_addParameter_sameKv() throws Exception { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&k1=v1"); - URL newUrl = url.addParameter("k1", "v1"); - - assertURLStrDecoder(url); - assertSame(newUrl, url); - } - - - @Test - public void test_addParameters() throws Exception { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); - url = url.addParameters(CollectionUtils.toStringMap("k1", "v1", "k2", "v2")); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(3, url.getParameters().size()); - assertEquals("morgan", url.getParameter("application")); - assertEquals("v1", url.getParameter("k1")); - assertEquals("v2", url.getParameter("k2")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); - url = url.addParameters("k1", "v1", "k2", "v2", "application", "xxx"); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(3, url.getParameters().size()); - assertEquals("xxx", url.getParameter("application")); - assertEquals("v1", url.getParameter("k1")); - assertEquals("v2", url.getParameter("k2")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); - url = url.addParametersIfAbsent(CollectionUtils.toStringMap("k1", "v1", "k2", "v2", "application", "xxx")); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(3, url.getParameters().size()); - assertEquals("morgan", url.getParameter("application")); - assertEquals("v1", url.getParameter("k1")); - assertEquals("v2", url.getParameter("k2")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); - url = url.addParameter("k1", "v1"); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("morgan", url.getParameter("application")); - assertEquals("v1", url.getParameter("k1")); - - url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); - url = url.addParameter("application", "xxx"); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(1, url.getParameters().size()); - assertEquals("xxx", url.getParameter("application")); - } - - @Test - public void test_addParameters_SameKv() throws Exception { - { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&k1=v1"); - URL newUrl = url.addParameters(CollectionUtils.toStringMap("k1", "v1")); - - assertURLStrDecoder(url); - assertSame(url, newUrl); - } - { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&k1=v1&k2=v2"); - URL newUrl = url.addParameters(CollectionUtils.toStringMap("k1", "v1", "k2", "v2")); - - assertURLStrDecoder(url); - assertSame(newUrl, url); - } - } - - @Test - public void test_addParameterIfAbsent() throws Exception { - URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); - url = url.addParameterIfAbsent("application", "xxx"); - - assertURLStrDecoder(url); - assertEquals("dubbo", url.getProtocol()); - assertEquals("admin", url.getUsername()); - assertEquals("hello1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(1, url.getParameters().size()); - assertEquals("morgan", url.getParameter("application")); - } - - @Test - public void test_windowAbsolutePathBeginWithSlashIsValid() throws Exception { - final String osProperty = System.getProperties().getProperty("os.name"); - if (!osProperty.toLowerCase().contains("windows")) return; - - System.out.println("Test Windows valid path string."); - - File f0 = new File("C:/Windows"); - File f1 = new File("/C:/Windows"); - - File f2 = new File("C:\\Windows"); - File f3 = new File("/C:\\Windows"); - File f4 = new File("\\C:\\Windows"); - - assertEquals(f0, f1); - assertEquals(f0, f2); - assertEquals(f0, f3); - assertEquals(f0, f4); - } - - @Test - public void test_javaNetUrl() throws Exception { - java.net.URL url = new java.net.URL("http://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan#anchor1"); - - assertEquals("http", url.getProtocol()); - assertEquals("admin:hello1234", url.getUserInfo()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals(20880, url.getPort()); - assertEquals("/context/path", url.getPath()); - assertEquals("version=1.0.0&application=morgan", url.getQuery()); - assertEquals("anchor1", url.getRef()); - - assertEquals("admin:hello1234@10.20.130.230:20880", url.getAuthority()); - assertEquals("/context/path?version=1.0.0&application=morgan", url.getFile()); - } - - @Test - public void test_Anyhost() throws Exception { - URL url = URL.valueOf("dubbo://0.0.0.0:20880"); - assertURLStrDecoder(url); - assertEquals("0.0.0.0", url.getHost()); - assertTrue(url.isAnyHost()); - } - - @Test - public void test_Localhost() throws Exception { - URL url = URL.valueOf("dubbo://127.0.0.1:20880"); - assertURLStrDecoder(url); - assertEquals("127.0.0.1", url.getHost()); - assertEquals("127.0.0.1:20880", url.getAddress()); - assertTrue(url.isLocalHost()); - - url = URL.valueOf("dubbo://127.0.1.1:20880"); - assertURLStrDecoder(url); - assertEquals("127.0.1.1", url.getHost()); - assertEquals("127.0.1.1:20880", url.getAddress()); - assertTrue(url.isLocalHost()); - - url = URL.valueOf("dubbo://localhost:20880"); - assertURLStrDecoder(url); - assertEquals("localhost", url.getHost()); - assertEquals("localhost:20880", url.getAddress()); - assertTrue(url.isLocalHost()); - } - - @Test - public void test_Path() throws Exception { - URL url = new URL("dubbo", "localhost", 20880, "////path"); - assertURLStrDecoder(url); - assertEquals("path", url.getPath()); - } - - @Test - public void testAddParameters() throws Exception { - URL url = URL.valueOf("dubbo://127.0.0.1:20880"); - assertURLStrDecoder(url); - - Map<String, String> parameters = new HashMap<String, String>(); - parameters.put("version", null); - url.addParameters(parameters); - assertURLStrDecoder(url); - } - - @Test - public void testUserNamePasswordContainsAt() { - // Test username or password contains "@" - URL url = URL.valueOf("ad@min:hello@1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertEquals("ad@min", url.getUsername()); - assertEquals("hello@1234", url.getPassword()); - assertEquals("10.20.130.230", url.getHost()); - assertEquals("10.20.130.230:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - } - - - @Test - public void testIpV6Address() { - // Test username or password contains "@" - URL url = URL.valueOf("ad@min111:haha@1234@2001:0db8:85a3:08d3:1319:8a2e:0370:7344:20880/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertEquals("ad@min111", url.getUsername()); - assertEquals("haha@1234", url.getPassword()); - assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344", url.getHost()); - assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344:20880", url.getAddress()); - assertEquals(20880, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - } - - @Test - public void testIpV6AddressWithScopeId() { - URL url = URL.valueOf("2001:0db8:85a3:08d3:1319:8a2e:0370:7344%5/context/path?version=1.0.0&application=morgan"); - assertURLStrDecoder(url); - assertNull(url.getProtocol()); - assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344%5", url.getHost()); - assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344%5", url.getAddress()); - assertEquals(0, url.getPort()); - assertEquals("context/path", url.getPath()); - assertEquals(2, url.getParameters().size()); - assertEquals("1.0.0", url.getParameter("version")); - assertEquals("morgan", url.getParameter("application")); - } - - @Test - public void testDefaultPort() { - Assertions.assertEquals("10.20.153.10:2181", URL.appendDefaultPort("10.20.153.10:0", 2181)); - Assertions.assertEquals("10.20.153.10:2181", URL.appendDefaultPort("10.20.153.10", 2181)); - } - - @Test - public void testGetServiceKey() { - URL url1 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName"); - assertURLStrDecoder(url1); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName", url1.getServiceKey()); - - URL url2 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName?interface=org.apache.dubbo.test.interfaceName"); - assertURLStrDecoder(url2); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName", url2.getServiceKey()); - - URL url3 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName?interface=org.apache.dubbo.test.interfaceName&group=group1&version=1.0.0"); - assertURLStrDecoder(url3); - Assertions.assertEquals("group1/org.apache.dubbo.test.interfaceName:1.0.0", url3.getServiceKey()); - - URL url4 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName"); - assertURLStrDecoder(url4); - Assertions.assertEquals("context/path", url4.getPathKey()); - - URL url5 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group1&version=1.0.0"); - assertURLStrDecoder(url5); - Assertions.assertEquals("group1/context/path:1.0.0", url5.getPathKey()); - } - - @Test - public void testGetColonSeparatedKey() { - URL url1 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group&version=1.0.0"); - assertURLStrDecoder(url1); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName:1.0.0:group", url1.getColonSeparatedKey()); - - URL url2 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&version=1.0.0"); - assertURLStrDecoder(url2); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName:1.0.0:", url2.getColonSeparatedKey()); - - URL url3 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group"); - assertURLStrDecoder(url3); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName::group", url3.getColonSeparatedKey()); - - URL url4 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName"); - assertURLStrDecoder(url4); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName::", url4.getColonSeparatedKey()); - - URL url5 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName"); - assertURLStrDecoder(url5); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName::", url5.getColonSeparatedKey()); - - URL url6 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName?interface=org.apache.dubbo.test.interfaceName1"); - assertURLStrDecoder(url6); - Assertions.assertEquals("org.apache.dubbo.test.interfaceName1::", url6.getColonSeparatedKey()); - } - - @Test - public void testValueOf() { - URL url = URL.valueOf("10.20.130.230"); - assertURLStrDecoder(url); - - url = URL.valueOf("10.20.130.230:20880"); - assertURLStrDecoder(url); - - url = URL.valueOf("dubbo://10.20.130.230:20880"); - assertURLStrDecoder(url); - - url = URL.valueOf("dubbo://10.20.130.230:20880/path"); - assertURLStrDecoder(url); - } - - - /** - * Test {@link URL#getParameters(Predicate)} method - * - * @since 2.7.8 - */ - @Test - public void testGetParameters() { - URL url = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group&version=1.0.0"); - Map<String, String> parameters = url.getParameters(i -> "version".equals(i)); - String version = parameters.get("version"); - assertEquals(1, parameters.size()); - assertEquals("1.0.0", version); - } -} +/* + * 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.dubbo.common; + +import org.apache.dubbo.common.utils.CollectionUtils; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +public class URLTest { + + @Test + public void test_valueOf_noProtocolAndHost() throws Exception { + URL url = URL.valueOf("/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertNull(url.getHost()); + assertNull(url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + + url = URL.valueOf("context/path?version=1.0.0&application=morgan"); + // ^^^^^^^ Caution , parse as host + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("context", url.getHost()); + assertEquals(0, url.getPort()); + assertEquals("path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + } + + private void assertURLStrDecoder(URL url) { + String fullURLStr = url.toFullString(); + URL newUrl = URLStrParser.parseEncodedStr(URL.encode(fullURLStr)); + assertEquals(URL.valueOf(fullURLStr), newUrl); + + URL newUrl2 = URLStrParser.parseDecodedStr(fullURLStr); + assertEquals(URL.valueOf(fullURLStr), newUrl2); + } + + @Test + public void test_valueOf_noProtocol() throws Exception { + URL url = URL.valueOf("10.20.130.230"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230", url.getAddress()); + assertEquals(0, url.getPort()); + assertNull(url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("10.20.130.230:20880"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertNull(url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("10.20.130.230/context/path"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230", url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("10.20.130.230:20880/context/path"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + } + + @Test + public void test_valueOf_noHost() throws Exception { + URL url = URL.valueOf("file:///home/user1/router.js"); + assertURLStrDecoder(url); + assertEquals("file", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertNull(url.getHost()); + assertNull(url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("home/user1/router.js", url.getPath()); + assertEquals(0, url.getParameters().size()); + + // Caution!! + url = URL.valueOf("file://home/user1/router.js"); + // ^^ only tow slash! + assertURLStrDecoder(url); + assertEquals("file", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("home", url.getHost()); + assertEquals(0, url.getPort()); + assertEquals("user1/router.js", url.getPath()); + assertEquals(0, url.getParameters().size()); + + + url = URL.valueOf("file:/home/user1/router.js"); + assertURLStrDecoder(url); + assertEquals("file", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertNull(url.getHost()); + assertNull(url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("home/user1/router.js", url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("file:///d:/home/user1/router.js"); + assertURLStrDecoder(url); + assertEquals("file", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertNull(url.getHost()); + assertNull(url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("d:/home/user1/router.js", url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("file:///home/user1/router.js?p1=v1&p2=v2"); + assertURLStrDecoder(url); + assertEquals("file", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertNull(url.getHost()); + assertNull(url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("home/user1/router.js", url.getPath()); + assertEquals(2, url.getParameters().size()); + Map<String, String> params = new HashMap<String, String>(); + params.put("p1", "v1"); + params.put("p2", "v2"); + assertEquals(params, url.getParameters()); + + url = URL.valueOf("file:/home/user1/router.js?p1=v1&p2=v2"); + assertURLStrDecoder(url); + assertEquals("file", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertNull(url.getHost()); + assertNull(url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("home/user1/router.js", url.getPath()); + assertEquals(2, url.getParameters().size()); + params = new HashMap<String, String>(); + params.put("p1", "v1"); + params.put("p2", "v2"); + assertEquals(params, url.getParameters()); + } + + @Test + public void test_valueOf_WithProtocolHost() throws Exception { + URL url = URL.valueOf("dubbo://10.20.130.230"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230", url.getAddress()); + assertEquals(0, url.getPort()); + assertNull(url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("dubbo://10.20.130.230:20880/context/path"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertNull(url.getUsername()); + assertNull(url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertNull(url.getPath()); + assertEquals(0, url.getParameters().size()); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880?version=1.0.0"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertNull(url.getPath()); + assertEquals(1, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&noValue"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(3, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + assertEquals("noValue", url.getParameter("noValue")); + } + + // TODO Do not want to use spaces? See: DUBBO-502, URL class handles special conventions for special characters. + @Test + public void test_valueOf_spaceSafe() throws Exception { + URL url = URL.valueOf("http://1.2.3.4:8080/path?key=value1 value2"); + assertURLStrDecoder(url); + assertEquals("http://1.2.3.4:8080/path?key=value1 value2", url.toString()); + assertEquals("value1 value2", url.getParameter("key")); + } + + @Test + public void test_noValueKey() throws Exception { + URL url = URL.valueOf("http://1.2.3.4:8080/path?k0&k1=v1"); + + assertURLStrDecoder(url); + assertTrue(url.hasParameter("k0")); + + // If a Key has no corresponding Value, then the Key also used as the Value. + assertEquals("k0", url.getParameter("k0")); + } + + @Test + public void test_valueOf_Exception_noProtocol() throws Exception { + try { + URL.valueOf("://1.2.3.4:8080/path"); + fail(); + } catch (IllegalStateException expected) { + assertEquals("url missing protocol: \"://1.2.3.4:8080/path\"", expected.getMessage()); + } + + try { + String encodedURLStr = URL.encode("://1.2.3.4:8080/path"); + URLStrParser.parseEncodedStr(encodedURLStr); + fail(); + } catch (IllegalStateException expected) { + assertEquals("url missing protocol: \"://1.2.3.4:8080/path\"", URL.decode(expected.getMessage())); + } + + try { + URLStrParser.parseDecodedStr("://1.2.3.4:8080/path"); + fail(); + } catch (IllegalStateException expected) { + assertEquals("url missing protocol: \"://1.2.3.4:8080/path\"", expected.getMessage()); + } + } + + @Test + public void test_getAddress() throws Exception { + URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url1); + assertEquals("10.20.130.230:20880", url1.getAddress()); + } + + @Test + public void test_getAbsolutePath() throws Exception { + URL url = new URL("p1", "1.2.2.2", 33); + assertURLStrDecoder(url); + assertNull(url.getAbsolutePath()); + + url = new URL("file", null, 90, "/home/user1/route.js"); + assertURLStrDecoder(url); + assertEquals("/home/user1/route.js", url.getAbsolutePath()); + } + + @Test + public void test_equals() throws Exception { + URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url1); + + Map<String, String> params = new HashMap<String, String>(); + params.put("version", "1.0.0"); + params.put("application", "morgan"); + URL url2 = new URL("dubbo", "admin", "hello1234", "10.20.130.230", 20880, "context/path", params); + + assertURLStrDecoder(url2); + assertEquals(url1, url2); + } + + @Test + public void test_toString() throws Exception { + URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url1); + assertThat(url1.toString(), anyOf( + equalTo("dubbo://10.20.130.230:20880/context/path?version=1.0.0&application=morgan"), + equalTo("dubbo://10.20.130.230:20880/context/path?application=morgan&version=1.0.0")) + ); + } + + @Test + public void test_toFullString() throws Exception { + URL url1 = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url1); + assertThat(url1.toFullString(), anyOf( + equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"), + equalTo("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&version=1.0.0")) + ); + } + + @Test + public void test_set_methods() throws Exception { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url); + + url = url.setHost("host"); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("host", url.getHost()); + assertEquals("host:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + + url = url.setPort(1); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("host", url.getHost()); + assertEquals("host:1", url.getAddress()); + assertEquals(1, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + + url = url.setPath("path"); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("host", url.getHost()); + assertEquals("host:1", url.getAddress()); + assertEquals(1, url.getPort()); + assertEquals("path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + + url = url.setProtocol("protocol"); + + assertURLStrDecoder(url); + assertEquals("protocol", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("host", url.getHost()); + assertEquals("host:1", url.getAddress()); + assertEquals(1, url.getPort()); + assertEquals("path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + + url = url.setUsername("username"); + + assertURLStrDecoder(url); + assertEquals("protocol", url.getProtocol()); + assertEquals("username", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("host", url.getHost()); + assertEquals("host:1", url.getAddress()); + assertEquals(1, url.getPort()); + assertEquals("path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + + url = url.setPassword("password"); + + assertURLStrDecoder(url); + assertEquals("protocol", url.getProtocol()); + assertEquals("username", url.getUsername()); + assertEquals("password", url.getPassword()); + assertEquals("host", url.getHost()); + assertEquals("host:1", url.getAddress()); + assertEquals(1, url.getPort()); + assertEquals("path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + } + + @Test + public void test_removeParameters() throws Exception { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&k1=v1&k2=v2"); + assertURLStrDecoder(url); + + url = url.removeParameter("version"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(3, url.getParameters().size()); + assertEquals("morgan", url.getParameter("application")); + assertEquals("v1", url.getParameter("k1")); + assertEquals("v2", url.getParameter("k2")); + assertNull(url.getParameter("version")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&k1=v1&k2=v2"); + url = url.removeParameters("version", "application", "NotExistedKey"); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("v1", url.getParameter("k1")); + assertEquals("v2", url.getParameter("k2")); + assertNull(url.getParameter("version")); + assertNull(url.getParameter("application")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan&k1=v1&k2=v2"); + url = url.removeParameters(Arrays.asList("version", "application")); + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("v1", url.getParameter("k1")); + assertEquals("v2", url.getParameter("k2")); + assertNull(url.getParameter("version")); + assertNull(url.getParameter("application")); + } + + @Test + public void test_addParameter() throws Exception { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); + url = url.addParameter("k1", "v1"); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("morgan", url.getParameter("application")); + assertEquals("v1", url.getParameter("k1")); + } + + @Test + public void test_addParameter_sameKv() throws Exception { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&k1=v1"); + URL newUrl = url.addParameter("k1", "v1"); + + assertURLStrDecoder(url); + assertSame(newUrl, url); + } + + + @Test + public void test_addParameters() throws Exception { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); + url = url.addParameters(CollectionUtils.toStringMap("k1", "v1", "k2", "v2")); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(3, url.getParameters().size()); + assertEquals("morgan", url.getParameter("application")); + assertEquals("v1", url.getParameter("k1")); + assertEquals("v2", url.getParameter("k2")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); + url = url.addParameters("k1", "v1", "k2", "v2", "application", "xxx"); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(3, url.getParameters().size()); + assertEquals("xxx", url.getParameter("application")); + assertEquals("v1", url.getParameter("k1")); + assertEquals("v2", url.getParameter("k2")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); + url = url.addParametersIfAbsent(CollectionUtils.toStringMap("k1", "v1", "k2", "v2", "application", "xxx")); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(3, url.getParameters().size()); + assertEquals("morgan", url.getParameter("application")); + assertEquals("v1", url.getParameter("k1")); + assertEquals("v2", url.getParameter("k2")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); + url = url.addParameter("k1", "v1"); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("morgan", url.getParameter("application")); + assertEquals("v1", url.getParameter("k1")); + + url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); + url = url.addParameter("application", "xxx"); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(1, url.getParameters().size()); + assertEquals("xxx", url.getParameter("application")); + } + + @Test + public void test_addParameters_SameKv() throws Exception { + { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&k1=v1"); + URL newUrl = url.addParameters(CollectionUtils.toStringMap("k1", "v1")); + + assertURLStrDecoder(url); + assertSame(url, newUrl); + } + { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan&k1=v1&k2=v2"); + URL newUrl = url.addParameters(CollectionUtils.toStringMap("k1", "v1", "k2", "v2")); + + assertURLStrDecoder(url); + assertSame(newUrl, url); + } + } + + @Test + public void test_addParameterIfAbsent() throws Exception { + URL url = URL.valueOf("dubbo://admin:hello1234@10.20.130.230:20880/context/path?application=morgan"); + url = url.addParameterIfAbsent("application", "xxx"); + + assertURLStrDecoder(url); + assertEquals("dubbo", url.getProtocol()); + assertEquals("admin", url.getUsername()); + assertEquals("hello1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(1, url.getParameters().size()); + assertEquals("morgan", url.getParameter("application")); + } + + @Test + public void test_windowAbsolutePathBeginWithSlashIsValid() throws Exception { + final String osProperty = System.getProperties().getProperty("os.name"); + if (!osProperty.toLowerCase().contains("windows")) return; + + System.out.println("Test Windows valid path string."); + + File f0 = new File("C:/Windows"); + File f1 = new File("/C:/Windows"); + + File f2 = new File("C:\\Windows"); + File f3 = new File("/C:\\Windows"); + File f4 = new File("\\C:\\Windows"); + + assertEquals(f0, f1); + assertEquals(f0, f2); + assertEquals(f0, f3); + assertEquals(f0, f4); + } + + @Test + public void test_javaNetUrl() throws Exception { + java.net.URL url = new java.net.URL("http://admin:hello1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan#anchor1"); + + assertEquals("http", url.getProtocol()); + assertEquals("admin:hello1234", url.getUserInfo()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals(20880, url.getPort()); + assertEquals("/context/path", url.getPath()); + assertEquals("version=1.0.0&application=morgan", url.getQuery()); + assertEquals("anchor1", url.getRef()); + + assertEquals("admin:hello1234@10.20.130.230:20880", url.getAuthority()); + assertEquals("/context/path?version=1.0.0&application=morgan", url.getFile()); + } + + @Test + public void test_Anyhost() throws Exception { + URL url = URL.valueOf("dubbo://0.0.0.0:20880"); + assertURLStrDecoder(url); + assertEquals("0.0.0.0", url.getHost()); + assertTrue(url.isAnyHost()); + } + + @Test + public void test_Localhost() throws Exception { + URL url = URL.valueOf("dubbo://127.0.0.1:20880"); + assertURLStrDecoder(url); + assertEquals("127.0.0.1", url.getHost()); + assertEquals("127.0.0.1:20880", url.getAddress()); + assertTrue(url.isLocalHost()); + + url = URL.valueOf("dubbo://127.0.1.1:20880"); + assertURLStrDecoder(url); + assertEquals("127.0.1.1", url.getHost()); + assertEquals("127.0.1.1:20880", url.getAddress()); + assertTrue(url.isLocalHost()); + + url = URL.valueOf("dubbo://localhost:20880"); + assertURLStrDecoder(url); + assertEquals("localhost", url.getHost()); + assertEquals("localhost:20880", url.getAddress()); + assertTrue(url.isLocalHost()); + } + + @Test + public void test_Path() throws Exception { + URL url = new URL("dubbo", "localhost", 20880, "////path"); + assertURLStrDecoder(url); + assertEquals("path", url.getPath()); + } + + @Test + public void testAddParameters() throws Exception { + URL url = URL.valueOf("dubbo://127.0.0.1:20880"); + assertURLStrDecoder(url); + + Map<String, String> parameters = new HashMap<String, String>(); + parameters.put("version", null); + url.addParameters(parameters); + assertURLStrDecoder(url); + } + + @Test + public void testUserNamePasswordContainsAt() { + // Test username or password contains "@" + URL url = URL.valueOf("ad@min:hello@1234@10.20.130.230:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertEquals("ad@min", url.getUsername()); + assertEquals("hello@1234", url.getPassword()); + assertEquals("10.20.130.230", url.getHost()); + assertEquals("10.20.130.230:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + } + + + @Test + public void testIpV6Address() { + // Test username or password contains "@" + URL url = URL.valueOf("ad@min111:haha@1234@2001:0db8:85a3:08d3:1319:8a2e:0370:7344:20880/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertEquals("ad@min111", url.getUsername()); + assertEquals("haha@1234", url.getPassword()); + assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344", url.getHost()); + assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344:20880", url.getAddress()); + assertEquals(20880, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + } + + @Test + public void testIpV6AddressWithScopeId() { + URL url = URL.valueOf("2001:0db8:85a3:08d3:1319:8a2e:0370:7344%5/context/path?version=1.0.0&application=morgan"); + assertURLStrDecoder(url); + assertNull(url.getProtocol()); + assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344%5", url.getHost()); + assertEquals("2001:0db8:85a3:08d3:1319:8a2e:0370:7344%5", url.getAddress()); + assertEquals(0, url.getPort()); + assertEquals("context/path", url.getPath()); + assertEquals(2, url.getParameters().size()); + assertEquals("1.0.0", url.getParameter("version")); + assertEquals("morgan", url.getParameter("application")); + } + + @Test + public void testDefaultPort() { + Assertions.assertEquals("10.20.153.10:2181", URL.appendDefaultPort("10.20.153.10:0", 2181)); + Assertions.assertEquals("10.20.153.10:2181", URL.appendDefaultPort("10.20.153.10", 2181)); + } + + @Test + public void testGetServiceKey() { + URL url1 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName"); + assertURLStrDecoder(url1); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName", url1.getServiceKey()); + + URL url2 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName?interface=org.apache.dubbo.test.interfaceName"); + assertURLStrDecoder(url2); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName", url2.getServiceKey()); + + URL url3 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName?interface=org.apache.dubbo.test.interfaceName&group=group1&version=1.0.0"); + assertURLStrDecoder(url3); + Assertions.assertEquals("group1/org.apache.dubbo.test.interfaceName:1.0.0", url3.getServiceKey()); + + URL url4 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName"); + assertURLStrDecoder(url4); + Assertions.assertEquals("context/path", url4.getPathKey()); + + URL url5 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group1&version=1.0.0"); + assertURLStrDecoder(url5); + Assertions.assertEquals("group1/context/path:1.0.0", url5.getPathKey()); + } + + @Test + public void testGetColonSeparatedKey() { + URL url1 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group&version=1.0.0"); + assertURLStrDecoder(url1); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName:1.0.0:group", url1.getColonSeparatedKey()); + + URL url2 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&version=1.0.0"); + assertURLStrDecoder(url2); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName:1.0.0:", url2.getColonSeparatedKey()); + + URL url3 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group"); + assertURLStrDecoder(url3); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName::group", url3.getColonSeparatedKey()); + + URL url4 = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName"); + assertURLStrDecoder(url4); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName::", url4.getColonSeparatedKey()); + + URL url5 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName"); + assertURLStrDecoder(url5); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName::", url5.getColonSeparatedKey()); + + URL url6 = URL.valueOf("10.20.130.230:20880/org.apache.dubbo.test.interfaceName?interface=org.apache.dubbo.test.interfaceName1"); + assertURLStrDecoder(url6); + Assertions.assertEquals("org.apache.dubbo.test.interfaceName1::", url6.getColonSeparatedKey()); + } + + @Test + public void testValueOf() { + URL url = URL.valueOf("10.20.130.230"); + assertURLStrDecoder(url); + + url = URL.valueOf("10.20.130.230:20880"); + assertURLStrDecoder(url); + + url = URL.valueOf("dubbo://10.20.130.230:20880"); + assertURLStrDecoder(url); + + url = URL.valueOf("dubbo://10.20.130.230:20880/path"); + assertURLStrDecoder(url); + } + + + /** + * Test {@link URL#getParameters(Predicate)} method + * + * @since 2.7.8 + */ + @Test + public void testGetParameters() { + URL url = URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group&version=1.0.0"); + Map<String, String> parameters = url.getParameters(i -> "version".equals(i)); + String version = parameters.get("version"); + assertEquals(1, parameters.size()); + assertEquals("1.0.0", version); + } + + @Test + public void testGetParameter() { + URL url = URL.valueOf("http://127.0.0.1:8080/path?i=1&b=false"); + assertEquals(Integer.valueOf(1), url.getParameter("i", Integer.class)); + assertEquals(Boolean.FALSE, url.getParameter("b", Boolean.class)); + } +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToStringConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/ConverterTest.java similarity index 53% copy from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToStringConverterTest.java copy to dubbo-common/src/test/java/org/apache/dubbo/common/convert/ConverterTest.java index 57806c3..1f5a36c 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToStringConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/ConverterTest.java @@ -14,41 +14,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; +package org.apache.dubbo.common.convert; -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToStringConverter; - -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.apache.dubbo.common.convert.Converter.convertIfPossible; +import static org.apache.dubbo.common.convert.Converter.getConverter; import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertSame; /** - * {@link StringToStringConverter} Test + * {@link Converter} Test-Cases * - * @since 2.7.6 + * @since 2.7.8 */ -public class StringToStringConverterTest { - - private StringToStringConverter converter; - - @BeforeEach - public void init() { - converter = (StringToStringConverter) getExtensionLoader(Converter.class).getExtension("string-to-string"); - } +public class ConverterTest { @Test - public void testAccept() { - assertTrue(converter.accept(String.class, String.class)); + public void testGetConverter() { + getExtensionLoader(Converter.class) + .getSupportedExtensionInstances() + .forEach(converter -> { + assertSame(converter, getConverter(converter.getSourceType(), converter.getTargetType())); + }); } @Test - public void testConvert() { - assertEquals("1", converter.convert("1")); - assertNull(converter.convert(null)); + public void testConvertIfPossible() { + assertEquals(Integer.valueOf(2), convertIfPossible("2", Integer.class)); + assertEquals(Boolean.FALSE, convertIfPossible("false", Boolean.class)); + assertEquals(Double.valueOf(1), convertIfPossible("1", Double.class)); } } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToBooleanConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToBooleanConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToBooleanConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToBooleanConverterTest.java index 3b1d75b..e955fa9 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToBooleanConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToBooleanConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToBooleanConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToCharArrayConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToCharArrayConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToCharArrayConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToCharArrayConverterTest.java index 492a129..bc3a606 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToCharArrayConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToCharArrayConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToCharArrayConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToCharacterConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToCharacterConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToCharacterConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToCharacterConverterTest.java index c9e88c2..87f3367 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToCharacterConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToCharacterConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToCharacterConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToDoubleConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToDoubleConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToDoubleConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToDoubleConverterTest.java index 668f3e6..2c74736 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToDoubleConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToDoubleConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToDoubleConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToFloatConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToFloatConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToFloatConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToFloatConverterTest.java index aa17499..b4b36f3 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToFloatConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToFloatConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToFloatConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToIntegerConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToIntegerConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToIntegerConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToIntegerConverterTest.java index 9c7d24b..1ccebfd 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToIntegerConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToIntegerConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToIntegerConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToLongConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToLongConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToLongConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToLongConverterTest.java index e14424a..c7cd926 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToLongConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToLongConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToLongConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToOptionalConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToOptionalConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToOptionalConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToOptionalConverterTest.java index 242ae60..9cb79e2 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToOptionalConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToOptionalConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToOptionalConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToShortConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToShortConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToShortConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToShortConverterTest.java index 3f1d493..9ecdc20 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToShortConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToShortConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToShortConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToStringConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToStringConverterTest.java similarity index 92% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/StringToStringConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToStringConverterTest.java index 57806c3..517585d 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/StringToStringConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToStringConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert; - -import org.apache.dubbo.common.convert.Converter; -import org.apache.dubbo.common.convert.StringToStringConverter; +package org.apache.dubbo.common.convert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/MultiValueConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/MultiValueConverterTest.java new file mode 100644 index 0000000..ea64628 --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/MultiValueConverterTest.java @@ -0,0 +1,72 @@ +/* + * 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.dubbo.common.convert.multiple; + +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.Deque; +import java.util.List; +import java.util.NavigableSet; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TransferQueue; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * {@link MultiValueConverter} Test + * + * @since 2.7.8 + */ +public class MultiValueConverterTest { + + @Test + public void testFind() { + MultiValueConverter converter = MultiValueConverter.find(String.class, String[].class); + assertEquals(StringToArrayConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, BlockingDeque.class); + assertEquals(StringToBlockingDequeConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, BlockingQueue.class); + assertEquals(StringToBlockingQueueConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, Collection.class); + assertEquals(StringToCollectionConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, Deque.class); + assertEquals(StringToDequeConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, List.class); + assertEquals(StringToListConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, NavigableSet.class); + assertEquals(StringToNavigableSetConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, Queue.class); + assertEquals(StringToQueueConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, Set.class); + assertEquals(StringToSetConverter.class, converter.getClass()); + + converter = MultiValueConverter.find(String.class, TransferQueue.class); + assertEquals(StringToTransferQueueConverter.class, converter.getClass()); + } +} diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToArrayConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToArrayConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToArrayConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToArrayConverterTest.java index 1781356..8279e07 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToArrayConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToArrayConverterTest.java @@ -14,9 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; - -import org.apache.dubbo.common.convert.multiple.StringToArrayConverter; +package org.apache.dubbo.common.convert.multiple; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToBlockingDequeConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToBlockingDequeConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToBlockingDequeConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToBlockingDequeConverterTest.java index 6f9597d..f0975ad 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToBlockingDequeConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToBlockingDequeConverterTest.java @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToBlockingDequeConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToBlockingQueueConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToBlockingQueueConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToBlockingQueueConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToBlockingQueueConverterTest.java index 4fa7532..f1d8cb8 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToBlockingQueueConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToBlockingQueueConverterTest.java @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToBlockingQueueConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToCollectionConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToCollectionConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToCollectionConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToCollectionConverterTest.java index f0b06ec..564ece3 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToCollectionConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToCollectionConverterTest.java @@ -14,10 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; - -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToCollectionConverter; +package org.apache.dubbo.common.convert.multiple; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToDequeConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToDequeConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToDequeConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToDequeConverterTest.java index e810092..3d4b785 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToDequeConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToDequeConverterTest.java @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToDequeConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToListConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToListConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToListConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToListConverterTest.java index af9ee91..4258199 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToListConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToListConverterTest.java @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToListConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToNavigableSetConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToNavigableSetConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToNavigableSetConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToNavigableSetConverterTest.java index face60d..e7e1660 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToNavigableSetConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToNavigableSetConverterTest.java @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToListConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; @@ -47,7 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** - * {@link StringToListConverter} Test + * {@link StringToNavigableSetConverter} Test * * @since 2.7.6 */ diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToQueueConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToQueueConverterTest.java similarity index 97% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToQueueConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToQueueConverterTest.java index 539693a..2933d04 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToQueueConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToQueueConverterTest.java @@ -14,9 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.StringToQueueConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToSetConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToSetConverterTest.java similarity index 97% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToSetConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToSetConverterTest.java index 269d709..5925cec 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToSetConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToSetConverterTest.java @@ -14,9 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.StringToSetConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToSortedSetConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToSortedSetConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToSortedSetConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToSortedSetConverterTest.java index 6af8f9d..2ed1252 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToSortedSetConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToSortedSetConverterTest.java @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToListConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; @@ -47,7 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** - * {@link StringToListConverter} Test + * {@link StringToSortedSetConverter} Test * * @since 2.7.6 */ diff --git a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToTransferQueueConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToTransferQueueConverterTest.java similarity index 95% rename from dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToTransferQueueConverterTest.java rename to dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToTransferQueueConverterTest.java index 4d8d66b..e4cc101 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/convert/multiple/StringToTransferQueueConverterTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/multiple/StringToTransferQueueConverterTest.java @@ -14,10 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.convert.multiple; +package org.apache.dubbo.common.convert.multiple; -import org.apache.dubbo.common.convert.multiple.MultiValueConverter; -import org.apache.dubbo.common.convert.multiple.StringToListConverter; import org.apache.dubbo.common.utils.CollectionUtils; import org.junit.jupiter.api.BeforeEach; @@ -48,7 +46,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; /** - * {@link StringToListConverter} Test + * {@link StringToTransferQueueConverter} Test * * @since 2.7.6 */ diff --git a/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulParameter.java b/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulParameter.java new file mode 100644 index 0000000..f3fb024 --- /dev/null +++ b/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulParameter.java @@ -0,0 +1,87 @@ +/* + * 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.dubbo.registry.consul; + +import org.apache.dubbo.common.URL; + +import static org.apache.dubbo.common.utils.StringUtils.isBlank; + +/** + * The enumeration for the Consul's parameters on the {@link URL} + * + * @see URL#getParameters() + * @since 2.7.8 + */ +public enum ConsulParameter { + + ACL_TOKEN, + + TAGS, + + INSTANCE_ZONE, + + DEFAULT_ZONE_METADATA_NAME("zone"), + + INSTANCE_GROUP, + + CONSISTENCY_MODE, + + ; + + private final String name; + + private final String defaultValue; + + ConsulParameter() { + this(null); + } + + ConsulParameter(String defaultValue) { + this(null, defaultValue); + } + + ConsulParameter(String name, String defaultValue) { + this.name = isBlank(name) ? defaultName() : name; + this.defaultValue = defaultValue; + } + + private String defaultName() { + return name().toLowerCase().replace('_', '-'); + } + + /** + * The parameter value from the specified registry {@link URL} + * + * @param registryURL the specified registry {@link URL} + * @return <code>defaultValue</code> if not found + */ + public String getValue(URL registryURL) { + return registryURL.getParameter(name, defaultValue); + } + + /** + * The parameter value from the specified registry {@link URL} + * + * @param registryURL the specified registry {@link URL} + * @param valueType the type of parameter value + * @param defaultValue the default value if parameter is absent + * @return <code>defaultValue</code> if not found + */ + public <T> T getValue(URL registryURL, Class<T> valueType, T defaultValue) { + return registryURL.getParameter(name, valueType, defaultValue); + } +} diff --git a/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java b/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java index 5d5e98b..b05f1d8 100644 --- a/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java +++ b/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java @@ -29,10 +29,12 @@ import org.apache.dubbo.registry.client.ServiceInstance; import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent; import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener; +import com.ecwid.consul.v1.ConsistencyMode; import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.QueryParams; import com.ecwid.consul.v1.Response; import com.ecwid.consul.v1.agent.model.NewService; +import com.ecwid.consul.v1.catalog.CatalogServicesRequest; import com.ecwid.consul.v1.health.HealthServicesRequest; import com.ecwid.consul.v1.health.model.HealthService; @@ -41,6 +43,7 @@ import java.util.Arrays; import java.util.Base64; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -53,6 +56,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static java.util.concurrent.Executors.newCachedThreadPool; +import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR_CHAR; import static org.apache.dubbo.common.constants.CommonConstants.SEMICOLON_SPLIT_PATTERN; import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.CHECK_PASS_INTERVAL; import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_CHECK_PASS_INTERVAL; @@ -61,6 +65,12 @@ import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_PO import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_WATCH_TIMEOUT; import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEREGISTER_AFTER; import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.WATCH_TIMEOUT; +import static org.apache.dubbo.registry.consul.ConsulParameter.ACL_TOKEN; +import static org.apache.dubbo.registry.consul.ConsulParameter.CONSISTENCY_MODE; +import static org.apache.dubbo.registry.consul.ConsulParameter.DEFAULT_ZONE_METADATA_NAME; +import static org.apache.dubbo.registry.consul.ConsulParameter.INSTANCE_GROUP; +import static org.apache.dubbo.registry.consul.ConsulParameter.INSTANCE_ZONE; +import static org.apache.dubbo.registry.consul.ConsulParameter.TAGS; /** * 2019-07-31 @@ -82,6 +92,25 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S private long checkPassInterval; private URL url; + private String aclToken; + + private List<String> tags; + + private ConsistencyMode consistencyMode; + + private String defaultZoneMetadataName; + + /** + * Service instance zone. + */ + private String instanceZone; + + /** + * Service instance group. + */ + private String instanceGroup; + + @Override public void onEvent(ServiceInstancesChangedEvent event) { @@ -97,6 +126,39 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S ttlScheduler = new TtlScheduler(checkPassInterval, client); this.tag = registryURL.getParameter(QUERY_TAG); this.registeringTags.addAll(getRegisteringTags(url)); + this.aclToken = ACL_TOKEN.getValue(registryURL); + this.tags = getTags(registryURL); + this.consistencyMode = getConsistencyMode(registryURL); + this.defaultZoneMetadataName = DEFAULT_ZONE_METADATA_NAME.getValue(registryURL); + this.instanceZone = INSTANCE_ZONE.getValue(registryURL); + this.instanceGroup = INSTANCE_GROUP.getValue(registryURL); + } + + /** + * Get the {@link ConsistencyMode} + * + * @param registryURL the {@link URL} of registry + * @return non-null, {@link ConsistencyMode#DEFAULT} as default + * @sine 2.7.8 + */ + private ConsistencyMode getConsistencyMode(URL registryURL) { + String value = CONSISTENCY_MODE.getValue(registryURL); + if (StringUtils.isNotEmpty(value)) { + return ConsistencyMode.valueOf(value); + } + return ConsistencyMode.DEFAULT; + } + + /** + * Get the "tags" from the {@link URL} of registry + * + * @param registryURL the {@link URL} of registry + * @return non-null + * @sine 2.7.8 + */ + private List<String> getTags(URL registryURL) { + String value = TAGS.getValue(registryURL); + return StringUtils.splitToList(value, COMMA_SEPARATOR_CHAR); } private List<String> getRegisteringTags(URL url) { @@ -122,7 +184,7 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S public void register(ServiceInstance serviceInstance) throws RuntimeException { NewService consulService = buildService(serviceInstance); ttlScheduler.add(consulService.getId()); - client.agentServiceRegister(consulService); + client.agentServiceRegister(consulService, aclToken); } @Override @@ -146,12 +208,16 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S public void unregister(ServiceInstance serviceInstance) throws RuntimeException { String id = buildId(serviceInstance); ttlScheduler.remove(id); - client.agentServiceDeregister(id); + client.agentServiceDeregister(id, aclToken); } @Override public Set<String> getServices() { - return null; + CatalogServicesRequest request = CatalogServicesRequest.newBuilder() + .setQueryParams(QueryParams.DEFAULT) + .setToken(aclToken) + .build(); + return this.client.getCatalogServices(request).getValue().keySet(); } @Override @@ -231,7 +297,6 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S service.setName(serviceInstance.getServiceName()); service.setCheck(buildCheck(serviceInstance)); service.setTags(buildTags(serviceInstance)); -// service.setMeta(buildMetadata(serviceInstance)); return service; } @@ -240,10 +305,21 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S } private List<String> buildTags(ServiceInstance serviceInstance) { + List<String> tags = new LinkedList<>(this.tags); + + if (StringUtils.isNotEmpty(instanceZone)) { + tags.add(defaultZoneMetadataName + "=" + instanceZone); + } + + if (StringUtils.isNotEmpty(instanceGroup)) { + tags.add("group=" + instanceGroup); + } + Map<String, String> params = serviceInstance.getMetadata(); - List<String> tags = params.keySet().stream() + params.keySet().stream() .map(k -> k + "=" + params.get(k)) - .collect(Collectors.toList()); + .forEach(tags::add); + tags.addAll(registeringTags); return tags; } @@ -281,7 +357,6 @@ public class ConsulServiceDiscovery implements ServiceDiscovery, EventListener<S check.setTtl((checkPassInterval / 1000) + "s"); String deregister = serviceInstance.getMetadata().get(DEREGISTER_AFTER); check.setDeregisterCriticalServiceAfter(deregister == null ? DEFAULT_DEREGISTER_TIME : deregister); - return check; }