getConfigGroups() {
.collect(Collectors.toSet());
}
- @Override
- protected String doGetConfig(String key, String group) throws Exception {
- File configFile = configFile(key, group);
- return getConfig(configFile);
- }
-
protected String getConfig(File configFile) {
return ThrowableFunction.execute(configFile,
file -> canRead(configFile) ? readFileToString(configFile, getEncoding()) : null);
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index eca3495d91d..657c1ab517b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -20,6 +20,7 @@
import org.apache.dubbo.common.URL;
import java.net.NetworkInterface;
+import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.regex.Pattern;
@@ -44,6 +45,11 @@ public interface CommonConstants {
String ANY_VALUE = "*";
+ /**
+ * @since 2.7.8
+ */
+ char COMMA_SEPARATOR_CHAR = ',';
+
String COMMA_SEPARATOR = ",";
String DOT_SEPARATOR = ".";
@@ -187,6 +193,14 @@ public interface CommonConstants {
String REMOTE_METADATA_STORAGE_TYPE = "remote";
+ /**
+ * The composite metadata storage type includes {@link #DEFAULT_METADATA_STORAGE_TYPE "local"} and
+ * {@link #REMOTE_METADATA_STORAGE_TYPE "remote"}.
+ *
+ * @since 2.7.8
+ */
+ String COMPOSITE_METADATA_STORAGE_TYPE = "composite";
+
/**
* Consumer side 's proxy class
*/
@@ -315,4 +329,19 @@ public interface CommonConstants {
String SSL_ENABLED_KEY = "ssl-enabled";
+
+ /**
+ * The parameter key for the class path of the ServiceNameMapping {@link Properties} file
+ *
+ * @since 2.7.8
+ */
+ String SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY = "service-name-mapping.properties-path";
+
+ /**
+ * The default class path of the ServiceNameMapping {@link Properties} file
+ *
+ * @since 2.7.8
+ */
+ String DEFAULT_SERVICE_NAME_MAPPING_PROPERTIES_PATH = "META-INF/dubbo/service-name-mapping.properties";
+
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
index 465c7e35cb0..ce83136b06b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RegistryConstants.java
@@ -76,6 +76,8 @@ public interface RegistryConstants {
/**
* The parameter key of the subscribed service names for Service-Oriented Registry
+ *
+ * If there is a multiple-values, the "comma" is the separator.
*
* @since 2.7.5
*/
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 5bc2d4d809d..e36fdf2324c 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 @@ default Class getTargetType() {
.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 the target type
+ * @return null
if can't be converted
+ * @since 2.7.8
+ */
+ static T convertIfPossible(Object source, Class 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 298b4594a9b..637d1a8f30e 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 @@ default Class getSourceType() {
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 null
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 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/main/java/org/apache/dubbo/common/utils/PathUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PathUtils.java
index 3e38ce14b8b..c291d792e65 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PathUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PathUtils.java
@@ -63,7 +63,12 @@ static String normalize(String path) {
if (index > -1) {
normalizedPath = normalizedPath.substring(0, index);
}
- return replace(normalizedPath, "//", "/");
+
+ while (normalizedPath.contains("//")) {
+ normalizedPath = replace(normalizedPath, "//", "/");
+ }
+
+ return normalizedPath;
}
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringConstantFieldValuePredicate.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringConstantFieldValuePredicate.java
new file mode 100644
index 00000000000..534a612bfdb
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringConstantFieldValuePredicate.java
@@ -0,0 +1,67 @@
+/*
+ * 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.utils;
+
+import java.lang.reflect.Field;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.lang.reflect.Modifier.isFinal;
+import static java.lang.reflect.Modifier.isPublic;
+import static java.lang.reflect.Modifier.isStatic;
+import static org.apache.dubbo.common.utils.FieldUtils.getFieldValue;
+
+/**
+ * The constant field value {@link Predicate} for the specified {@link Class}
+ *
+ * @see Predicate
+ * @since 2.7.8
+ */
+public class StringConstantFieldValuePredicate implements Predicate {
+
+ private final Set constantFieldValues;
+
+ public StringConstantFieldValuePredicate(Class> targetClass) {
+ this.constantFieldValues = getConstantFieldValues(targetClass);
+ }
+
+ public static Predicate of(Class> targetClass) {
+ return new StringConstantFieldValuePredicate(targetClass);
+ }
+
+ private Set getConstantFieldValues(Class> targetClass) {
+ return Stream.of(targetClass.getFields())
+ .filter(f -> isStatic(f.getModifiers())) // static
+ .filter(f -> isPublic(f.getModifiers())) // public
+ .filter(f -> isFinal(f.getModifiers())) // final
+ .map(this::getConstantValue)
+ .filter(v -> v instanceof String) // filters String type
+ .map(String.class::cast) // Casts String type
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public boolean test(String s) {
+ return constantFieldValues.contains(s);
+ }
+
+ private Object getConstantValue(Field field) {
+ return getFieldValue(null, field);
+ }
+}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
index 42ee05bbe5c..fc444750c57 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
@@ -28,13 +28,17 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.String.valueOf;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.unmodifiableSet;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.DOT_REGEX;
@@ -699,6 +703,45 @@ public static List splitToList(String str, char ch) {
return splitToList0(str, ch);
}
+ /**
+ * Split the specified value to be a {@link Set}
+ *
+ * @param value the content to be split
+ * @param separatorChar a char to separate
+ * @return non-null read-only {@link Set}
+ * @since 2.7.8
+ */
+ public static Set splitToSet(String value, char separatorChar) {
+ return splitToSet(value, separatorChar, false);
+ }
+
+ /**
+ * Split the specified value to be a {@link Set}
+ *
+ * @param value the content to be split
+ * @param separatorChar a char to separate
+ * @param trimElements require to trim the elements or not
+ * @return non-null read-only {@link Set}
+ * @since 2.7.8
+ */
+ public static Set splitToSet(String value, char separatorChar, boolean trimElements) {
+ List values = splitToList(value, separatorChar);
+ int size = values.size();
+
+ if (size < 1) { // empty condition
+ return emptySet();
+ }
+
+ if (!trimElements) { // Do not require to trim the elements
+ return new LinkedHashSet(values);
+ }
+
+ return unmodifiableSet(values
+ .stream()
+ .map(String::trim)
+ .collect(LinkedHashSet::new, Set::add, Set::addAll));
+ }
+
/**
* join string.
*
@@ -797,7 +840,7 @@ private static Map parseKeyValuePair(String str, String itemSepa
}
public static String getQueryStringValue(String qs, String key) {
- Map map = StringUtils.parseQueryString(qs);
+ Map map = parseQueryString(qs);
return map.get(key);
}
@@ -1051,4 +1094,16 @@ public static byte decodeHexByte(CharSequence s, int pos) {
return (byte) ((hi << 4) + lo);
}
+ /**
+ * Create the common-delimited {@link String} by one or more {@link String} members
+ *
+ * @param one one {@link String}
+ * @param others others {@link String}
+ * @return null
if one
or others
is null
+ * @since 2.7.8
+ */
+ public static String toCommaDelimitedString(String one, String... others) {
+ String another = arrayToDelimitedString(others, COMMA_SEPARATOR);
+ return isEmpty(another) ? one : one + COMMA_SEPARATOR + another;
+ }
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java
index eb1a2e6ead2..5492ac08d90 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/annotation/DubboReference.java
@@ -16,6 +16,8 @@
*/
package org.apache.dubbo.config.annotation;
+import org.apache.dubbo.common.constants.RegistryConstants;
+
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -279,4 +281,11 @@
* @since 2.7.3
*/
String id() default "";
+
+ /**
+ * @return The service names that the Dubbo interface subscribed
+ * @see RegistryConstants#SUBSCRIBED_SERVICE_NAMES_KEY
+ * @since 2.7.8
+ */
+ String[] services() default {};
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
index ed0188aa438..868fadcc973 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
@@ -67,10 +67,10 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
public static final String NAME = "config";
- private final Map> configsCache = newMap();
-
private final ReadWriteLock lock = new ReentrantReadWriteLock();
+ final Map> configsCache = newMap();
+
public ConfigManager() {
}
@@ -371,6 +371,15 @@ public void clear() {
});
}
+ /**
+ * @throws IllegalStateException
+ * @since 2.7.8
+ */
+ @Override
+ public void destroy() throws IllegalStateException {
+ clear();
+ }
+
/**
* Add the dubbo {@link AbstractConfig config}
*
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java b/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java
index 06c6f6afdf7..bb36c77607d 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/event/EventListener.java
@@ -56,7 +56,7 @@ public interface EventListener extends java.util.EventListener,
* The comparison rule , refer to {@link #compareTo}.
*/
default int getPriority() {
- return MIN_PRIORITY;
+ return NORMAL_PRIORITY;
}
/**
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 db5f57b1c51..5ba606d5ad7 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,877 +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 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 params = new HashMap();
- 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();
- 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 params = new HashMap();
- 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 parameters = new HashMap();
- 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);
- }
-}
+/*
+ * 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 params = new HashMap();
+ 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();
+ 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 params = new HashMap();
+ 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 parameters = new HashMap();
+ 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 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/common/config/configcenter/AbstractDynamicConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java
index 4f2f700e8ba..7605a3c6184 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java
@@ -28,15 +28,17 @@
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.DEFAULT_THREAD_POOL_KEEP_ALIVE_TIME;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.DEFAULT_THREAD_POOL_PREFIX;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.DEFAULT_THREAD_POOL_SIZE;
+import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.GROUP_PARAM_NAME;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.PARAM_NAME_PREFIX;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.THREAD_POOL_KEEP_ALIVE_TIME_PARAM_NAME;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.THREAD_POOL_PREFIX_PARAM_NAME;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.THREAD_POOL_SIZE_PARAM_NAME;
+import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.TIMEOUT_PARAM_NAME;
+import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.DEFAULT_GROUP;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* {@link AbstractDynamicConfiguration} Test
@@ -49,7 +51,7 @@ public class AbstractDynamicConfigurationTest {
@BeforeEach
public void init() {
- configuration = new AbstractDynamicConfiguration() {
+ configuration = new AbstractDynamicConfiguration(null) {
@Override
protected String doGetConfig(String key, String group) throws Exception {
return null;
@@ -59,6 +61,11 @@ protected String doGetConfig(String key, String group) throws Exception {
protected void doClose() throws Exception {
}
+
+ @Override
+ protected boolean doRemoveConfig(String key, String group) throws Exception {
+ return false;
+ }
};
}
@@ -71,6 +78,10 @@ public void testConstants() {
assertEquals("dubbo.config-center.thread-pool.keep-alive-time", THREAD_POOL_KEEP_ALIVE_TIME_PARAM_NAME);
assertEquals(1, DEFAULT_THREAD_POOL_SIZE);
assertEquals(60 * 1000, DEFAULT_THREAD_POOL_KEEP_ALIVE_TIME);
+
+ // @since 2.7.8
+ assertEquals("dubbo.config-center.group", GROUP_PARAM_NAME);
+ assertEquals("dubbo.config-center.timeout", TIMEOUT_PARAM_NAME);
}
@Test
@@ -91,6 +102,11 @@ protected String doGetConfig(String key, String group) throws Exception {
protected void doClose() throws Exception {
}
+
+ @Override
+ protected boolean doRemoveConfig(String key, String group) throws Exception {
+ return false;
+ }
};
ThreadPoolExecutor threadPoolExecutor = configuration.getWorkersThreadPool();
@@ -149,4 +165,42 @@ public void testRemoveListener() {
public void testClose() throws Exception {
configuration.close();
}
+
+ /**
+ * Test {@link AbstractDynamicConfiguration#getGroup()} and
+ * {@link AbstractDynamicConfiguration#getDefaultGroup()} methods
+ *
+ * @since 2.7.8
+ */
+ @Test
+ public void testGetGroupAndGetDefaultGroup() {
+ assertEquals(configuration.getGroup(), configuration.getDefaultGroup());
+ assertEquals(DEFAULT_GROUP, configuration.getDefaultGroup());
+ }
+
+ /**
+ * Test {@link AbstractDynamicConfiguration#getTimeout()} and
+ * {@link AbstractDynamicConfiguration#getDefaultTimeout()} methods
+ *
+ * @since 2.7.8
+ */
+ @Test
+ public void testGetTimeoutAndGetDefaultTimeout() {
+ assertEquals(configuration.getTimeout(), configuration.getDefaultTimeout());
+ assertEquals(-1L, configuration.getDefaultTimeout());
+ }
+
+ /**
+ * Test {@link AbstractDynamicConfiguration#removeConfig(String, String)} and
+ * {@link AbstractDynamicConfiguration#doRemoveConfig(String, String)} methods
+ *
+ * @since 2.7.8
+ */
+ @Test
+ public void testRemoveConfigAndDoRemoveConfig() throws Exception {
+ String key = null;
+ String group = null;
+ assertEquals(configuration.removeConfig(key, group), configuration.doRemoveConfig(key, group));
+ assertFalse(configuration.removeConfig(key, group));
+ }
}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
index 1422ba63e88..80282c185c3 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
@@ -17,6 +17,8 @@
package org.apache.dubbo.common.config.configcenter.file;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterEach;
@@ -24,15 +26,17 @@
import org.junit.jupiter.api.Test;
import java.io.File;
+import java.util.TreeSet;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicBoolean;
+import static java.util.Arrays.asList;
import static org.apache.commons.io.FileUtils.deleteQuietly;
import static org.apache.dubbo.common.URL.valueOf;
import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.DEFAULT_GROUP;
import static org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration.CONFIG_CENTER_DIR_PARAM_NAME;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -41,6 +45,8 @@
*/
public class FileSystemDynamicConfigurationTest {
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
private FileSystemDynamicConfiguration configuration;
private static final String KEY = "abc-def-ghi";
@@ -53,11 +59,11 @@ public void init() {
rootDirectory.mkdirs();
URL url = valueOf("dubbo://127.0.0.1:20880").addParameter(CONFIG_CENTER_DIR_PARAM_NAME, rootDirectory.getAbsolutePath());
configuration = new FileSystemDynamicConfiguration(url);
- deleteQuietly(configuration.getRootDirectory());
}
@AfterEach
public void destroy() throws Exception {
+ deleteQuietly(configuration.getRootDirectory());
configuration.close();
}
@@ -73,9 +79,6 @@ public void testInit() {
assertEquals(ThreadPoolExecutor.class, configuration.getWorkersThreadPool().getClass());
assertEquals(1, (configuration.getWorkersThreadPool()).getCorePoolSize());
assertEquals(1, (configuration.getWorkersThreadPool()).getMaximumPoolSize());
- assertNotNull(configuration.getWatchEventsLoopThreadPool());
- assertEquals(1, (configuration.getWatchEventsLoopThreadPool()).getCorePoolSize());
- assertEquals(1, (configuration.getWatchEventsLoopThreadPool()).getMaximumPoolSize());
if (configuration.isBasedPoolingWatchService()) {
assertEquals(2, configuration.getDelay());
@@ -103,7 +106,7 @@ public void testAddAndRemoveListener() throws InterruptedException {
processedEvent.set(true);
assertEquals(KEY, event.getKey());
- System.out.printf("[%s] " + event + "\n", Thread.currentThread().getName());
+ logger.info(String.format("[%s] " + event + "\n", Thread.currentThread().getName()));
});
@@ -127,7 +130,7 @@ public void testAddAndRemoveListener() throws InterruptedException {
configuration.addListener("test", "test", event -> {
processedEvent.set(true);
assertEquals("test", event.getKey());
- System.out.printf("[%s] " + event + "\n", Thread.currentThread().getName());
+ logger.info(String.format("[%s] " + event + "\n", Thread.currentThread().getName()));
});
processedEvent.set(false);
configuration.publishConfig("test", "test", "TEST");
@@ -141,10 +144,36 @@ public void testAddAndRemoveListener() throws InterruptedException {
processedEvent.set(false);
- File keyFile = configuration.configFile(KEY, DEFAULT_GROUP);
+ configuration.getRootDirectory();
+ File keyFile = new File(KEY, DEFAULT_GROUP);
FileUtils.deleteQuietly(keyFile);
while (!processedEvent.get()) {
Thread.sleep(1 * 1000L);
}
}
+
+ @Test
+ public void testRemoveConfig() throws Exception {
+
+ assertTrue(configuration.publishConfig(KEY, DEFAULT_GROUP, "A"));
+
+ assertEquals("A", FileUtils.readFileToString(configuration.configFile(KEY, DEFAULT_GROUP), configuration.getEncoding()));
+
+ assertTrue(configuration.removeConfig(KEY, DEFAULT_GROUP));
+
+ assertFalse(configuration.configFile(KEY, DEFAULT_GROUP).exists());
+
+ }
+
+ @Test
+ public void testGetConfigKeys() throws Exception {
+
+ assertTrue(configuration.publishConfig("A", DEFAULT_GROUP, "A"));
+
+ assertTrue(configuration.publishConfig("B", DEFAULT_GROUP, "B"));
+
+ assertTrue(configuration.publishConfig("C", DEFAULT_GROUP, "C"));
+
+ assertEquals(new TreeSet(asList("A", "B", "C")), configuration.getConfigKeys(DEFAULT_GROUP));
+ }
}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/constants/CommonConstantsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/constants/CommonConstantsTest.java
new file mode 100644
index 00000000000..bc85dfb3d50
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/constants/CommonConstantsTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.constants;
+
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR_CHAR;
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_SERVICE_NAME_MAPPING_PROPERTIES_PATH;
+import static org.apache.dubbo.common.constants.CommonConstants.SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link CommonConstants} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class CommonConstantsTest {
+
+ @Test
+ public void test() {
+ assertEquals(',', COMMA_SEPARATOR_CHAR);
+ assertEquals("composite", COMPOSITE_METADATA_STORAGE_TYPE);
+ assertEquals("service-name-mapping.properties-path", SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY);
+ assertEquals("META-INF/dubbo/service-name-mapping.properties", DEFAULT_SERVICE_NAME_MAPPING_PROPERTIES_PATH);
+ }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/convert/ConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/ConverterTest.java
new file mode 100644
index 00000000000..1f5a36cd94a
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/ConverterTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+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.assertSame;
+
+/**
+ * {@link Converter} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class ConverterTest {
+
+ @Test
+ public void testGetConverter() {
+ getExtensionLoader(Converter.class)
+ .getSupportedExtensionInstances()
+ .forEach(converter -> {
+ assertSame(converter, getConverter(converter.getSourceType(), converter.getTargetType()));
+ });
+ }
+
+ @Test
+ 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 3b1d75bb63a..e955fa9a417 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 492a1299e4b..bc3a606ee58 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 c9e88c24211..87f3367709b 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 668f3e6b80f..2c747360185 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 aa1749948a9..b4b36f3f178 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 9c7d24b6019..1ccebfd183e 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 e14424a62b0..c7cd926262d 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 242ae6053e5..9cb79e20b50 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 3f1d4935a14..9ecdc207b75 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 57806c345a8..517585df778 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 00000000000..ea64628bd23
--- /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 17813566c71..8279e07b35a 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 6f9597d7065..f0975ad6bfd 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 4fa7532a038..f1d8cb8b674 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 f0b06ec19c3..564ece3384c 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 e8100920923..3d4b785f418 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 af9ee91c48a..4258199e3d0 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 face60dbfdf..e7e1660d813 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.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 539693adfd6..2933d04bdf8 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 269d709a66b..5925cec226e 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 6af8f9de9ee..2ed12526cee 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.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 4d8d66b7db4..e4cc101b910 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.assertTrue;
/**
- * {@link StringToListConverter} Test
+ * {@link StringToTransferQueueConverter} Test
*
* @since 2.7.6
*/
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
index 014405959f0..24cb292104d 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/PojoUtilsTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.dubbo.common.utils;
-import com.alibaba.fastjson.JSONObject;
import org.apache.dubbo.common.model.Person;
import org.apache.dubbo.common.model.SerializablePerson;
import org.apache.dubbo.common.model.User;
@@ -26,6 +25,7 @@
import org.apache.dubbo.common.model.person.PersonStatus;
import org.apache.dubbo.common.model.person.Phone;
+import com.alibaba.fastjson.JSONObject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/StringConstantFieldValuePredicateTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/StringConstantFieldValuePredicateTest.java
new file mode 100644
index 00000000000..061854296f5
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/StringConstantFieldValuePredicateTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.common.utils;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.function.Predicate;
+
+import static org.apache.dubbo.common.utils.StringConstantFieldValuePredicate.of;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link StringConstantFieldValuePredicate} Test
+ *
+ * @since 2.7.8
+ */
+public class StringConstantFieldValuePredicateTest {
+
+ public static final String S1 = "1";
+
+ public static final Object O1 = "2";
+
+ public static final Object O2 = 3;
+
+ @Test
+ public void test() {
+ Predicate predicate = of(getClass());
+ assertTrue(predicate.test("1"));
+ assertTrue(predicate.test("2"));
+ assertFalse(predicate.test("3"));
+ }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/StringUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/StringUtilsTest.java
index 736e9d84338..0d38e6c8c54 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/StringUtilsTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/StringUtilsTest.java
@@ -18,19 +18,33 @@
import org.junit.jupiter.api.Test;
-import java.util.*;
-
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.utils.CollectionUtils.ofSet;
+import static org.apache.dubbo.common.utils.StringUtils.splitToList;
+import static org.apache.dubbo.common.utils.StringUtils.splitToSet;
+import static org.apache.dubbo.common.utils.StringUtils.toCommaDelimitedString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.nullValue;
-import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class StringUtilsTest {
@Test
@@ -234,16 +248,32 @@ public void testSplit() throws Exception {
public void testSplitToList() throws Exception {
String str = "d,1,2,4";
- assertEquals(4, StringUtils.splitToList(str, ',').size());
- assertEquals(Arrays.asList(str.split(",")), StringUtils.splitToList(str, ','));
+ assertEquals(4, splitToList(str, ',').size());
+ assertEquals(asList(str.split(",")), splitToList(str, ','));
- assertEquals(1, StringUtils.splitToList(str, 'a').size());
- assertEquals(Arrays.asList(str.split("a")), StringUtils.splitToList(str, 'a'));
+ assertEquals(1, splitToList(str, 'a').size());
+ assertEquals(asList(str.split("a")), splitToList(str, 'a'));
- assertEquals(0, StringUtils.splitToList("", 'a').size());
- assertEquals(0, StringUtils.splitToList(null, 'a').size());
+ assertEquals(0, splitToList("", 'a').size());
+ assertEquals(0, splitToList(null, 'a').size());
}
+ /**
+ * Test {@link StringUtils#splitToSet(String, char, boolean)}
+ *
+ * @since 2.7.8
+ */
+ @Test
+ public void testSplitToSet() {
+ String value = "1# 2#3 #4#3";
+ Set values = splitToSet(value, '#', false);
+ assertEquals(ofSet("1", " 2", "3 ", "4", "3"), values);
+
+ values = splitToSet(value, '#', true);
+ assertEquals(ofSet("1", "2", "3", "4"), values);
+ }
+
+
@Test
public void testTranslate() throws Exception {
String s = "16314";
@@ -363,4 +393,29 @@ public void testParseParameters() {
assertEquals(0, illegalMap.size());
}
+ /**
+ * Test {@link StringUtils#toCommaDelimitedString(String, String...)}
+ * @since 2.7.8
+ */
+ @Test
+ public void testToCommaDelimitedString() {
+ String value = toCommaDelimitedString(null);
+ assertNull(value);
+
+ value = toCommaDelimitedString(null, null);
+ assertNull(value);
+
+ value = toCommaDelimitedString("");
+ assertEquals("", value);
+
+ value = toCommaDelimitedString("one");
+ assertEquals("one", value);
+
+ value = toCommaDelimitedString("one", "two");
+ assertEquals("one,two", value);
+
+ value = toCommaDelimitedString("one", "two", "three");
+ assertEquals("one,two,three", value);
+ }
+
}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
index 58fc3cccdd3..24c4f0028cf 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
@@ -49,7 +49,12 @@ public class ConfigManagerTest {
@BeforeEach
public void init() {
- configManager.clear();
+ configManager.destroy();
+ }
+
+ @Test
+ public void testDestroy() {
+ assertTrue(configManager.configsCache.isEmpty());
}
@Test
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/event/EchoEventListener2.java b/dubbo-common/src/test/java/org/apache/dubbo/event/EchoEventListener2.java
index 18e7cf90aeb..0d27802d15f 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/event/EchoEventListener2.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/event/EchoEventListener2.java
@@ -41,7 +41,7 @@ public void onEvent(Event event) {
@Override
public int getPriority() {
- return 0;
+ return -1;
}
public int getEventOccurs() {
diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ConfigTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ConfigTest.java
index 95608d76c23..9ce219193a1 100644
--- a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ConfigTest.java
+++ b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ConfigTest.java
@@ -35,14 +35,14 @@ public class ConfigTest {
@AfterEach
public void tearDown() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@BeforeEach
public void setup() {
// In IDE env, make sure adding the following argument to VM options
System.setProperty("java.net.preferIPv4Stack", "true");
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@Test
diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index d30f632fb1f..883dc12cbce 100644
--- a/dubbo-compatible/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ b/dubbo-compatible/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -38,12 +38,12 @@ public class ReferenceConfigTest {
@BeforeEach
public void setUp() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@AfterEach
public void tearDown() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@Test
diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml
index 89580bd5347..4ccfd67a36c 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -135,6 +135,12 @@
dubbo-registry-eureka
${project.parent.version}
test
+
+
+ com.google.guava
+ guava
+
+
@@ -156,6 +162,12 @@
dubbo-metadata-report-zookeeper
${project.parent.version}
test
+
+
+ com.google.guava
+ guava
+
+
@@ -170,6 +182,19 @@
dubbo-metadata-report-nacos
${project.parent.version}
test
+
+
+ com.google.guava
+ guava
+
+
+
+
+
+ org.apache.dubbo
+ dubbo-metadata-report-consul
+ ${project.parent.version}
+ test
@@ -191,6 +216,12 @@
dubbo-configcenter-nacos
${project.parent.version}
test
+
+
+ com.google.guava
+ guava
+
+
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index df9eed242c3..570f7a49f0e 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -19,6 +19,7 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.bytecode.Wrapper;
+import org.apache.dubbo.common.constants.RegistryConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
@@ -31,10 +32,10 @@
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.event.ReferenceConfigDestroyedEvent;
import org.apache.dubbo.config.event.ReferenceConfigInitializedEvent;
+import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.event.Event;
import org.apache.dubbo.event.EventDispatcher;
-import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProxyFactory;
@@ -57,25 +58,25 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
+import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR_CHAR;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
-import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROXY_CLASS_REF;
-import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SEMICOLON_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
import static org.apache.dubbo.common.utils.NetUtils.isInvalidLocalHost;
+import static org.apache.dubbo.common.utils.StringUtils.splitToSet;
import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
-import static org.apache.dubbo.registry.Constants.CONSUMER_PROTOCOL;
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
@@ -140,6 +141,13 @@ public class ReferenceConfig extends ReferenceConfigBase {
private DubboBootstrap bootstrap;
+ /**
+ * The service names that the Dubbo interface subscribed.
+ *
+ * @since 2.7.8
+ */
+ private String services;
+
public ReferenceConfig() {
super();
this.repository = ApplicationModel.getServiceRepository();
@@ -150,6 +158,40 @@ public ReferenceConfig(Reference reference) {
this.repository = ApplicationModel.getServiceRepository();
}
+ /**
+ * Get a string presenting the service names that the Dubbo interface subscribed.
+ * If it is a multiple-values, the content will be a comma-delimited String.
+ *
+ * @return non-null
+ * @see RegistryConstants#SUBSCRIBED_SERVICE_NAMES_KEY
+ * @since 2.7.8
+ */
+ @Parameter(key = SUBSCRIBED_SERVICE_NAMES_KEY)
+ public String getServices() {
+ return services;
+ }
+
+ /**
+ * It's an alias method for {@link #getServices()}, but the more convenient.
+ *
+ * @return the String {@link List} presenting the Dubbo interface subscribed
+ * @since 2.7.8
+ */
+ @Parameter(excluded = true)
+ public Set getSubscribedServices() {
+ return splitToSet(getServices(), COMMA_SEPARATOR_CHAR);
+ }
+
+ /**
+ * Set the service names that the Dubbo interface subscribed.
+ *
+ * @param services If it is a multiple-values, the content will be a comma-delimited String.
+ * @since 2.7.8
+ */
+ public void setServices(String services) {
+ this.services = services;
+ }
+
public synchronized T get() {
if (destroyed) {
throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!");
@@ -221,10 +263,6 @@ public synchronized void init() {
// appendParameters(map, consumer, Constants.DEFAULT_KEY);
AbstractConfig.appendParameters(map, consumer);
AbstractConfig.appendParameters(map, this);
- MetadataReportConfig metadataReportConfig = getMetadataReportConfig();
- if (metadataReportConfig != null && metadataReportConfig.isValid()) {
- map.putIfAbsent(METADATA_KEY, REMOTE_METADATA_STORAGE_TYPE);
- }
Map attributes = null;
if (CollectionUtils.isNotEmpty(getMethods())) {
attributes = new HashMap<>();
@@ -355,16 +393,6 @@ private T createProxy(Map map) {
if (logger.isInfoEnabled()) {
logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());
}
- /**
- * @since 2.7.0
- * ServiceData Store
- */
- String metadata = map.get(METADATA_KEY);
- WritableMetadataService metadataService = WritableMetadataService.getExtension(metadata == null ? DEFAULT_METADATA_STORAGE_TYPE : metadata);
- if (metadataService != null) {
- URL consumerURL = new URL(CONSUMER_PROTOCOL, map.remove(REGISTER_IP_KEY), 0, map.get(INTERFACE_KEY), map);
- metadataService.publishServiceDefinition(consumerURL);
- }
// create service proxy
return (T) PROXY_FACTORY.getProxy(invoker, ProtocolUtils.isGeneric(generic));
}
@@ -469,7 +497,7 @@ public void setBootstrap(DubboBootstrap bootstrap) {
}
private void postProcessConfig() {
- List configPostProcessors =ExtensionLoader.getExtensionLoader(ConfigPostProcessor.class)
+ List configPostProcessors = ExtensionLoader.getExtensionLoader(ConfigPostProcessor.class)
.getActivateExtension(URL.valueOf("configPostProcessor://"), (String[]) null);
configPostProcessors.forEach(component -> component.postProcessReferConfig(this));
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 3ad4545f382..5173bf71ced 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -37,7 +37,6 @@
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.event.Event;
import org.apache.dubbo.event.EventDispatcher;
-import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
@@ -68,16 +67,13 @@
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND;
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
-import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.REGISTER_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.DYNAMIC_KEY;
@@ -187,7 +183,7 @@ public synchronized void export() {
if (bootstrap == null) {
bootstrap = DubboBootstrap.getInstance();
- bootstrap.init();
+ bootstrap.initialize();
}
checkAndUpdateSubConfigs();
@@ -344,10 +340,6 @@ private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List r
AbstractConfig.appendParameters(map, provider);
AbstractConfig.appendParameters(map, protocolConfig);
AbstractConfig.appendParameters(map, this);
- MetadataReportConfig metadataReportConfig = getMetadataReportConfig();
- if (metadataReportConfig != null && metadataReportConfig.isValid()) {
- map.putIfAbsent(METADATA_KEY, REMOTE_METADATA_STORAGE_TYPE);
- }
if (CollectionUtils.isNotEmpty(getMethods())) {
for (MethodConfig method : getMethods()) {
AbstractConfig.appendParameters(map, method, method.getName());
@@ -502,14 +494,6 @@ private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List r
Exporter> exporter = PROTOCOL.export(wrapperInvoker);
exporters.add(exporter);
}
- /**
- * @since 2.7.0
- * ServiceData Store
- */
- WritableMetadataService metadataService = WritableMetadataService.getExtension(url.getParameter(METADATA_KEY, DEFAULT_METADATA_STORAGE_TYPE));
- if (metadataService != null) {
- metadataService.publishServiceDefinition(url);
- }
}
}
this.urls.add(url);
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
index cd92fe5e52c..10dd4f209f7 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
@@ -52,7 +52,6 @@
import org.apache.dubbo.config.bootstrap.builders.RegistryBuilder;
import org.apache.dubbo.config.bootstrap.builders.ServiceBuilder;
import org.apache.dubbo.config.context.ConfigManager;
-import org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.apache.dubbo.event.EventDispatcher;
@@ -66,6 +65,7 @@
import org.apache.dubbo.registry.client.ServiceDiscovery;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
import org.apache.dubbo.registry.client.ServiceInstance;
+import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
import org.apache.dubbo.registry.support.AbstractRegistryFactory;
import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -93,17 +93,17 @@
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.apache.dubbo.common.function.ThrowableAction.execute;
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
-import static org.apache.dubbo.metadata.WritableMetadataService.getExtension;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.setMetadataStorageType;
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
/**
* See {@link ApplicationModel} and {@link ExtensionLoader} for why this class is designed to be singleton.
- *
+ *
* The bootstrap class of Dubbo
- *
+ *
* Get singleton instance by calling static method {@link #getInstance()}.
* Designed as singleton because some classes inside Dubbo, such as ExtensionLoader, are designed only for one instance per process.
*
@@ -141,7 +141,7 @@ public class DubboBootstrap extends GenericEventListener {
private final EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
- private final ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
+ private final ExecutorRepository executorRepository = getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
private final ConfigManager configManager;
@@ -165,7 +165,7 @@ public class DubboBootstrap extends GenericEventListener {
private volatile MetadataService metadataService;
- private volatile MetadataServiceExporter metadataServiceExporter;
+ private volatile Set metadataServiceExporters;
private List> exportedServices = new ArrayList<>();
@@ -500,7 +500,7 @@ public void init() {
/**
* Initialize
*/
- private void initialize() {
+ public void initialize() {
if (!initialized.compareAndSet(false, true)) {
return;
}
@@ -509,14 +509,17 @@ private void initialize() {
startConfigCenter();
- useRegistryAsConfigCenterIfNecessary();
-
loadRemoteConfigs();
checkGlobalConfigs();
+ // @since 2.7.8
+ startMetadataCenter();
+
initMetadataService();
+ initMetadataServiceExports();
+
initEventListener();
if (logger.isInfoEnabled()) {
@@ -583,6 +586,9 @@ private void checkGlobalConfigs() {
}
private void startConfigCenter() {
+
+ useRegistryAsConfigCenterIfNecessary();
+
Collection configCenters = configManager.getConfigCenters();
// check Config Center
@@ -610,7 +616,10 @@ private void startConfigCenter() {
configManager.refreshAll();
}
- private void startMetadataReport() {
+ private void startMetadataCenter() {
+
+ useRegistryAsMetadataCenterIfNecessary();
+
ApplicationConfig applicationConfig = getApplication();
String metadataType = applicationConfig.getMetadataType();
@@ -646,33 +655,87 @@ private void useRegistryAsConfigCenterIfNecessary() {
return;
}
- configManager.getDefaultRegistries().stream()
- .filter(registryConfig -> registryConfig.getUseAsConfigCenter() == null || registryConfig.getUseAsConfigCenter())
- .forEach(registryConfig -> {
- String protocol = registryConfig.getProtocol();
- String id = "config-center-" + protocol + "-" + registryConfig.getPort();
- ConfigCenterConfig cc = new ConfigCenterConfig();
- cc.setId(id);
- if (cc.getParameters() == null) {
- cc.setParameters(new HashMap<>());
- }
- if (registryConfig.getParameters() != null) {
- cc.getParameters().putAll(registryConfig.getParameters());
- }
- cc.getParameters().put(CLIENT_KEY, registryConfig.getClient());
- cc.setProtocol(registryConfig.getProtocol());
- cc.setPort(registryConfig.getPort());
- cc.setAddress(getRegistryCompatibleAddress(registryConfig.getAddress()));
- cc.setNamespace(registryConfig.getGroup());
- cc.setUsername(registryConfig.getUsername());
- cc.setPassword(registryConfig.getPassword());
- if (registryConfig.getTimeout() != null) {
- cc.setTimeout(registryConfig.getTimeout().longValue());
- }
- cc.setHighestPriority(false);
- configManager.addConfigCenter(cc);
- });
- startConfigCenter();
+ configManager
+ .getDefaultRegistries()
+ .stream()
+ .filter(this::isUsedRegistryAsConfigCenter)
+ .map(this::registryAsConfigCenter)
+ .forEach(configManager::addConfigCenter);
+ }
+
+ private boolean isUsedRegistryAsConfigCenter(RegistryConfig registryConfig) {
+ // TODO: confirm ? registryConfig.getUseAsConfigCenter() == null || registryConfig.getUseAsConfigCenter()
+ return Boolean.TRUE.equals(registryConfig.getUseAsConfigCenter());
+ }
+
+ private ConfigCenterConfig registryAsConfigCenter(RegistryConfig registryConfig) {
+ String protocol = registryConfig.getProtocol();
+ Integer port = registryConfig.getPort();
+ String id = "config-center-" + protocol + "-" + port;
+ ConfigCenterConfig cc = new ConfigCenterConfig();
+ cc.setId(id);
+ if (cc.getParameters() == null) {
+ cc.setParameters(new HashMap<>());
+ }
+ if (registryConfig.getParameters() != null) {
+ cc.getParameters().putAll(registryConfig.getParameters()); // copy the parameters
+ }
+ cc.getParameters().put(CLIENT_KEY, registryConfig.getClient());
+ cc.setProtocol(protocol);
+ cc.setPort(port);
+ cc.setGroup(registryConfig.getGroup());
+ cc.setAddress(getRegistryCompatibleAddress(registryConfig.getAddress()));
+ cc.setNamespace(registryConfig.getGroup());
+ cc.setUsername(registryConfig.getUsername());
+ cc.setPassword(registryConfig.getPassword());
+ if (registryConfig.getTimeout() != null) {
+ cc.setTimeout(registryConfig.getTimeout().longValue());
+ }
+ cc.setHighestPriority(false);
+ return cc;
+ }
+
+ private void useRegistryAsMetadataCenterIfNecessary() {
+
+ Collection metadataConfigs = configManager.getMetadataConfigs();
+
+ if (CollectionUtils.isNotEmpty(metadataConfigs)) {
+ return;
+ }
+
+ configManager
+ .getDefaultRegistries()
+ .stream()
+ .filter(this::isUsedRegistryAsMetadataCenter)
+ .map(this::registryAsMetadataCenter)
+ .forEach(configManager::addMetadataReport);
+
+ }
+
+ private boolean isUsedRegistryAsMetadataCenter(RegistryConfig registryConfig) {
+ // TODO: confirm ? registryConfig.getUseAsMetadataCenter() == null || registryConfig.getUseAsMetadataCenter()
+ return Boolean.TRUE.equals(registryConfig.getUseAsMetadataCenter());
+ }
+
+ private MetadataReportConfig registryAsMetadataCenter(RegistryConfig registryConfig) {
+ String protocol = registryConfig.getProtocol();
+ Integer port = registryConfig.getPort();
+ String id = "metadata-center-" + protocol + "-" + port;
+ MetadataReportConfig metadataReportConfig = new MetadataReportConfig();
+ metadataReportConfig.setId(id);
+ if (metadataReportConfig.getParameters() == null) {
+ metadataReportConfig.setParameters(new HashMap<>());
+ }
+ if (registryConfig.getParameters() != null) {
+ metadataReportConfig.getParameters().putAll(registryConfig.getParameters()); // copy the parameters
+ }
+ metadataReportConfig.getParameters().put(CLIENT_KEY, registryConfig.getClient());
+ metadataReportConfig.setGroup(registryConfig.getGroup());
+ metadataReportConfig.setAddress(getRegistryCompatibleAddress(registryConfig.getAddress()));
+ metadataReportConfig.setUsername(registryConfig.getUsername());
+ metadataReportConfig.setPassword(registryConfig.getPassword());
+ metadataReportConfig.setTimeout(registryConfig.getTimeout());
+ return metadataReportConfig;
}
private String getRegistryCompatibleAddress(String registryAddress) {
@@ -719,12 +782,17 @@ private void loadRemoteConfigs() {
/**
- * Initialize {@link MetadataService} from {@link WritableMetadataService}'s extension
+ * Initialize {@link #metadataService WritableMetadataService} from {@link WritableMetadataService}'s extension
*/
private void initMetadataService() {
- startMetadataReport();
- this.metadataService = getExtension(getMetadataType());
- this.metadataServiceExporter = new ConfigurableMetadataServiceExporter(metadataService);
+ this.metadataService = WritableMetadataService.getExtension(getMetadataType());
+ }
+
+ /**
+ * Initialize {@link #metadataServiceExporters MetadataServiceExporter}
+ */
+ private void initMetadataServiceExports() {
+ this.metadataServiceExporters = getExtensionLoader(MetadataServiceExporter.class).getSupportedExtensionInstances();
}
/**
@@ -926,13 +994,21 @@ public DubboBootstrap addEventListener(EventListener> listener) {
* export {@link MetadataService}
*/
private void exportMetadataService() {
- metadataServiceExporter.export();
+ metadataServiceExporters
+ .stream()
+ .filter(this::supports)
+ .forEach(MetadataServiceExporter::export);
}
private void unexportMetadataService() {
- if (metadataServiceExporter != null && metadataServiceExporter.isExported()) {
- metadataServiceExporter.unexport();
- }
+ metadataServiceExporters
+ .stream()
+ .filter(this::supports)
+ .forEach(MetadataServiceExporter::unexport);
+ }
+
+ private boolean supports(MetadataServiceExporter exporter) {
+ return exporter.supports(getMetadataType());
}
private void exportServices() {
@@ -1025,9 +1101,37 @@ private void registerServiceInstance() {
ServiceInstance serviceInstance = createServiceInstance(serviceName, host, port);
+ preRegisterServiceInstance(serviceInstance);
+
getServiceDiscoveries().forEach(serviceDiscovery -> serviceDiscovery.register(serviceInstance));
}
+ /**
+ * Pre-register {@link ServiceInstance the service instance}
+ *
+ * @param serviceInstance {@link ServiceInstance the service instance}
+ * @since 2.7.8
+ */
+ private void preRegisterServiceInstance(ServiceInstance serviceInstance) {
+ customizeServiceInstance(serviceInstance);
+ }
+
+ /**
+ * Customize {@link ServiceInstance the service instance}
+ *
+ * @param serviceInstance {@link ServiceInstance the service instance}
+ * @since 2.7.8
+ */
+ private void customizeServiceInstance(ServiceInstance serviceInstance) {
+ ExtensionLoader loader =
+ getExtensionLoader(ServiceInstanceCustomizer.class);
+ // FIXME, sort customizer before apply
+ loader.getSupportedExtensionInstances().forEach(customizer -> {
+ // customizes
+ customizer.customize(serviceInstance);
+ });
+ }
+
private URL selectMetadataServiceExportedURL() {
URL selectedURL = null;
@@ -1118,7 +1222,7 @@ private void clearApplicationModel() {
}
private void clearConfigs() {
- configManager.clear();
+ configManager.destroy();
if (logger.isDebugEnabled()) {
logger.debug(NAME + "'s configs have been clear.");
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilder.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilder.java
index 69e798433bd..99af153c301 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilder.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilder.java
@@ -24,6 +24,8 @@
import java.util.ArrayList;
import java.util.List;
+import static org.apache.dubbo.common.utils.StringUtils.toCommaDelimitedString;
+
/**
* This is a builder for build {@link ReferenceConfigBase}.
*
@@ -65,6 +67,13 @@ public class ReferenceBuilder extends AbstractReferenceBuilder protocol(String protocol) {
return getThis();
}
+ /**
+ * @param service one service name
+ * @param otherServices other service names
+ * @return {@link ReferenceBuilder}
+ * @since 2.7.8
+ */
+ public ReferenceBuilder services(String service, String... otherServices) {
+ this.services = toCommaDelimitedString(service, otherServices);
+ return getThis();
+ }
+
public ReferenceConfig build() {
ReferenceConfig reference = new ReferenceConfig<>();
super.build(reference);
@@ -132,6 +152,8 @@ public ReferenceConfig build() {
reference.setMethods(methods);
reference.setConsumer(consumer);
reference.setProtocol(protocol);
+ // @since 2.7.8
+ reference.setServices(services);
return reference;
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilder.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilder.java
index f2ffab86e3a..d717aaaf66f 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilder.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilder.java
@@ -285,6 +285,16 @@ public RegistryBuilder appendParameter(String key, String value) {
return getThis();
}
+ /**
+ * @param name the parameter name
+ * @param value the parameter value
+ * @return {@link RegistryBuilder}
+ * @since 2.7.8
+ */
+ public RegistryBuilder parameter(String name, String value) {
+ return appendParameter(name, value);
+ }
+
public RegistryBuilder appendParameters(Map appendParameters) {
this.parameters = appendParameters(parameters, appendParameters);
return getThis();
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListener.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListener.java
new file mode 100644
index 00000000000..9731034c70a
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListener.java
@@ -0,0 +1,74 @@
+/*
+ * 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.config.event.listener;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.AbstractInterfaceConfig;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.event.ReferenceConfigInitializedEvent;
+import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
+import org.apache.dubbo.event.EventListener;
+import org.apache.dubbo.event.GenericEventListener;
+import org.apache.dubbo.metadata.WritableMetadataService;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.metadata.WritableMetadataService.getExtension;
+
+/**
+ * An {@link EventListener} {@link WritableMetadataService#publishServiceDefinition(URL) publishs the service definition}
+ * when {@link ServiceConfigExportedEvent the event of the exported Dubbo service} and
+ * {@link ReferenceConfigInitializedEvent the event of the referenced Dubbo service} is raised.
+ *
+ * @see GenericEventListener
+ * @see ServiceConfigExportedEvent
+ * @see ReferenceConfigInitializedEvent
+ * @since 2.7.8
+ */
+public class PublishingServiceDefinitionListener extends GenericEventListener {
+
+ public void onEvent(ReferenceConfigInitializedEvent event) {
+ handleEvent(event.getReferenceConfig());
+ }
+
+ public void onEvent(ServiceConfigExportedEvent event) {
+ handleEvent(event.getServiceConfig());
+ }
+
+ private void handleEvent(AbstractInterfaceConfig config) {
+ String metadataType = getMetadataType(config);
+ for (URL exportedURL : config.getExportedUrls()) {
+ WritableMetadataService metadataService = getExtension(metadataType);
+ if (metadataService != null) {
+ metadataService.publishServiceDefinition(exportedURL);
+ }
+ }
+ }
+
+ private String getMetadataType(AbstractInterfaceConfig config) {
+ ApplicationConfig applicationConfig = config.getApplication();
+ String metadataType = applicationConfig.getMetadataType();
+ if (REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) {
+ MetadataReportConfig metadataReportConfig = config.getMetadataReportConfig();
+ if (metadataReportConfig == null || !metadataReportConfig.isValid()) {
+ metadataType = DEFAULT_METADATA_STORAGE_TYPE;
+ }
+ }
+ return metadataType;
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/event/listener/ServiceNameMappingListener.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/event/listener/ServiceNameMappingListener.java
index 4dcfde3a94a..8607b51f37c 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/event/listener/ServiceNameMappingListener.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/event/listener/ServiceNameMappingListener.java
@@ -24,8 +24,6 @@
import java.util.List;
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.metadata.ServiceNameMapping.getDefaultExtension;
/**
@@ -45,11 +43,7 @@ public void onEvent(ServiceConfigExportedEvent event) {
ServiceConfig serviceConfig = event.getServiceConfig();
List exportedURLs = serviceConfig.getExportedUrls();
exportedURLs.forEach(url -> {
- String serviceInterface = url.getServiceInterface();
- String group = url.getParameter(GROUP_KEY);
- String version = url.getParameter(VERSION_KEY);
- String protocol = url.getProtocol();
- serviceNameMapping.map(serviceInterface, group, version, protocol);
+ serviceNameMapping.map(url);
});
}
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/AbstractMetadataServiceExporter.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/AbstractMetadataServiceExporter.java
new file mode 100644
index 00000000000..ce2b389c220
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/AbstractMetadataServiceExporter.java
@@ -0,0 +1,150 @@
+/*
+ * 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.config.metadata;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.metadata.MetadataServiceExporter;
+import org.apache.dubbo.metadata.MetadataServiceType;
+import org.apache.dubbo.metadata.WritableMetadataService;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.EnumSet.of;
+import static org.apache.dubbo.metadata.MetadataServiceType.getOrDefault;
+
+/**
+ * The abstract implementation of {@link MetadataServiceExporter} to provider the commons features for sub-types
+ *
+ * @see MetadataServiceExporter
+ * @see MetadataService
+ * @since 2.7.8
+ */
+public abstract class AbstractMetadataServiceExporter implements MetadataServiceExporter {
+
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ protected final WritableMetadataService metadataService;
+
+ private final int priority;
+
+ private final Set supportedMetadataServiceTypes;
+
+ private volatile boolean exported = false;
+
+ public AbstractMetadataServiceExporter(String metadataType,
+ int priority,
+ MetadataServiceType supportMetadataServiceType,
+ MetadataServiceType... otherSupportMetadataServiceTypes) {
+ this(metadataType, priority, of(supportMetadataServiceType, otherSupportMetadataServiceTypes));
+ }
+
+ public AbstractMetadataServiceExporter(String metadataType,
+ int priority,
+ Set supportedMetadataServiceTypes) {
+ this.metadataService = WritableMetadataService.getExtension(metadataType);
+ this.priority = priority;
+ this.supportedMetadataServiceTypes = supportedMetadataServiceTypes;
+ }
+
+ @Override
+ public final MetadataServiceExporter export() {
+ if (!isExported()) {
+ try {
+ doExport();
+ exported = true;
+ } catch (Exception e) {
+ if (logger.isErrorEnabled()) {
+ logger.error("Exporting the MetadataService fails", e);
+ }
+ exported = false;
+ }
+ } else {
+ if (logger.isWarnEnabled()) {
+ logger.warn("The MetadataService has been exported : " + getExportedURLs());
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public final MetadataServiceExporter unexport() {
+ if (isExported()) {
+ try {
+ doUnexport();
+ exported = false;
+ } catch (Exception e) {
+ if (logger.isErrorEnabled()) {
+ logger.error("UnExporting the MetadataService fails", e);
+ }
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public List getExportedURLs() {
+ return metadataService
+ .getExportedURLs()
+ .stream()
+ .map(URL::valueOf)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public boolean isExported() {
+ return exported;
+ }
+
+ @Override
+ public final boolean supports(String metadataType) {
+ MetadataServiceType metadataServiceType = getOrDefault(metadataType);
+ return supportedMetadataServiceTypes.contains(metadataServiceType);
+ }
+
+ @Override
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * Exports the {@link MetadataService}
+ *
+ * @throws Exception If some exception occurs
+ */
+ protected abstract void doExport() throws Exception;
+
+ /**
+ * Unexports the {@link MetadataService}
+ *
+ * @throws Exception If some exception occurs
+ */
+ protected abstract void doUnexport() throws Exception;
+
+ /**
+ * Get the underlying of {@link MetadataService}
+ *
+ * @return non-null
+ */
+ public WritableMetadataService getMetadataService() {
+ return metadataService;
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
index fdb011f8953..d89fb7719fc 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ConfigurableMetadataServiceExporter.java
@@ -17,8 +17,6 @@
package org.apache.dubbo.config.metadata;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
@@ -26,12 +24,15 @@
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.MetadataServiceExporter;
+import org.apache.dubbo.metadata.MetadataServiceType;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.emptyList;
+import static java.util.EnumSet.allOf;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
/**
@@ -49,56 +50,41 @@
* @see ConfigManager
* @since 2.7.5
*/
-public class ConfigurableMetadataServiceExporter implements MetadataServiceExporter {
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final MetadataService metadataService;
+public class ConfigurableMetadataServiceExporter extends AbstractMetadataServiceExporter {
private volatile ServiceConfig serviceConfig;
- public ConfigurableMetadataServiceExporter(MetadataService metadataService) {
- this.metadataService = metadataService;
+ public ConfigurableMetadataServiceExporter() {
+ super(DEFAULT_METADATA_STORAGE_TYPE, MAX_PRIORITY, allOf(MetadataServiceType.class));
}
@Override
- public ConfigurableMetadataServiceExporter export() {
-
- if (!isExported()) {
-
- ServiceConfig serviceConfig = new ServiceConfig<>();
- serviceConfig.setApplication(getApplicationConfig());
- serviceConfig.setRegistries(getRegistries());
- serviceConfig.setProtocol(generateMetadataProtocol());
- serviceConfig.setInterface(MetadataService.class);
- serviceConfig.setRef(metadataService);
- serviceConfig.setGroup(getApplicationConfig().getName());
- serviceConfig.setVersion(metadataService.version());
-
- // export
- serviceConfig.export();
-
- if (logger.isInfoEnabled()) {
- logger.info("The MetadataService exports urls : " + serviceConfig.getExportedUrls());
- }
-
- this.serviceConfig = serviceConfig;
-
- } else {
- if (logger.isWarnEnabled()) {
- logger.warn("The MetadataService has been exported : " + serviceConfig.getExportedUrls());
- }
+ protected void doExport() throws Exception {
+
+ ServiceConfig serviceConfig = new ServiceConfig<>();
+ serviceConfig.setApplication(getApplicationConfig());
+ serviceConfig.setRegistries(getRegistries());
+ serviceConfig.setProtocol(generateMetadataProtocol());
+ serviceConfig.setInterface(MetadataService.class);
+ serviceConfig.setRef(metadataService);
+ serviceConfig.setGroup(getApplicationConfig().getName());
+ serviceConfig.setVersion(metadataService.version());
+
+ // export
+ serviceConfig.export();
+
+ if (logger.isInfoEnabled()) {
+ logger.info("The MetadataService exports urls : " + serviceConfig.getExportedUrls());
}
- return this;
+ this.serviceConfig = serviceConfig;
}
@Override
- public ConfigurableMetadataServiceExporter unexport() {
- if (isExported()) {
+ protected void doUnexport() throws Exception {
+ if (serviceConfig != null) {
serviceConfig.unexport();
}
- return this;
}
@Override
@@ -110,6 +96,11 @@ public boolean isExported() {
return serviceConfig != null && serviceConfig.isExported();
}
+ @Override
+ public int getPriority() {
+ return MAX_PRIORITY;
+ }
+
private ApplicationConfig getApplicationConfig() {
return ApplicationModel.getConfigManager().getApplication().get();
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/RemoteMetadataServiceExporter.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/RemoteMetadataServiceExporter.java
new file mode 100644
index 00000000000..6d4892101f7
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/RemoteMetadataServiceExporter.java
@@ -0,0 +1,79 @@
+/*
+ * 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.config.metadata;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.metadata.MetadataServiceExporter;
+import org.apache.dubbo.metadata.MetadataServiceType;
+import org.apache.dubbo.metadata.URLRevisionResolver;
+import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.MetadataReportInstance;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+
+import java.util.SortedSet;
+
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+
+/**
+ * The implementation of {@link MetadataServiceExporter} for
+ * {@link CommonConstants#REMOTE_METADATA_STORAGE_TYPE "remote" metadata storage type}
+ *
+ * @see MetadataServiceExporter
+ * @since 2.7.8
+ */
+public class RemoteMetadataServiceExporter extends AbstractMetadataServiceExporter {
+
+ private final URLRevisionResolver urlRevisionResolver;
+
+ public RemoteMetadataServiceExporter() {
+ super(REMOTE_METADATA_STORAGE_TYPE, MIN_PRIORITY, MetadataServiceType.REMOTE, MetadataServiceType.COMPOSITE);
+ this.urlRevisionResolver = URLRevisionResolver.INSTANCE;
+ }
+
+ @Override
+ protected void doExport() throws Exception {
+ WritableMetadataService metadataServiceDelegate = WritableMetadataService.getDefaultExtension();
+ if (publishServiceMetadata(metadataServiceDelegate)) {
+ publicConsumerMetadata(metadataServiceDelegate);
+ }
+ }
+
+ private boolean publishServiceMetadata(WritableMetadataService metadataServiceDelegate) {
+ String serviceName = metadataServiceDelegate.serviceName();
+ SortedSet exportedURLs = metadataServiceDelegate.getExportedURLs();
+ String revision = urlRevisionResolver.resolve(exportedURLs);
+ return getMetadataReport().saveExportedURLs(serviceName, revision, exportedURLs);
+ }
+
+ private boolean publicConsumerMetadata(WritableMetadataService metadataServiceDelegate) {
+ String serviceName = metadataServiceDelegate.serviceName();
+ SortedSet subscribedURLs = metadataServiceDelegate.getSubscribedURLs();
+ String revision = urlRevisionResolver.resolve(subscribedURLs);
+ getMetadataReport().saveSubscribedData(new SubscriberMetadataIdentifier(serviceName, revision), subscribedURLs);
+ return true;
+ }
+
+ private MetadataReport getMetadataReport() {
+ return MetadataReportInstance.getMetadataReport(true);
+ }
+
+ @Override
+ protected void doUnexport() throws Exception {
+ // DOES NOTHING
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java
index 2e46fa26024..8a91d1cce5e 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/ConfigValidationUtils.java
@@ -223,10 +223,12 @@ public static URL loadMonitor(AbstractInterfaceConfig interfaceConfig, URL regis
ApplicationConfig application = interfaceConfig.getApplication();
AbstractConfig.appendParameters(map, monitor);
AbstractConfig.appendParameters(map, application);
- String address = monitor.getAddress();
+ String address = null;
String sysaddress = System.getProperty("dubbo.monitor.address");
if (sysaddress != null && sysaddress.length() > 0) {
address = sysaddress;
+ } else if (monitor != null) {
+ address = monitor.getAddress();
}
if (ConfigUtils.isNotEmpty(address)) {
if (!map.containsKey(PROTOCOL_KEY)) {
@@ -237,7 +239,8 @@ public static URL loadMonitor(AbstractInterfaceConfig interfaceConfig, URL regis
}
}
return UrlUtils.parseURL(address, map);
- } else if ((REGISTRY_PROTOCOL.equals(monitor.getProtocol()) || SERVICE_REGISTRY_PROTOCOL.equals(monitor.getProtocol()))
+ } else if (monitor != null &&
+ (REGISTRY_PROTOCOL.equals(monitor.getProtocol()) || SERVICE_REGISTRY_PROTOCOL.equals(monitor.getProtocol()))
&& registryURL != null) {
return URLBuilder.from(registryURL)
.setProtocol(DUBBO_PROTOCOL)
diff --git a/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener b/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
index db73041bd43..b1946c09f30 100644
--- a/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
+++ b/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
@@ -1,2 +1,4 @@
service-mapping=org.apache.dubbo.config.event.listener.ServiceNameMappingListener
-config-logging=org.apache.dubbo.config.event.listener.LoggingEventListener
\ No newline at end of file
+config-logging=org.apache.dubbo.config.event.listener.LoggingEventListener
+# since 2.7.8
+publishing-service-definition=org.apache.dubbo.config.event.listener.PublishingServiceDefinitionListener
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter b/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter
new file mode 100644
index 00000000000..1b843b6bbc7
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter
@@ -0,0 +1,3 @@
+# since 2.7.8
+local = org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter
+remote = org.apache.dubbo.config.metadata.RemoteMetadataServiceExporter
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index c992e48c0d9..775596c3fbe 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -21,6 +21,7 @@
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.api.DemoService;
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
@@ -33,12 +34,12 @@ public class ReferenceConfigTest {
@BeforeEach
public void setUp() {
-// ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@AfterEach
public void tearDown() {
-// ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@Test
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceConsumerBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceConsumerBootstrap.java
new file mode 100644
index 00000000000..824de82dae8
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceConsumerBootstrap.java
@@ -0,0 +1,52 @@
+/*
+ * 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.config.bootstrap;
+
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+
+/**
+ * Dubbo Provider Bootstrap
+ *
+ * @since 2.7.5
+ */
+public class ConsulDubboServiceConsumerBootstrap {
+
+ public static void main(String[] args) throws Exception {
+
+ DubboBootstrap bootstrap = DubboBootstrap.getInstance()
+ .application("consul-dubbo-consumer", app -> app.metadata(DEFAULT_METADATA_STORAGE_TYPE))
+ .registry("zookeeper", builder -> builder.address("consul://127.0.0.1:8500?registry-type=service&subscribed-services=consul-dubbo-provider")
+ .useAsConfigCenter(true)
+ .useAsMetadataCenter(true))
+ .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
+ .reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
+ .start();
+
+ EchoService echoService = bootstrap.getCache().get(EchoService.class);
+ UserService userService = bootstrap.getCache().get(UserService.class);
+
+ for (int i = 0; i < 5; i++) {
+ Thread.sleep(2000L);
+ System.out.println(echoService.echo("Hello,World"));
+ System.out.println(userService.getUser(i * 1L));
+ }
+
+ bootstrap.stop();
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceProviderBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceProviderBootstrap.java
new file mode 100644
index 00000000000..ef3894422e5
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ConsulDubboServiceProviderBootstrap.java
@@ -0,0 +1,42 @@
+/*
+ * 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.config.bootstrap;
+
+import org.apache.dubbo.config.bootstrap.rest.UserService;
+import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+
+/**
+ * TODO
+ */
+public class ConsulDubboServiceProviderBootstrap {
+
+ public static void main(String[] args) {
+ DubboBootstrap.getInstance()
+ .application("consul-dubbo-provider", app -> app.metadata(DEFAULT_METADATA_STORAGE_TYPE))
+ .registry(builder -> builder.address("consul://127.0.0.1:8500?registry-type=service")
+ .useAsConfigCenter(true)
+ .useAsMetadataCenter(true))
+ .protocol("dubbo", builder -> builder.port(-1).name("dubbo"))
+ .protocol("rest", builder -> builder.port(8081).name("rest"))
+ .service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
+ .service("user", builder -> builder.interfaceClass(UserService.class).ref(new UserServiceImpl()).protocolIds("rest"))
+ .start()
+ .await();
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
index b91659d084a..37262e23c2e 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
@@ -17,9 +17,10 @@
package org.apache.dubbo.config.bootstrap;
import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.bootstrap.rest.UserService;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+
/**
* Dubbo Provider Bootstrap
*
@@ -30,21 +31,25 @@ public class NacosDubboServiceConsumerBootstrap {
public static void main(String[] args) throws Exception {
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-nacos-consumer-demo");
-// applicationConfig.setMetadataType("remote");
+ applicationConfig.setMetadataType(REMOTE_METADATA_STORAGE_TYPE);
DubboBootstrap bootstrap = DubboBootstrap.getInstance()
.application(applicationConfig)
- // Zookeeper
-// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service&subscribed.services=dubbo-nacos-provider-demo"))
-// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=dubbo-nacos-provider-demo"))
- .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=dubbo-nacos-provider-demo"))
- .metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848"))
+ // Nacos in service registry type
+ .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service")
+ .useAsConfigCenter(true)
+ .useAsMetadataCenter(true))
+ // Nacos in traditional registry type
+// .registry("nacos-traditional", builder -> builder.address("nacos://127.0.0.1:8848"))
+ .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start();
+ EchoService echoService = bootstrap.getCache().get(EchoService.class);
UserService userService = bootstrap.getCache().get(UserService.class);
- for (int i = 0; i < 500; i++) {
+ for (int i = 0; i < 5; i++) {
Thread.sleep(2000L);
+ System.out.println(echoService.echo("Hello,World"));
System.out.println(userService.getUser(i * 1L));
}
}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceProviderBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceProviderBootstrap.java
index 35ed723e61c..f55790ac806 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceProviderBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceProviderBootstrap.java
@@ -17,10 +17,13 @@
package org.apache.dubbo.config.bootstrap;
import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.bootstrap.rest.UserService;
import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
+
/**
* Dubbo Provider Bootstrap
*
@@ -30,15 +33,16 @@ public class NacosDubboServiceProviderBootstrap {
public static void main(String[] args) {
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-nacos-provider-demo");
-// applicationConfig.setMetadataType("remote");
+ applicationConfig.setMetadataType(REMOTE_METADATA_STORAGE_TYPE);
DubboBootstrap.getInstance()
.application(applicationConfig)
- // Zookeeper in service registry type
- .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service").useAsConfigCenter(true))
- // Nacos
-// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service"))
-// .registry(RegistryBuilder.newBuilder().address("etcd3://127.0.0.1:2379?registry.type=service").build())
- .metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848"))
+ // Nacos in service registry type
+ .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848")
+ .parameter(REGISTRY_TYPE_KEY, SERVICE_REGISTRY_TYPE)
+ .useAsConfigCenter(true)
+ .useAsMetadataCenter(true))
+ // Nacos in traditional registry type
+// .registry("nacos-traditional", builder -> builder.address("nacos://127.0.0.1:8848"))
.protocol("dubbo", builder -> builder.port(20885).name("dubbo"))
.protocol("rest", builder -> builder.port(9090).name("rest"))
.service(builder -> builder.id("echo").interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
index 9b0d866e12c..27f3eb98d46 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
@@ -18,6 +18,10 @@
import org.apache.dubbo.config.bootstrap.rest.UserService;
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
+
/**
* Dubbo Provider Bootstrap
*
@@ -28,9 +32,12 @@ public class ZookeeperDubboServiceConsumerBootstrap {
public static void main(String[] args) throws Exception {
DubboBootstrap bootstrap = DubboBootstrap.getInstance()
- .application("zookeeper-dubbo-consumer")
- .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service&subscribed-services=zookeeper-dubbo-provider"))
- .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
+ .application("zookeeper-dubbo-consumer", app -> app.metadata(COMPOSITE_METADATA_STORAGE_TYPE))
+ .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181")
+ .parameter(REGISTRY_TYPE_KEY, SERVICE_REGISTRY_TYPE)
+ .useAsConfigCenter(true)
+ .useAsMetadataCenter(true))
+ .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo").services("zookeeper-dubbo-provider"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start();
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceProviderBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceProviderBootstrap.java
index c653fe70c3f..e9b946fe47c 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceProviderBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceProviderBootstrap.java
@@ -19,6 +19,10 @@
import org.apache.dubbo.config.bootstrap.rest.UserService;
import org.apache.dubbo.config.bootstrap.rest.UserServiceImpl;
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
+
/**
* TODO
*/
@@ -26,8 +30,11 @@ public class ZookeeperDubboServiceProviderBootstrap {
public static void main(String[] args) {
DubboBootstrap.getInstance()
- .application("zookeeper-dubbo-provider")
- .registry(builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service"))
+ .application("zookeeper-dubbo-provider", app -> app.metadata(COMPOSITE_METADATA_STORAGE_TYPE))
+ .registry(builder -> builder.address("zookeeper://127.0.0.1:2181")
+ .parameter(REGISTRY_TYPE_KEY, SERVICE_REGISTRY_TYPE)
+ .useAsConfigCenter(true)
+ .useAsMetadataCenter(true))
.protocol("dubbo", builder -> builder.port(-1).name("dubbo"))
.protocol("rest", builder -> builder.port(8081).name("rest"))
.service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilderTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilderTest.java
index 210d92e251a..4d11ef43149 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilderTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/ReferenceBuilderTest.java
@@ -26,6 +26,8 @@
import java.util.Collections;
+import static org.apache.dubbo.common.utils.CollectionUtils.ofSet;
+
class ReferenceBuilderTest {
@Test
@@ -95,8 +97,15 @@ void build() {
MethodConfig method = new MethodConfig();
ReferenceBuilder builder = new ReferenceBuilder<>();
- builder.id("id").interfaceClass(DemoService.class).protocol("protocol").client("client").url("url")
- .consumer(consumer).addMethod(method);
+ builder.id("id")
+ .interfaceClass(DemoService.class)
+ .protocol("protocol")
+ .client("client")
+ .url("url")
+ .consumer(consumer)
+ .addMethod(method)
+ // introduced since 2.7.8
+ .services("test-service", "test-service2");
ReferenceConfig config = builder.build();
ReferenceConfig config2 = builder.build();
@@ -107,6 +116,8 @@ void build() {
Assertions.assertEquals("client", config.getClient());
Assertions.assertEquals("url", config.getUrl());
Assertions.assertEquals(consumer, config.getConsumer());
+ Assertions.assertEquals("test-service,test-service2", config.getServices());
+ Assertions.assertEquals(ofSet("test-service", "test-service2"), config.getSubscribedServices());
Assertions.assertTrue(config.getMethods().contains(method));
Assertions.assertEquals(1, config.getMethods().size());
Assertions.assertNotSame(config, config2);
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilderTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilderTest.java
index 24c4a4d02dc..b125547420e 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilderTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/RegistryBuilderTest.java
@@ -220,7 +220,7 @@ void build() {
.transporter("transporter").server("server").client("client").cluster("cluster").group("group")
.version("version").timeout(1000).session(2000).file("file").wait(Integer.valueOf(10)).isCheck(true)
.isDynamic(false).register(true).subscribe(false).isDefault(true).simplified(false).extraKeys("A")
- .appendParameter("default.num", "one").id("id").prefix("prefix");
+ .parameter("default.num", "one").id("id").prefix("prefix");
RegistryConfig config = builder.build();
RegistryConfig config2 = builder.build();
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
new file mode 100644
index 00000000000..67a562d6687
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/event/listener/PublishingServiceDefinitionListenerTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.config.event.listener;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.bootstrap.EchoService;
+import org.apache.dubbo.config.bootstrap.EchoServiceImpl;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
+import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import com.google.gson.Gson;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
+import static org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder.buildFullDefinition;
+import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
+import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link PublishingServiceDefinitionListener} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class PublishingServiceDefinitionListenerTest {
+
+ private WritableMetadataService writableMetadataService;
+
+ @BeforeEach
+ public void init() {
+ String metadataType = DEFAULT_METADATA_STORAGE_TYPE;
+ ConfigManager configManager = ApplicationModel.getConfigManager();
+ ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-provider");
+ applicationConfig.setMetadataType(metadataType);
+ configManager.setApplication(applicationConfig);
+ this.writableMetadataService = WritableMetadataService.getExtension(metadataType);
+ }
+
+ @AfterEach
+ public void reset() {
+ ApplicationModel.reset();
+ }
+
+ /**
+ * Test {@link ServiceConfigExportedEvent} arising
+ */
+ @Test
+ public void testOnServiceConfigExportedEvent() {
+ ServiceConfig serviceConfig = new ServiceConfig<>();
+ serviceConfig.setInterface(EchoService.class);
+ serviceConfig.setRef(new EchoServiceImpl());
+ serviceConfig.setRegistry(new RegistryConfig("N/A"));
+ serviceConfig.export();
+
+ String serviceDefinition = writableMetadataService.getServiceDefinition(EchoService.class.getName());
+
+ List exportedUrls = serviceConfig.getExportedUrls();
+
+ FullServiceDefinition fullServiceDefinition = buildFullDefinition(
+ serviceConfig.getInterfaceClass(),
+ exportedUrls.get(0)
+ .removeParameters(PID_KEY, TIMESTAMP_KEY, BIND_IP_KEY, BIND_PORT_KEY, TIMESTAMP_KEY)
+ .getParameters()
+ );
+
+ assertEquals(serviceDefinition, new Gson().toJson(fullServiceDefinition));
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/metadata/RemoteMetadataServiceExporterTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/metadata/RemoteMetadataServiceExporterTest.java
new file mode 100644
index 00000000000..e4d13a15289
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/metadata/RemoteMetadataServiceExporterTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.config.metadata;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.metadata.MetadataServiceExporter;
+import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.metadata.report.MetadataReportInstance;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.service.EchoService;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static java.util.Arrays.asList;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
+import static org.apache.dubbo.metadata.MetadataServiceExporter.getExtension;
+import static org.apache.dubbo.metadata.report.support.Constants.SYNC_REPORT_KEY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link RemoteMetadataServiceExporter} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class RemoteMetadataServiceExporterTest {
+
+ private static final URL METADATA_REPORT_URL = URL.valueOf("file://")
+ .addParameter(APPLICATION_KEY, "test")
+ .addParameter(SYNC_REPORT_KEY, "true");
+
+ private static final Class INTERFACE_CLASS = EchoService.class;
+
+ private static final String INTERFACE_NAME = INTERFACE_CLASS.getName();
+
+ private static final String APP_NAME = "test-service";
+
+ private static final URL BASE_URL = URL
+ .valueOf("dubbo://127.0.0.1:20880")
+ .setPath(INTERFACE_NAME)
+ .addParameter(APPLICATION_KEY, APP_NAME)
+ .addParameter(SIDE_KEY, "provider");
+
+ private final MetadataServiceExporter exporter = getExtension(REMOTE_METADATA_STORAGE_TYPE);
+
+ private WritableMetadataService writableMetadataService;
+
+ @BeforeEach
+ public void init() {
+ ApplicationModel.getConfigManager().setApplication(new ApplicationConfig(APP_NAME));
+ MetadataReportInstance.init(METADATA_REPORT_URL);
+ writableMetadataService = WritableMetadataService.getDefaultExtension();
+ writableMetadataService.exportURL(BASE_URL);
+ }
+
+ @AfterEach
+ public void reset() {
+ ApplicationModel.reset();
+ }
+
+ @Test
+ public void testType() {
+ assertEquals(RemoteMetadataServiceExporter.class, exporter.getClass());
+ }
+
+ @Test
+ public void testSupports() {
+ assertTrue(exporter.supports(REMOTE_METADATA_STORAGE_TYPE));
+ assertTrue(exporter.supports(COMPOSITE_METADATA_STORAGE_TYPE));
+ assertFalse(exporter.supports(DEFAULT_METADATA_STORAGE_TYPE));
+ }
+
+ @Test
+ public void testExportAndUnexport() {
+ assertFalse(exporter.isExported());
+ assertEquals(exporter, exporter.export());
+ assertTrue(exporter.isExported());
+
+ assertEquals(asList(BASE_URL), exporter.getExportedURLs());
+
+ assertEquals(exporter, exporter.unexport());
+ assertFalse(exporter.isExported());
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
index e1fbfb4fda1..5c19d04151e 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/ExporterSideConfigUrlTest.java
@@ -19,6 +19,7 @@
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
@@ -42,13 +43,13 @@ public static void start() {
@BeforeEach
public void setUp() {
+ ApplicationModel.reset();
initServConf();
-// ApplicationModel.getConfigManager().clear();
}
@AfterEach()
public void teardown() {
-// ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@Test
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/metadata/MetadataServiceExporterTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/metadata/MetadataServiceExporterTest.java
new file mode 100644
index 00000000000..8096276f19a
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/metadata/MetadataServiceExporterTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.metadata;
+
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link MetadataServiceExporter} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class MetadataServiceExporterTest {
+
+ @Test
+ public void test() {
+ MetadataServiceExporter exporter = MetadataServiceExporter.getExtension(null);
+ assertEquals(exporter, MetadataServiceExporter.getDefaultExtension());
+ assertTrue(exporter.supports(DEFAULT_METADATA_STORAGE_TYPE));
+ assertTrue(exporter.supports(REMOTE_METADATA_STORAGE_TYPE));
+ assertTrue(exporter.supports(COMPOSITE_METADATA_STORAGE_TYPE));
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/pom.xml b/dubbo-config/dubbo-config-spring/pom.xml
index 74cc929a4d5..31bfcf4c149 100644
--- a/dubbo-config/dubbo-config-spring/pom.xml
+++ b/dubbo-config/dubbo-config-spring/pom.xml
@@ -142,6 +142,27 @@
test
+
+
+ org.apache.dubbo
+ dubbo-registry-zookeeper
+ ${project.parent.version}
+ test
+
+
+
+ org.apache.dubbo
+ dubbo-metadata-report-zookeeper
+ ${project.parent.version}
+ test
+
+
+ com.google.guava
+ guava
+
+
+
+
org.apache.dubbo
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index 05c81394281..07de2ee6465 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -17,11 +17,11 @@
package org.apache.dubbo.config.spring.beans.factory.annotation;
import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
-import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
import com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor;
import org.springframework.beans.BeansException;
@@ -31,12 +31,9 @@
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.AnnotationAttributes;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
@@ -46,7 +43,6 @@
import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
import static com.alibaba.spring.util.AnnotationUtils.getAttributes;
-import static java.lang.reflect.Proxy.newProxyInstance;
import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create;
import static org.springframework.util.StringUtils.hasText;
@@ -60,7 +56,7 @@
* @since 2.5.7
*/
public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBeanPostProcessor implements
- ApplicationContextAware, ApplicationListener {
+ ApplicationContextAware {
/**
* The bean name of {@link ReferenceAnnotationBeanPostProcessor}
@@ -81,9 +77,6 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
private final ConcurrentMap> injectedMethodReferenceBeanCache =
new ConcurrentHashMap<>(CACHE_SIZE);
- private final ConcurrentMap referencedBeanInvocationHandlersCache =
- new ConcurrentHashMap<>();
-
private ApplicationContext applicationContext;
/**
@@ -142,11 +135,13 @@ protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean,
boolean localServiceBean = isLocalServiceBean(referencedBeanName, referenceBean, attributes);
+ prepareReferenceBean(referencedBeanName, referenceBean, localServiceBean);
+
registerReferenceBean(referencedBeanName, referenceBean, attributes, localServiceBean, injectedType);
cacheInjectedReferenceBean(referenceBean, injectedElement);
- return getOrCreateProxy(referencedBeanName, referenceBean, localServiceBean, injectedType);
+ return referenceBean.get();
}
/**
@@ -261,23 +256,19 @@ private boolean isRemoteReferenceBean(ReferenceBean referenceBean, AnnotationAtt
}
/**
- * Get or Create a proxy of {@link ReferenceBean} for the specified the type of Dubbo service interface
+ * Prepare {@link ReferenceBean}
*
- * @param referencedBeanName The name of bean that annotated Dubbo's {@link Service @Service} in the Spring {@link ApplicationContext}
- * @param referenceBean the instance of {@link ReferenceBean}
- * @param localServiceBean Is Local Service bean or not
- * @param serviceInterfaceType the type of Dubbo service interface
- * @return non-null
- * @since 2.7.4
+ * @param referencedBeanName The name of bean that annotated Dubbo's {@link DubboService @DubboService}
+ * in the Spring {@link ApplicationContext}
+ * @param referenceBean the instance of {@link ReferenceBean}
+ * @param localServiceBean Is Local Service bean or not
+ * @since 2.7.8
*/
- private Object getOrCreateProxy(String referencedBeanName, ReferenceBean referenceBean, boolean localServiceBean,
- Class> serviceInterfaceType) {
- if (localServiceBean) { // If the local @Service Bean exists, build a proxy of Service
- return newProxyInstance(getClassLoader(), new Class[]{serviceInterfaceType},
- newReferencedBeanInvocationHandler(referencedBeanName));
- } else {
+ private void prepareReferenceBean(String referencedBeanName, ReferenceBean referenceBean, boolean localServiceBean) {
+ // Issue : https://github.com/apache/dubbo/issues/6224
+ if (localServiceBean) { // If the local @Service Bean exists
+ referenceBean.setInjvm(Boolean.TRUE);
exportServiceBeanIfNecessary(referencedBeanName); // If the referenced ServiceBean exits, export it immediately
- return referenceBean.get();
}
}
@@ -295,58 +286,6 @@ private ServiceBean getServiceBean(String referencedBeanName) {
return applicationContext.getBean(referencedBeanName, ServiceBean.class);
}
- private InvocationHandler newReferencedBeanInvocationHandler(String referencedBeanName) {
- return referencedBeanInvocationHandlersCache.computeIfAbsent(referencedBeanName,
- ReferencedBeanInvocationHandler::new);
- }
-
- /**
- * The {@link InvocationHandler} class for the referenced Bean
- */
- @Override
- public void onApplicationEvent(ServiceBeanExportedEvent event) {
- initReferencedBeanInvocationHandler(event.getServiceBean());
- }
-
- private void initReferencedBeanInvocationHandler(ServiceBean serviceBean) {
- String serviceBeanName = serviceBean.getBeanName();
- referencedBeanInvocationHandlersCache.computeIfPresent(serviceBeanName, (name, handler) -> {
- handler.init();
- return null;
- });
- }
-
- private class ReferencedBeanInvocationHandler implements InvocationHandler {
-
- private final String referencedBeanName;
-
- private Object bean;
-
- private ReferencedBeanInvocationHandler(String referencedBeanName) {
- this.referencedBeanName = referencedBeanName;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object result = null;
- try {
- if (bean == null) {
- init();
- }
- result = method.invoke(bean, args);
- } catch (InvocationTargetException e) {
- // re-throws the actual Exception.
- throw e.getTargetException();
- }
- return result;
- }
-
- private void init() {
- ServiceBean serviceBean = applicationContext.getBean(referencedBeanName, ServiceBean.class);
- this.bean = serviceBean.getRef();
- }
- }
-
@Override
protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName,
Class> injectedType, InjectionMetadata.InjectedElement injectedElement) {
@@ -402,7 +341,6 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
public void destroy() throws Exception {
super.destroy();
this.referenceBeanCache.clear();
- this.referencedBeanInvocationHandlersCache.clear();
this.injectedFieldReferenceBeanCache.clear();
this.injectedMethodReferenceBeanCache.clear();
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java
index bcc16bfe33d..05d9027edee 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java
@@ -25,7 +25,6 @@
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
-import static org.apache.dubbo.config.spring.util.DubboBeanUtils.registerCommonBeans;
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
import static org.springframework.util.StringUtils.trimArrayElements;
@@ -58,8 +57,13 @@ protected void doParse(Element element, ParserContext parserContext, BeanDefinit
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- // @since 2.7.6 Register the common beans
- registerCommonBeans(parserContext.getRegistry());
+ /**
+ * @since 2.7.6 Register the common beans
+ * @since 2.7.8 comment this code line, and migrated to
+ * @see DubboNamespaceHandler#parse(Element, ParserContext)
+ * @see https://github.com/apache/dubbo/issues/6174
+ */
+ // registerCommonBeans(parserContext.getRegistry());
}
@Override
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
index 31b299ad21b..084479a83cd 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
@@ -29,14 +29,13 @@
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
-import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigAliasPostProcessor;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.TypedStringValue;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -55,7 +54,6 @@
import java.util.Set;
import java.util.regex.Pattern;
-import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.apache.dubbo.common.constants.CommonConstants.HIDE_KEY_PREFIX;
/**
@@ -80,7 +78,7 @@ public DubboBeanDefinitionParser(Class> beanClass, boolean required) {
}
@SuppressWarnings("unchecked")
- private static BeanDefinition parse(Element element, ParserContext parserContext, Class> beanClass, boolean required) {
+ private static RootBeanDefinition parse(Element element, ParserContext parserContext, Class> beanClass, boolean required) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(beanClass);
beanDefinition.setLazyInit(false);
@@ -130,7 +128,7 @@ private static BeanDefinition parse(Element element, ParserContext parserContext
parseProperties(element.getChildNodes(), classDefinition, parserContext);
beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));
}
- } else if (ProviderConfig.class.equals(beanClass)) {
+ } else if (ProviderConfig.class.equals(beanClass)) {
parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition);
} else if (ConsumerConfig.class.equals(beanClass)) {
parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition);
@@ -350,11 +348,18 @@ private static void parseMethods(String id, NodeList nodeList, RootBeanDefinitio
if (methods == null) {
methods = new ManagedList();
}
- BeanDefinition methodBeanDefinition = parse(element,
+ RootBeanDefinition methodBeanDefinition = parse(element,
parserContext, MethodConfig.class, false);
- String name = id + "." + methodName;
+ String beanName = id + "." + methodName;
+
+ // If the PropertyValue named "id" can't be found,
+ // bean name will be taken as the "id" PropertyValue for MethodConfig
+ if (!hasPropertyValue(methodBeanDefinition, "id")) {
+ addPropertyValue(methodBeanDefinition, "id", beanName);
+ }
+
BeanDefinitionHolder methodBeanDefinitionHolder = new BeanDefinitionHolder(
- methodBeanDefinition, name);
+ methodBeanDefinition, beanName);
methods.add(methodBeanDefinitionHolder);
}
}
@@ -363,6 +368,17 @@ private static void parseMethods(String id, NodeList nodeList, RootBeanDefinitio
}
}
+ private static boolean hasPropertyValue(AbstractBeanDefinition beanDefinition, String propertyName) {
+ return beanDefinition.getPropertyValues().contains(propertyName);
+ }
+
+ private static void addPropertyValue(AbstractBeanDefinition beanDefinition, String propertyName, String propertyValue) {
+ if (StringUtils.isBlank(propertyName) || StringUtils.isBlank(propertyValue)) {
+ return;
+ }
+ beanDefinition.getPropertyValues().addPropertyValue(propertyName, propertyValue);
+ }
+
@SuppressWarnings("unchecked")
private static void parseArguments(String id, NodeList nodeList, RootBeanDefinition beanDefinition,
ParserContext parserContext) {
@@ -395,22 +411,9 @@ private static void parseArguments(String id, NodeList nodeList, RootBeanDefinit
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
- // Register DubboConfigAliasPostProcessor
- registerDubboConfigAliasPostProcessor(parserContext.getRegistry());
-
return parse(element, parserContext, beanClass, required);
}
- /**
- * Register {@link DubboConfigAliasPostProcessor}
- *
- * @param registry {@link BeanDefinitionRegistry}
- * @since 2.7.5 [Feature] https://github.com/apache/dubbo/issues/5093
- */
- private void registerDubboConfigAliasPostProcessor(BeanDefinitionRegistry registry) {
- registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME, DubboConfigAliasPostProcessor.class);
- }
-
private static String resolveAttribute(Element element, String attributeName, ParserContext parserContext) {
String attributeValue = element.getAttribute(attributeName);
Environment environment = parserContext.getReaderContext().getEnvironment();
diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
index bfaaf3ff469..b12d81563a3 100644
--- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
+++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
@@ -6,7 +6,8 @@
targetNamespace="http://dubbo.apache.org/schema/dubbo">
-
+
@@ -702,7 +703,8 @@
-
+
+
@@ -945,7 +947,8 @@
-
+
+
@@ -1011,6 +1014,14 @@
+
+
+
+
+
+
+
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
index 679d46d3562..598933d5495 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
@@ -22,11 +22,14 @@
import org.apache.dubbo.config.spring.api.DemoService;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
+import org.junit.After;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -67,6 +70,16 @@
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class ReferenceAnnotationBeanPostProcessorTest {
+ @Before
+ public void setUp() {
+ ApplicationModel.reset();
+ }
+
+ @After
+ public void tearDown() {
+ ApplicationModel.reset();
+ }
+
private static final String AOP_SUFFIX = "(based on AOP)";
@Aspect
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilderTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilderTest.java
index 4395c392354..60837e274e8 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilderTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilderTest.java
@@ -17,15 +17,20 @@
package org.apache.dubbo.config.spring.beans.factory.annotation;
+import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.ReferenceBean;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -33,6 +38,7 @@
import java.util.HashMap;
import java.util.Map;
+import static org.apache.dubbo.common.utils.CollectionUtils.ofSet;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
import static org.springframework.util.ReflectionUtils.findField;
@@ -40,6 +46,7 @@
* {@link ReferenceBeanBuilder} Test
*
* @see ReferenceBeanBuilder
+ * @see DubboReference
* @see Reference
* @since 2.6.4
*/
@@ -47,7 +54,7 @@
@ContextConfiguration(classes = ReferenceBeanBuilderTest.class)
public class ReferenceBeanBuilderTest {
- @Reference(
+ @DubboReference(
interfaceClass = CharSequence.class,
interfaceName = "java.lang.CharSequence",
version = "1.0.0", group = "TEST_GROUP", url = "dubbo://localhost:12345",
@@ -62,17 +69,27 @@ public class ReferenceBeanBuilderTest {
timeout = 3, cache = "cache", filter = {"echo", "generic", "accesslog"},
listener = {"deprecated"}, parameters = {"n1=v1 ", "n2 = v2 ", " n3 = v3 "},
application = "application",
- module = "module", consumer = "consumer", monitor = "monitor", registry = {"registry"}
+ module = "module", consumer = "consumer", monitor = "monitor", registry = {"registry"},
+ // @since 2.7.3
+ id = "reference",
+ // @since 2.7.8
+ services = {"service1", "service2", "service3", "service2", "service1"}
)
private static final Object TEST_FIELD = new Object();
@Autowired
private ApplicationContext context;
+ @Before
+ public void init() {
+ ApplicationModel.reset();
+ }
+
@Test
public void testBuild() throws Exception {
- Reference reference = findAnnotation(findField(getClass(), "TEST_FIELD"), Reference.class);
- ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder.create(reference, context.getClassLoader(), context);
+ DubboReference reference = findAnnotation(findField(getClass(), "TEST_FIELD"), DubboReference.class);
+ AnnotationAttributes attributes = AnnotationUtils.getAnnotationAttributes(reference, false, false);
+ ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder.create(attributes, context);
beanBuilder.interfaceClass(CharSequence.class);
ReferenceBean referenceBean = beanBuilder.build();
Assert.assertEquals(CharSequence.class, referenceBean.getInterfaceClass());
@@ -81,7 +98,7 @@ public void testBuild() throws Exception {
Assert.assertEquals("dubbo://localhost:12345", referenceBean.getUrl());
Assert.assertEquals("client", referenceBean.getClient());
Assert.assertEquals(true, referenceBean.isGeneric());
- Assert.assertNull(referenceBean.isInjvm());
+ Assert.assertTrue(referenceBean.isInjvm());
Assert.assertEquals(false, referenceBean.isCheck());
Assert.assertFalse(referenceBean.isInit());
Assert.assertEquals(true, referenceBean.getLazy());
@@ -108,6 +125,8 @@ public void testBuild() throws Exception {
Assert.assertEquals("cache", referenceBean.getCache());
Assert.assertEquals("echo,generic,accesslog", referenceBean.getFilter());
Assert.assertEquals("deprecated", referenceBean.getListener());
+ Assert.assertEquals("reference", referenceBean.getId());
+ Assert.assertEquals(ofSet("service1", "service2", "service3"), referenceBean.getSubscribedServices());
// parameters
Map parameters = new HashMap();
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
index a509b43f418..171cda3217a 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessorTest.java
@@ -18,8 +18,11 @@
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.api.HelloService;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.junit.After;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,6 +52,16 @@
})
public class ServiceAnnotationBeanPostProcessorTest {
+ @Before
+ public void setUp() {
+ ApplicationModel.reset();
+ }
+
+ @After
+ public void tearDown() {
+ ApplicationModel.reset();
+ }
+
@Autowired
private ConfigurableListableBeanFactory beanFactory;
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java
index 4422e75b5ee..e6c1d77e698 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceClassPostProcessorTest.java
@@ -18,8 +18,11 @@
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.api.HelloService;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.junit.After;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,6 +52,16 @@
})
public class ServiceClassPostProcessorTest {
+ @Before
+ public void setUp() {
+ ApplicationModel.reset();
+ }
+
+ @After
+ public void tearDown() {
+ ApplicationModel.reset();
+ }
+
@Autowired
private ConfigurableListableBeanFactory beanFactory;
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/config/MultipleServicesWithMethodConfigsTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/config/MultipleServicesWithMethodConfigsTest.java
new file mode 100644
index 00000000000..d66c8c3e063
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/config/MultipleServicesWithMethodConfigsTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.config.spring.beans.factory.config;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = MultipleServicesWithMethodConfigsTest.class)
+@ImportResource(locations = "classpath:/META-INF/spring/multiple-services-with-methods.xml")
+public class MultipleServicesWithMethodConfigsTest {
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Test
+ public void test() {
+// Map methodConfigs = applicationContext.getBeansOfType(MethodConfig.class);
+// assertEquals(2, methodConfigs.size());
+ }
+}
+
+
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
index 21163021b09..80a8d40b885 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
@@ -41,12 +41,12 @@ public class DubboComponentScanRegistrarTest {
@BeforeEach
public void setUp() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@AfterEach
public void tearDown() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@Test
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
index 42fadfc6ab6..d9364d04c67 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
@@ -52,13 +52,13 @@ public class EnableDubboTest {
@BeforeEach
public void setUp() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
context = new AnnotationConfigApplicationContext();
}
@AfterEach
public void tearDown() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
context.close();
}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java
index b5b0aa56be3..47e0d30751f 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java
@@ -38,7 +38,10 @@ public class TestConsumerConfiguration {
private static final String remoteURL = "dubbo://127.0.0.1:12345?version=2.5.7";
- @Reference(version = "2.5.7", url = remoteURL, application = "dubbo-demo-application")
+ @Reference(version = "2.5.7",
+ url = remoteURL,
+ application = "dubbo-demo-application",
+ filter = "mymock")
private DemoService demoService;
@Autowired
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinderTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinderTest.java
index aea9fb93374..2123b549e22 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinderTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinderTest.java
@@ -20,7 +20,10 @@
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
@@ -34,6 +37,16 @@
@ContextConfiguration(classes = DefaultDubboConfigBinder.class)
public class DefaultDubboConfigBinderTest {
+ @Before
+ public void setUp() {
+ ApplicationModel.reset();
+ }
+
+ @After
+ public void tearDown() {
+ ApplicationModel.reset();
+ }
+
@Autowired
private DubboConfigBinder dubboConfigBinder;
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/Issue6252Test.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/Issue6252Test.java
new file mode 100644
index 00000000000..8c34e7e5cbe
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/issues/Issue6252Test.java
@@ -0,0 +1,50 @@
+/*
+ * 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.config.spring.issues;
+
+import org.apache.dubbo.config.spring.ReferenceBean;
+import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * The test-case for https://github.com/apache/dubbo/issues/6252
+ *
+ * @since 2.7.8
+ */
+@Configuration
+@EnableDubboConfig
+@PropertySource("classpath:/META-INF/issue-6252-test.properties")
+public class Issue6252Test {
+
+ @Bean
+ public static ReferenceBean referenceBean() {
+ return new ReferenceBean();
+ }
+
+ @Test
+ public void test() throws Exception {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Issue6252Test.class);
+ context.getBean(ReferenceBean.class);
+ context.close();
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringConsumerBootstrap.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringConsumerBootstrap.java
new file mode 100644
index 00000000000..4c567e5caca
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringConsumerBootstrap.java
@@ -0,0 +1,53 @@
+/*
+ * 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.config.spring.samples;
+
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.dubbo.config.spring.api.DemoService;
+import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * Zookeeper Dubbo Spring Provider Bootstrap
+ *
+ * @since 2.7.8
+ */
+@EnableDubboConfig
+@PropertySource("classpath:/META-INF/service-introspection/zookeeper-dubbb-consumer.properties")
+public class ZookeeperDubboSpringConsumerBootstrap {
+
+ @DubboReference(services = "${dubbo.provider.name},${dubbo.provider.name1},${dubbo.provider.name2}")
+ private DemoService demoService;
+
+ public static void main(String[] args) throws Exception {
+ Class> beanType = ZookeeperDubboSpringConsumerBootstrap.class;
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(beanType);
+
+ ZookeeperDubboSpringConsumerBootstrap bootstrap = context.getBean(ZookeeperDubboSpringConsumerBootstrap.class);
+
+ for (int i = 0; i < 100; i++) {
+ System.out.println(bootstrap.demoService.sayName("Hello"));
+ Thread.sleep(1000L);
+ }
+
+ System.in.read();
+
+ context.close();
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringConsumerXmlBootstrap.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringConsumerXmlBootstrap.java
new file mode 100644
index 00000000000..08c14509ce0
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringConsumerXmlBootstrap.java
@@ -0,0 +1,42 @@
+/*
+ * 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.config.spring.samples;
+
+import org.apache.dubbo.config.spring.api.DemoService;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * Zookeeper Dubbo Spring Provider XML Bootstrap
+ *
+ * @since 2.7.8
+ */
+public class ZookeeperDubboSpringConsumerXmlBootstrap {
+
+ public static void main(String[] args) throws Exception {
+ String location = "classpath:/META-INF/service-introspection/zookeeper-dubbo-consumer.xml";
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(location);
+
+ DemoService demoService = context.getBean("demoService", DemoService.class);
+
+ for (int i = 0; i < 100; i++) {
+ System.out.println(demoService.sayName("Hello"));
+ }
+
+ context.close();
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringProviderBootstrap.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringProviderBootstrap.java
new file mode 100644
index 00000000000..ddd40109c3d
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/samples/ZookeeperDubboSpringProviderBootstrap.java
@@ -0,0 +1,60 @@
+/*
+ * 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.config.spring.samples;
+
+import org.apache.dubbo.config.annotation.DubboService;
+import org.apache.dubbo.config.spring.api.Box;
+import org.apache.dubbo.config.spring.api.DemoService;
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.apache.dubbo.rpc.RpcContext;
+
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.PropertySource;
+
+import static java.lang.String.format;
+
+/**
+ * Zookeeper Dubbo Spring Provider Bootstrap
+ *
+ * @since 2.7.8
+ */
+@EnableDubbo
+@PropertySource("classpath:/META-INF/service-introspection/zookeeper-dubbb-provider.properties")
+public class ZookeeperDubboSpringProviderBootstrap {
+
+ public static void main(String[] args) throws Exception {
+ AnnotationConfigApplicationContext context =
+ new AnnotationConfigApplicationContext(ZookeeperDubboSpringProviderBootstrap.class);
+ System.in.read();
+ context.close();
+ }
+}
+
+@DubboService
+class DefaultDemoService implements DemoService {
+
+ @Override
+ public String sayName(String name) {
+ RpcContext rpcContext = RpcContext.getContext();
+ return format("[%s:%s] Say - %s", rpcContext.getLocalHost(), rpcContext.getLocalPort(), name);
+ }
+
+ @Override
+ public Box getBox() {
+ return null;
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
index a7c733c2531..705b890ed48 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java
@@ -49,12 +49,12 @@
public class DubboNamespaceHandlerTest {
@BeforeEach
public void setUp() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@AfterEach
public void tearDown() {
- ApplicationModel.getConfigManager().clear();
+ ApplicationModel.reset();
}
@Configuration
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
index 410e3e9bb50..6deb2abaf5f 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/GenericServiceTest.java
@@ -18,7 +18,10 @@
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -34,6 +37,16 @@
@ImportResource(locations = "classpath:/META-INF/spring/dubbo-generic-consumer.xml")
public class GenericServiceTest {
+ @Before
+ public void setUp() {
+ ApplicationModel.reset();
+ }
+
+ @After
+ public void tearDown() {
+ ApplicationModel.reset();
+ }
+
@Autowired
@Qualifier("demoServiceRef")
private ReferenceBean referenceBean;
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/issue-6252-test.properties b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/issue-6252-test.properties
new file mode 100644
index 00000000000..413806d52f3
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/issue-6252-test.properties
@@ -0,0 +1,11 @@
+dubbo.application.name=demo-zk
+dubbo.application.qos-enable=false
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=-1
+dubbo.scan.basePackages=com.example.demo
+dubbo.consumer.check=false
+dubbo.registries.z214.address=zookeeper://192.168.99.214:2181
+dubbo.registries.z214.timeout=60000
+dubbo.registries.z214.subscribe=false
+dubbo.registries.z205.address=zookeeper://192.168.99.205:2181
+dubbo.registries.z205.timeout=60000
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbb-consumer.properties b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbb-consumer.properties
new file mode 100644
index 00000000000..1795afac935
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbb-consumer.properties
@@ -0,0 +1,14 @@
+# Dubbo Consumer for Zookeeper
+
+dubbo.application.name = zookeeper-dubbo-spring-consumer
+
+dubbo.registry.address = zookeeper://127.0.0.1:2181?registry-type=service
+dubbo.registry.useAsConfigCenter = true
+dubbo.registry.useAsMetadataCenter = true
+
+dubbo.protocol.name = dubbo
+dubbo.protocol.port = -1
+
+dubbo.provider.name = zookeeper-dubbo-spring-provider
+dubbo.provider.name1 = zookeeper-dubbo-spring-provider-1
+dubbo.provider.name2 = zookeeper-dubbo-spring-provider-2
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbb-provider.properties b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbb-provider.properties
new file mode 100644
index 00000000000..1b977a57f99
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbb-provider.properties
@@ -0,0 +1,10 @@
+# Dubbo Provider for Zookeeper
+
+dubbo.application.name = zookeeper-dubbo-spring-provider-1
+
+dubbo.registry.address = zookeeper://127.0.0.1:2181?registry-type=service
+dubbo.registry.useAsConfigCenter = true
+dubbo.registry.useAsMetadataCenter = true
+
+dubbo.protocol.name = dubbo
+dubbo.protocol.port = -1
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbo-consumer.xml b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbo-consumer.xml
new file mode 100644
index 00000000000..92305f5ff49
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/service-introspection/zookeeper-dubbo-consumer.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
new file mode 100644
index 00000000000..848990dfca7
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/test/resources/META-INF/spring/multiple-services-with-methods.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
index e0e9a86dda3..5bf8abed371 100644
--- a/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
@@ -21,11 +21,10 @@
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.config.configcenter.TreePathDynamicConfiguration;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.common.utils.StringUtils;
import com.google.common.base.Charsets;
import com.google.common.net.HostAndPort;
@@ -34,39 +33,36 @@
import com.orbitz.consul.cache.KVCache;
import com.orbitz.consul.model.kv.Value;
+import java.util.Collection;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-import static org.apache.dubbo.common.utils.StringUtils.EMPTY_STRING;
/**
* config center implementation for consul
*/
-public class ConsulDynamicConfiguration implements DynamicConfiguration {
+public class ConsulDynamicConfiguration extends TreePathDynamicConfiguration {
private static final Logger logger = LoggerFactory.getLogger(ConsulDynamicConfiguration.class);
private static final int DEFAULT_PORT = 8500;
private static final int DEFAULT_WATCH_TIMEOUT = 60 * 1000;
private static final String WATCH_TIMEOUT = "consul-watch-timeout";
- private URL url;
- private String rootPath;
private Consul client;
+
private KeyValueClient kvClient;
+
private ConcurrentMap watchers = new ConcurrentHashMap<>();
public ConsulDynamicConfiguration(URL url) {
- this.url = url;
- this.rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + PATH_SEPARATOR + "config";
+ super(url);
String host = url.getHost();
int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
client = Consul.builder().withHostAndPort(HostAndPort.fromParts(host, port)).build();
@@ -74,112 +70,69 @@ public ConsulDynamicConfiguration(URL url) {
}
@Override
- public void addListener(String key, String group, ConfigurationListener listener) {
- logger.info("register listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
- String normalizedKey = convertKey(group, key);
- ConsulListener watcher = watchers.computeIfAbsent(normalizedKey, k -> new ConsulListener(key, group));
- watcher.addListener(listener);
+ public String getInternalProperty(String key) {
+ logger.info("getting config from: " + key);
+ return kvClient.getValueAsString(key, Charsets.UTF_8).orElse(null);
}
@Override
- public void removeListener(String key, String group, ConfigurationListener listener) {
- logger.info("unregister listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
- ConsulListener watcher = watchers.get(convertKey(group, key));
- if (watcher != null) {
- watcher.removeListener(listener);
- }
+ protected boolean doPublishConfig(String pathKey, String content) throws Exception {
+ return kvClient.putValue(pathKey, content);
+ }
+
+ @Override
+ protected String doGetConfig(String pathKey) throws Exception {
+ return getInternalProperty(pathKey);
}
@Override
- public String getConfig(String key, String group, long timeout) throws IllegalStateException {
- return (String) getInternalProperty(convertKey(group, key));
+ protected boolean doRemoveConfig(String pathKey) throws Exception {
+ kvClient.deleteKey(pathKey);
+ return true;
}
@Override
- public SortedSet getConfigKeys(String group) throws UnsupportedOperationException {
- SortedSet configKeys = new TreeSet<>();
- String normalizedKey = convertKey(group, EMPTY_STRING);
- List keys = kvClient.getKeys(normalizedKey);
+ protected Collection doGetConfigKeys(String groupPath) {
+ List keys = kvClient.getKeys(groupPath);
+ List configKeys = new LinkedList<>();
if (CollectionUtils.isNotEmpty(keys)) {
keys.stream()
- .filter(k -> !k.equals(normalizedKey))
+ .filter(k -> !k.equals(groupPath))
.map(k -> k.substring(k.lastIndexOf(PATH_SEPARATOR) + 1))
.forEach(configKeys::add);
}
return configKeys;
-// SortedSet configKeys = new TreeSet<>();
-// String normalizedKey = convertKey(group, key);
-// kvClient.getValueAsString(normalizedKey).ifPresent(v -> {
-// Collections.addAll(configKeys, v.split(","));
-// });
-// return configKeys;
}
- /**
- * @param key the key to represent a configuration
- * @param group the group where the key belongs to
- * @param content the content of configuration
- * @return
- * @throws UnsupportedOperationException
- */
@Override
- public boolean publishConfig(String key, String group, String content) throws UnsupportedOperationException {
-// String normalizedKey = convertKey(group, key);
-// Value value = kvClient.getValue(normalizedKey).orElseThrow(() -> new IllegalArgumentException(normalizedKey + " does not exit."));
-// Optional old = value.getValueAsString();
-// if (old.isPresent()) {
-// content = old.get() + "," + content;
-// }
-//
-// while (!kvClient.putValue(key, content, value.getModifyIndex())) {
-// value = kvClient.getValue(normalizedKey).orElseThrow(() -> new IllegalArgumentException(normalizedKey + " does not exit."));
-// old = value.getValueAsString();
-// if (old.isPresent()) {
-// content = old.get() + "," + content;
-// }
-// try {
-// Thread.sleep(10);
-// } catch (InterruptedException e) {
-// e.printStackTrace();
-// }
-// }
-// return true;
- String normalizedKey = convertKey(group, key);
- return kvClient.putValue(normalizedKey, content);
+ protected void doAddListener(String pathKey, ConfigurationListener listener) {
+ logger.info("register listener " + listener.getClass() + " for config with key: " + pathKey);
+ ConsulListener watcher = watchers.computeIfAbsent(pathKey, k -> new ConsulListener(pathKey));
+ watcher.addListener(listener);
}
@Override
- public Object getInternalProperty(String key) {
- logger.info("getting config from: " + key);
- return kvClient.getValueAsString(key, Charsets.UTF_8).orElse(null);
+ protected void doRemoveListener(String pathKey, ConfigurationListener listener) {
+ logger.info("unregister listener " + listener.getClass() + " for config with key: " + pathKey);
+ ConsulListener watcher = watchers.get(pathKey);
+ if (watcher != null) {
+ watcher.removeListener(listener);
+ }
}
@Override
- public void close() throws Exception {
+ protected void doClose() throws Exception {
client.destroy();
}
- private String buildPath(String group) {
- String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
- return rootPath + PATH_SEPARATOR + actualGroup;
- }
-
- private String convertKey(String group, String key) {
- return buildPath(group) + PATH_SEPARATOR + key;
- }
-
private class ConsulListener implements KVCache.Listener {
private KVCache kvCache;
private Set listeners = new LinkedHashSet<>();
- private String key;
- private String group;
private String normalizedKey;
- public ConsulListener(String key, String group) {
- this.key = key;
- this.group = group;
- this.normalizedKey = convertKey(group, key);
+ public ConsulListener(String normalizedKey) {
+ this.normalizedKey = normalizedKey;
initKVCache();
}
@@ -201,7 +154,7 @@ public void notify(Map newValues) {
// Values are encoded in key/value store, decode it if needed
Optional decodedValue = newValue.get().getValueAsString();
decodedValue.ifPresent(v -> listeners.forEach(l -> {
- ConfigChangedEvent event = new ConfigChangedEvent(key, group, v, ConfigChangeType.MODIFIED);
+ ConfigChangedEvent event = new ConfigChangedEvent(normalizedKey, getGroup(), v, ConfigChangeType.MODIFIED);
l.process(event);
}));
});
diff --git a/dubbo-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java b/dubbo-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java
index d924c834e46..c54d1034143 100644
--- a/dubbo-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java
+++ b/dubbo-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java
@@ -30,7 +30,9 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import java.util.Arrays;
import java.util.Optional;
+import java.util.TreeSet;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -51,10 +53,10 @@ public static void setUp() throws Exception {
consul = ConsulStarterBuilder.consulStarter()
.build()
.start();
- configCenterUrl = URL.valueOf("consul://localhost:" + consul.getHttpPort());
+ configCenterUrl = URL.valueOf("consul://127.0.0.1:" + consul.getHttpPort());
configuration = new ConsulDynamicConfiguration(configCenterUrl);
- client = Consul.builder().withHostAndPort(HostAndPort.fromParts("localhost", consul.getHttpPort())).build();
+ client = Consul.builder().withHostAndPort(HostAndPort.fromParts("127.0.0.1", consul.getHttpPort())).build();
kvClient = client.keyValueClient();
}
@@ -74,6 +76,14 @@ public void testGetConfig() {
Assertions.assertNull(configuration.getConfig("not-exist", "dubbo"));
}
+ @Test
+ public void testPublishConfig() {
+ configuration.publishConfig("value", "metadata", "1");
+ // test equals
+ assertEquals("1", configuration.getConfig("value", "/metadata"));
+ assertEquals("1", kvClient.getValueAsString("/dubbo/config/metadata/value").get());
+ }
+
@Test
public void testAddListener() {
KVCache cache = KVCache.newCache(kvClient, "/dubbo/config/dubbo/foo");
@@ -102,14 +112,12 @@ public void testAddListener() {
System.out.println(kvClient.getValues("/dubbo/config/dubbo/foo"));
}
- @Test
- public void testPublishConfig() {
- configuration.publishConfig("foo", "value1");
- Assertions.assertEquals("value1", configuration.getString("/dubbo/config/dubbo/foo"));
- }
-
@Test
public void testGetConfigKeys() {
-
+ configuration.publishConfig("v1", "metadata", "1");
+ configuration.publishConfig("v2", "metadata", "2");
+ configuration.publishConfig("v3", "metadata", "3");
+ // test equals
+ assertEquals(new TreeSet(Arrays.asList("v1", "v2", "v3")), configuration.getConfigKeys("metadata"));
}
}
diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
index 2227015b610..cca467f7bf2 100644
--- a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
@@ -30,6 +30,7 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
import com.alibaba.nacos.api.exception.NacosException;
@@ -50,31 +51,17 @@
import java.util.concurrent.Executor;
import java.util.stream.Stream;
-import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_RETRY_TIME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG;
import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE;
-import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT;
import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_POLLING_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
+import static org.apache.dubbo.common.utils.StringConstantFieldValuePredicate.of;
import static org.apache.dubbo.common.utils.StringUtils.HYPHEN_CHAR;
import static org.apache.dubbo.common.utils.StringUtils.SLASH_CHAR;
+import static org.apache.dubbo.common.utils.StringUtils.isBlank;
/**
* The nacos implementation of {@link DynamicConfiguration}
@@ -159,24 +146,13 @@ private void setServerAddr(URL url, Properties properties) {
private static void setProperties(URL url, Properties properties) {
putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
- putPropertyIfAbsent(url, properties, IS_USE_CLOUD_NAMESPACE_PARSING);
- putPropertyIfAbsent(url, properties, IS_USE_ENDPOINT_PARSING_RULE);
- putPropertyIfAbsent(url, properties, ENDPOINT);
- putPropertyIfAbsent(url, properties, ENDPOINT_PORT);
- putPropertyIfAbsent(url, properties, NAMESPACE);
- putPropertyIfAbsent(url, properties, ACCESS_KEY);
- putPropertyIfAbsent(url, properties, SECRET_KEY);
- putPropertyIfAbsent(url, properties, RAM_ROLE_NAME);
- putPropertyIfAbsent(url, properties, CONTEXT_PATH);
- putPropertyIfAbsent(url, properties, CLUSTER_NAME);
- putPropertyIfAbsent(url, properties, ENCODE);
- putPropertyIfAbsent(url, properties, CONFIG_LONG_POLL_TIMEOUT);
- putPropertyIfAbsent(url, properties, CONFIG_RETRY_TIME);
- putPropertyIfAbsent(url, properties, MAX_RETRY);
- putPropertyIfAbsent(url, properties, ENABLE_REMOTE_SYNC_CONFIG);
+
+ // Get the parameters from constants
+ Map parameters = url.getParameters(of(PropertyKeyConst.class));
+ // Put all parameters
+ properties.putAll(parameters);
+
putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, "true");
- putPropertyIfAbsent(url, properties, NAMING_CLIENT_BEAT_THREAD_COUNT);
- putPropertyIfAbsent(url, properties, NAMING_POLLING_THREAD_COUNT);
}
private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
@@ -260,13 +236,9 @@ public boolean publishConfig(String key, String group, String content) {
boolean published = false;
String resolvedGroup = resolveGroup(group);
try {
- String value = configService.getConfig(key, resolvedGroup, getDefaultTimeout());
- if (StringUtils.isNotEmpty(value)) {
- content = value + "," + content;
- }
published = configService.publishConfig(key, resolvedGroup, content);
} catch (NacosException e) {
- logger.error(e.getErrMsg());
+ logger.error(e.getErrMsg(), e);
}
return published;
}
@@ -279,7 +251,6 @@ public long getDefaultTimeout() {
/**
* TODO Nacos does not support atomic update of the value mapped to a key.
*
- * @param key
* @param group the specified group
* @return
*/
@@ -307,6 +278,19 @@ public SortedSet getConfigKeys(String group) {
return keys;
}
+ @Override
+ public boolean removeConfig(String key, String group) {
+ boolean removed = false;
+ try {
+ removed = configService.removeConfig(key, group);
+ } catch (NacosException e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return removed;
+ }
+
private Stream toKeysStream(String content) {
JSONObject jsonObject = JSON.parseObject(content);
JSONArray pageItems = jsonObject.getJSONArray("pageItems");
@@ -376,6 +360,6 @@ protected String buildListenerKey(String key, String group) {
}
protected String resolveGroup(String group) {
- return group.replace(SLASH_CHAR, HYPHEN_CHAR);
+ return isBlank(group) ? group : group.replace(SLASH_CHAR, HYPHEN_CHAR);
}
}
diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
index 4bd65a92ff1..a96f8438f16 100644
--- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
@@ -18,36 +18,21 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.config.configcenter.TreePathDynamicConfiguration;
import org.apache.dubbo.common.utils.NamedThreadFactory;
-import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-import static java.util.Collections.emptySortedSet;
-import static java.util.Collections.unmodifiableSortedSet;
-import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
-import static org.apache.dubbo.common.utils.StringUtils.EMPTY_STRING;
-
/**
*
*/
-public class ZookeeperDynamicConfiguration implements DynamicConfiguration {
-
- private static final Logger logger = LoggerFactory.getLogger(ZookeeperDynamicConfiguration.class);
+public class ZookeeperDynamicConfiguration extends TreePathDynamicConfiguration {
private Executor executor;
// The final root path would be: /configRootPath/"config"
@@ -60,8 +45,9 @@ public class ZookeeperDynamicConfiguration implements DynamicConfiguration {
ZookeeperDynamicConfiguration(URL url, ZookeeperTransporter zookeeperTransporter) {
+ super(url);
this.url = url;
- rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + "/config";
+ rootPath = getRootPath(url);
initializedLatch = new CountDownLatch(1);
this.cacheListener = new CacheListener(rootPath, initializedLatch);
@@ -87,52 +73,44 @@ public class ZookeeperDynamicConfiguration implements DynamicConfiguration {
* @return
*/
@Override
- public Object getInternalProperty(String key) {
+ public String getInternalProperty(String key) {
return zkClient.getContent(key);
}
- /**
- * For service governance, multi group is not supported by this implementation. So group is not used at present.
- */
@Override
- public void addListener(String key, String group, ConfigurationListener listener) {
- cacheListener.addListener(getPathKey(group, key), listener);
+ protected void doClose() throws Exception {
+ zkClient.close();
}
@Override
- public void removeListener(String key, String group, ConfigurationListener listener) {
- cacheListener.removeListener(getPathKey(group, key), listener);
+ protected boolean doPublishConfig(String pathKey, String content) throws Exception {
+ zkClient.create(pathKey, content, false);
+ return true;
}
@Override
- public String getConfig(String key, String group, long timeout) throws IllegalStateException {
- return (String) getInternalProperty(getPathKey(group, key));
+ protected String doGetConfig(String pathKey) throws Exception {
+ return zkClient.getContent(pathKey);
}
@Override
- public boolean publishConfig(String key, String group, String content) {
- String path = getPathKey(group, key);
- zkClient.create(path, content, false);
+ protected boolean doRemoveConfig(String pathKey) throws Exception {
+ zkClient.delete(pathKey);
return true;
}
@Override
- public SortedSet getConfigKeys(String group) {
- String path = getPathKey(group, EMPTY_STRING);
- List nodes = zkClient.getChildren(path);
- return isEmpty(nodes) ? emptySortedSet() : unmodifiableSortedSet(new TreeSet<>(nodes));
+ protected Collection doGetConfigKeys(String groupPath) {
+ return zkClient.getChildren(groupPath);
}
- private String buildPath(String group) {
- String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
- return rootPath + PATH_SEPARATOR + actualGroup;
+ @Override
+ protected void doAddListener(String pathKey, ConfigurationListener listener) {
+ cacheListener.addListener(pathKey, listener);
}
- private String getPathKey(String group, String key) {
- if (StringUtils.isEmpty(key)) {
- return buildPath(group);
- }
- return buildPath(group) + PATH_SEPARATOR + key;
+ @Override
+ protected void doRemoveListener(String pathKey, ConfigurationListener listener) {
+ cacheListener.removeListener(pathKey, listener);
}
-
}
diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
index 3c06fbe6e3f..9d4a0c36d3f 100644
--- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
+++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
@@ -58,7 +58,7 @@ public class ZookeeperDynamicConfigurationTest {
public static void setUp() throws Exception {
zkServer = new TestingServer(zkServerPort, true);
- client = CuratorFrameworkFactory.newClient("localhost:" + zkServerPort, 60 * 1000, 60 * 1000,
+ client = CuratorFrameworkFactory.newClient("127.0.0.1:" + zkServerPort, 60 * 1000, 60 * 1000,
new ExponentialBackoffRetry(1000, 3));
client.start();
@@ -73,7 +73,7 @@ public static void setUp() throws Exception {
}
- configUrl = URL.valueOf("zookeeper://localhost:" + zkServerPort);
+ configUrl = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort);
configuration = ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getExtension(configUrl.getProtocol()).getDynamicConfiguration(configUrl);
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/CompositeServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/CompositeServiceNameMapping.java
new file mode 100644
index 00000000000..9ad130b2768
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/CompositeServiceNameMapping.java
@@ -0,0 +1,96 @@
+/*
+ * 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.metadata;
+
+
+import org.apache.dubbo.common.URL;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static java.util.Collections.emptySet;
+import static java.util.Collections.unmodifiableSet;
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+import static org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty;
+
+/**
+ * The composite implementation of {@link ServiceNameMapping}
+ *
+ * @see ParameterizedServiceNameMapping
+ * @see PropertiesFileServiceNameMapping
+ * @see DynamicConfigurationServiceNameMapping
+ * @since 2.7.8
+ */
+public class CompositeServiceNameMapping implements ServiceNameMapping {
+
+ private volatile List serviceNameMappings;
+
+ private List getServiceNameMappings() {
+ if (this.serviceNameMappings == null) {
+ synchronized (this) {
+ if (this.serviceNameMappings == null) {
+ Set serviceNameMappings = loadAllServiceNameMappings();
+
+ removeSelf(serviceNameMappings);
+
+ this.serviceNameMappings = new LinkedList<>(serviceNameMappings);
+ }
+ }
+ }
+ return this.serviceNameMappings;
+ }
+
+ private Set loadAllServiceNameMappings() {
+ return getExtensionLoader(ServiceNameMapping.class).getSupportedExtensionInstances();
+ }
+
+ private void removeSelf(Set serviceNameMappings) {
+ Iterator iterator = serviceNameMappings.iterator();
+ while (iterator.hasNext()) {
+ ServiceNameMapping serviceNameMapping = iterator.next();
+ if (this.getClass().equals(serviceNameMapping.getClass())) {
+ iterator.remove(); // Remove self
+ }
+ }
+ }
+
+ @Override
+ public void map(URL exportedURL) {
+ List serviceNameMappings = getServiceNameMappings();
+ serviceNameMappings.forEach(serviceNameMapping -> serviceNameMapping.map(exportedURL));
+ }
+
+ @Override
+ public Set get(URL subscribedURL) {
+ List serviceNameMappings = getServiceNameMappings();
+ Set serviceNames = null;
+ for (ServiceNameMapping serviceNameMapping : serviceNameMappings) {
+ serviceNames = serviceNameMapping.get(subscribedURL);
+ if (isNotEmpty(serviceNames)) {
+ break;
+ }
+ }
+ return serviceNames == null ? emptySet() : unmodifiableSet(serviceNames);
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java
index d84eba02b65..2a04cb79e2c 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.metadata;
+import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
@@ -27,11 +28,17 @@
import static java.lang.String.valueOf;
import static java.util.Arrays.asList;
+import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.getDynamicConfiguration;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty;
import static org.apache.dubbo.common.utils.StringUtils.SLASH;
import static org.apache.dubbo.rpc.model.ApplicationModel.getName;
/**
* The {@link ServiceNameMapping} implementation based on {@link DynamicConfiguration}
+ *
+ * @since 2.7.5
*/
public class DynamicConfigurationServiceNameMapping implements ServiceNameMapping {
@@ -41,14 +48,24 @@ public class DynamicConfigurationServiceNameMapping implements ServiceNameMappin
private final Logger logger = LoggerFactory.getLogger(getClass());
+ /**
+ * The priority of {@link DynamicConfigurationServiceNameMapping} is
+ * lower than {@link ParameterizedServiceNameMapping}
+ */
+ static final int PRIORITY = PropertiesFileServiceNameMapping.PRIORITY + 1;
+
@Override
- public void map(String serviceInterface, String group, String version, String protocol) {
+ public void map(URL exportedURL) {
+
+ String serviceInterface = exportedURL.getServiceInterface();
if (IGNORED_SERVICE_INTERFACES.contains(serviceInterface)) {
return;
}
- DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
+ String group = exportedURL.getParameter(GROUP_KEY);
+ String version = exportedURL.getParameter(VERSION_KEY);
+ String protocol = exportedURL.getProtocol();
// the Dubbo Service Key as group
// the service(application) name as key
@@ -56,7 +73,7 @@ public void map(String serviceInterface, String group, String version, String pr
String key = getName();
String content = valueOf(System.currentTimeMillis());
execute(() -> {
- dynamicConfiguration.publishConfig(key, buildGroup(serviceInterface, group, version, protocol), content);
+ getDynamicConfiguration().publishConfig(key, buildGroup(serviceInterface, group, version, protocol), content);
if (logger.isInfoEnabled()) {
logger.info(String.format("Dubbo service[%s] mapped to interface name[%s].",
group, serviceInterface, group));
@@ -65,14 +82,19 @@ public void map(String serviceInterface, String group, String version, String pr
}
@Override
- public Set get(String serviceInterface, String group, String version, String protocol) {
+ public Set get(URL subscribedURL) {
- DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
+ String serviceInterface = subscribedURL.getServiceInterface();
+ String group = subscribedURL.getParameter(GROUP_KEY);
+ String version = subscribedURL.getParameter(VERSION_KEY);
+ String protocol = subscribedURL.getProtocol();
Set serviceNames = new LinkedHashSet<>();
execute(() -> {
- Set keys = dynamicConfiguration.getConfigKeys(buildGroup(serviceInterface, group, version, protocol));
- serviceNames.addAll(keys);
+ Set keys = getDynamicConfiguration().getConfigKeys(buildGroup(serviceInterface, group, version, protocol));
+ if (isNotEmpty(keys)) {
+ serviceNames.addAll(keys);
+ }
});
return Collections.unmodifiableSet(serviceNames);
}
@@ -96,4 +118,9 @@ private void execute(Runnable runnable) {
}
}
}
+
+ @Override
+ public int getPriority() {
+ return PRIORITY;
+ }
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java
index e03ddd6969a..d67008904ff 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataConstants.java
@@ -16,11 +16,22 @@
*/
package org.apache.dubbo.metadata;
-public class MetadataConstants {
- public static final String KEY_SEPARATOR = ":";
- public static final String DEFAULT_PATH_TAG = "metadata";
- public static final String KEY_REVISON_PREFIX = "revision";
- public static final String META_DATA_STORE_TAG = ".metaData";
- public static final String SERVICE_META_DATA_STORE_TAG = ".smd";
- public static final String CONSUMER_META_DATA_STORE_TAG = ".cmd";
+public interface MetadataConstants {
+ String KEY_SEPARATOR = ":";
+ String DEFAULT_PATH_TAG = "metadata";
+ String KEY_REVISON_PREFIX = "revision";
+ String META_DATA_STORE_TAG = ".metaData";
+ String SERVICE_META_DATA_STORE_TAG = ".smd";
+ String CONSUMER_META_DATA_STORE_TAG = ".cmd";
+
+ /**
+ * @since 2.7.8
+ */
+ String EXPORTED_URLS_TAG = "exported-urls";
+
+ /**
+ * @since 2.7.8
+ */
+ String SUBSCRIBED_URLS_TAG = "subscribed-urls";
+
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java
index 0780149523b..660ac4246a9 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java
@@ -28,6 +28,7 @@
import static java.util.Collections.unmodifiableSortedSet;
import static java.util.stream.StreamSupport.stream;
+import static org.apache.dubbo.common.URL.buildKey;
/**
* A framework interface of Dubbo Metadata Service defines the contract of Dubbo Services registartion and subscription
@@ -90,7 +91,7 @@ default String version() {
* @see #toSortedStrings(Stream)
* @see URL#toFullString()
*/
- default SortedSet getSubscribedURLs(){
+ default SortedSet getSubscribedURLs() {
throw new UnsupportedOperationException("This operation is not supported for consumer.");
}
@@ -165,7 +166,9 @@ default SortedSet getExportedURLs(String serviceInterface, String group,
*
* @return
*/
- String getServiceDefinition(String interfaceName, String version, String group);
+ default String getServiceDefinition(String interfaceName, String version, String group) {
+ return getServiceDefinition(buildKey(interfaceName, group, version));
+ }
/**
* Interface definition.
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataServiceExporter.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataServiceExporter.java
index 16d1e3bef4f..34d3b54e3f7 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataServiceExporter.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataServiceExporter.java
@@ -17,9 +17,14 @@
package org.apache.dubbo.metadata;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
import java.util.List;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+
/**
* The exporter of {@link MetadataService}
*
@@ -28,7 +33,8 @@
* @see #unexport()
* @since 2.7.5
*/
-public interface MetadataServiceExporter {
+@SPI(DEFAULT_METADATA_STORAGE_TYPE)
+public interface MetadataServiceExporter extends Prioritized {
/**
* Exports the {@link MetadataService} as a Dubbo service
@@ -57,5 +63,38 @@ public interface MetadataServiceExporter {
* @return if {@link #export()} was executed, return true
, or false
*/
boolean isExported();
+
+ /**
+ * Does current implementation support the specified metadata type?
+ *
+ * @param metadataType the specified metadata type
+ * @return If supports, return true
, or false
+ * @since 2.7.8
+ */
+ default boolean supports(String metadataType) {
+ return true;
+ }
+
+ /**
+ * Get the extension of {@link MetadataServiceExporter} by the type.
+ * If not found, return the default implementation
+ *
+ * @param metadataType the metadata type
+ * @return non-null
+ * @since 2.7.8
+ */
+ static MetadataServiceExporter getExtension(String metadataType) {
+ return getExtensionLoader(MetadataServiceExporter.class).getOrDefaultExtension(metadataType);
+ }
+
+ /**
+ * Get the default extension of {@link MetadataServiceExporter}
+ *
+ * @return non-null
+ * @since 2.7.8
+ */
+ static MetadataServiceExporter getDefaultExtension() {
+ return getExtension(DEFAULT_METADATA_STORAGE_TYPE);
+ }
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataServiceType.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataServiceType.java
new file mode 100644
index 00000000000..3af6b38eb1f
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataServiceType.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.metadata;
+
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+
+/**
+ * The type enumerations of {@link MetadataService}
+ *
+ * @see MetadataService
+ * @since 2.7.8
+ */
+public enum MetadataServiceType {
+
+ /**
+ * The default type of {@link MetadataService}
+ */
+ DEFAULT(DEFAULT_METADATA_STORAGE_TYPE),
+
+ /**
+ * The remote type of {@link MetadataService}
+ */
+ REMOTE(REMOTE_METADATA_STORAGE_TYPE),
+
+ /**
+ * The composite type of {@link MetadataService}
+ */
+ COMPOSITE(COMPOSITE_METADATA_STORAGE_TYPE);
+
+ /**
+ * The {@link String} value of type
+ */
+ private final String value;
+
+ MetadataServiceType(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static MetadataServiceType getOrDefault(String value) {
+ MetadataServiceType targetType = null;
+ for (MetadataServiceType type : values()) {
+ if (type.getValue().equals(value)) {
+ targetType = type;
+ break;
+ }
+ }
+ if (targetType == null) {
+ targetType = DEFAULT;
+ }
+ return targetType;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataUtil.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataUtil.java
deleted file mode 100644
index 85ce30e8ccd..00000000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataUtil.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.metadata;
-
-/**
- * FIXME
- * 2019-07-31
- */
-public class MetadataUtil {
-
-// public static String getMetadataKey(URL url, KeyTypeEnum keyType){
-//
-// }
-//
-// private String getIdentifierKey() {
-// return serviceInterface
-// + KEY_SEPARATOR + (version == null ? "" : version)
-// + KEY_SEPARATOR + (group == null ? "" : group)
-// + KEY_SEPARATOR + (side == null ? "" : side)
-// + KEY_SEPARATOR + application;
-// }
-//
-// private String getFilePathKey() {
-// return getFilePathKey(DEFAULT_PATH_TAG);
-// }
-//
-// private String getFilePathKey(String pathTag) {
-// return pathTag
-// + (StringUtils.isEmpty(toServicePath()) ? "" : (PATH_SEPARATOR + toServicePath()))
-// + (version == null ? "" : (PATH_SEPARATOR + version))
-// + (group == null ? "" : (PATH_SEPARATOR + group))
-// + (side == null ? "" : (PATH_SEPARATOR + side))
-// + (getApplication() == null ? "" : (PATH_SEPARATOR + getApplication()));
-// }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ParameterizedServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ParameterizedServiceNameMapping.java
new file mode 100644
index 00000000000..893a6f4137d
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ParameterizedServiceNameMapping.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata;
+
+import org.apache.dubbo.common.URL;
+
+import java.util.Set;
+
+import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
+
+/**
+ * The parameterized implementation of {@link ServiceNameMapping}
+ *
+ * @see ReadOnlyServiceNameMapping
+ * @since 2.7.8
+ */
+public class ParameterizedServiceNameMapping extends ReadOnlyServiceNameMapping {
+
+ /**
+ * The priority of {@link PropertiesFileServiceNameMapping}
+ */
+ static final int PRIORITY = MAX_PRIORITY + 99;
+
+ @Override
+ public Set get(URL subscribedURL) {
+ return getValue(subscribedURL.getParameter(SUBSCRIBED_SERVICE_NAMES_KEY));
+ }
+
+ @Override
+ public int getPriority() {
+ return PRIORITY;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/PropertiesFileServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/PropertiesFileServiceNameMapping.java
new file mode 100644
index 00000000000..7870895975a
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/PropertiesFileServiceNameMapping.java
@@ -0,0 +1,148 @@
+/*
+ * 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.metadata;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.Configuration;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.utils.ClassUtils;
+import org.apache.dubbo.common.utils.PathUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import static java.lang.String.format;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_SERVICE_NAME_MAPPING_PROPERTIES_PATH;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.utils.StringUtils.SLASH;
+import static org.apache.dubbo.metadata.MetadataConstants.KEY_SEPARATOR;
+
+/**
+ * The externalized {@link Properties} file implementation of {@link ServiceNameMapping},
+ * the default properties class path is
+ * {@link CommonConstants#DEFAULT_SERVICE_NAME_MAPPING_PROPERTIES_PATH "/META-INF/dubbo/service-name-mapping.properties"},
+ * whose format as following:
+ *
+ * dubbo\:com.acme.Interface1\:default = Service1
+ * thirft\:com.acme.InterfaceX = Service1,Service2
+ * rest\:com.acme.interfaceN = Service3
+ *
+ *
+ * THe search path could be configured by the externalized property {@link CommonConstants#SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY}
+ *
+ * @see ReadOnlyServiceNameMapping
+ * @see ParameterizedServiceNameMapping
+ * @since 2.7.8
+ */
+public class PropertiesFileServiceNameMapping extends ReadOnlyServiceNameMapping {
+
+ /**
+ * The priority of {@link PropertiesFileServiceNameMapping} is
+ * lower than {@link ParameterizedServiceNameMapping}
+ */
+ static final int PRIORITY = ParameterizedServiceNameMapping.PRIORITY + 1;
+
+
+ private final List propertiesList;
+
+ public PropertiesFileServiceNameMapping() {
+ this.propertiesList = loadPropertiesList();
+ }
+
+ @Override
+ public Set get(URL subscribedURL) {
+ String propertyKey = getPropertyKey(subscribedURL);
+ String propertyValue = null;
+
+ for (Properties properties : propertiesList) {
+ propertyValue = properties.getProperty(propertyKey);
+ if (propertyValue != null) {
+ break;
+ }
+ }
+
+ return getValue(propertyValue);
+ }
+
+ private String getPropertyKey(URL url) {
+ String protocol = url.getProtocol();
+ String serviceInterface = url.getServiceInterface();
+ // Optional
+ String group = url.getParameter(GROUP_KEY);
+ String version = url.getParameter(VERSION_KEY);
+
+ StringBuilder propertyKeyBuilder = new StringBuilder(protocol)
+ .append(KEY_SEPARATOR)
+ .append(serviceInterface);
+
+ appendIfPresent(propertyKeyBuilder, group);
+ appendIfPresent(propertyKeyBuilder, version);
+
+ return propertyKeyBuilder.toString();
+ }
+
+ private void appendIfPresent(StringBuilder builder, String value) {
+ if (!StringUtils.isBlank(value)) {
+ builder.append(KEY_SEPARATOR).append(value);
+ }
+ }
+
+ private List loadPropertiesList() {
+ List propertiesList = new LinkedList<>();
+ String propertiesPath = getPropertiesPath();
+ try {
+ Enumeration resources = ClassUtils.getClassLoader().getResources(propertiesPath);
+ while (resources.hasMoreElements()) {
+ java.net.URL resource = resources.nextElement();
+ InputStream inputStream = resource.openStream();
+ Properties properties = new Properties();
+ properties.load(new InputStreamReader(inputStream, "UTF-8"));
+ propertiesList.add(properties);
+ }
+ } catch (IOException e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(format("The path of ServiceNameMapping's Properties file[path : %s] can't be loaded", propertiesPath), e);
+ }
+ }
+ return propertiesList;
+ }
+
+ private String getPropertiesPath() {
+ Configuration configuration = ApplicationModel.getEnvironment().getConfiguration();
+ String propertyPath = configuration.getString(SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY, DEFAULT_SERVICE_NAME_MAPPING_PROPERTIES_PATH);
+ propertyPath = PathUtils.normalize(propertyPath);
+ if (propertyPath.startsWith(SLASH)) {
+ propertyPath = propertyPath.substring(SLASH.length());
+ }
+ return propertyPath;
+ }
+
+ @Override
+ public int getPriority() {
+ return PRIORITY;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ReadOnlyServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ReadOnlyServiceNameMapping.java
new file mode 100644
index 00000000000..58035d35316
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ReadOnlyServiceNameMapping.java
@@ -0,0 +1,45 @@
+/*
+ * 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.metadata;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import java.util.Set;
+
+import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR_CHAR;
+import static org.apache.dubbo.common.utils.StringUtils.splitToSet;
+
+/**
+ * Read-Only implementation of {@link ServiceNameMapping}
+ *
+ * @since 2.7.8
+ */
+public abstract class ReadOnlyServiceNameMapping implements ServiceNameMapping {
+
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Override
+ public void map(URL exportedURL) {
+ // DO NOTING for mapping
+ }
+
+ protected Set getValue(String rawValue) {
+ return splitToSet(rawValue, COMMA_SEPARATOR_CHAR, true);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
index 74113f2dbdd..46f657d184e 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
@@ -16,7 +16,9 @@
*/
package org.apache.dubbo.metadata;
+import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
import java.util.Set;
@@ -28,7 +30,7 @@
* @since 2.7.5
*/
@SPI("default")
-public interface ServiceNameMapping {
+public interface ServiceNameMapping extends Prioritized {
/**
* Map the specified Dubbo service interface, group, version and protocol to current Dubbo service name
@@ -37,8 +39,20 @@ public interface ServiceNameMapping {
* @param group the group of Dubbo service interface (optional)
* @param version the version of Dubbo service interface version (optional)
* @param protocol the protocol of Dubbo service interface exported (optional)
+ * @deprecated 2.7.8 This method will be removed since 3.0
*/
- void map(String serviceInterface, String group, String version, String protocol);
+ @Deprecated
+ default void map(String serviceInterface, String group, String version, String protocol) {
+ throw new UnsupportedOperationException("This method has been deprecated and should not be invoked!");
+ }
+
+ /**
+ * Map the specified Dubbo service {@link URL} to current Dubbo service name
+ *
+ * @param exportedURL the {@link URL} that the Dubbo Provider exported
+ * @since 2.7.8
+ */
+ void map(URL exportedURL);
/**
* Get the service names from the specified Dubbo service interface, group, version and protocol
@@ -47,10 +61,22 @@ public interface ServiceNameMapping {
* @param group the group of Dubbo service interface (optional)
* @param version the version of Dubbo service interface version (optional)
* @param protocol the protocol of Dubbo service interface exported (optional)
- * @return
+ * @return non-null {@link Set}
+ * @deprecated 2.7.8 This method will be removed since 3.0
*/
- Set get(String serviceInterface, String group, String version, String protocol);
+ @Deprecated
+ default Set get(String serviceInterface, String group, String version, String protocol) {
+ throw new UnsupportedOperationException("This method has been deprecated and should not be invoked!");
+ }
+ /**
+ * Get the service names from the subscribed Dubbo service {@link URL}
+ *
+ * @param subscribedURL the {@link URL} that the Dubbo consumer subscribed
+ * @return non-null {@link Set}
+ * @since 2.7.8
+ */
+ Set get(URL subscribedURL);
/**
* Get the default extension of {@link ServiceNameMapping}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/URLRevisionResolver.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/URLRevisionResolver.java
similarity index 67%
rename from dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/URLRevisionResolver.java
rename to dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/URLRevisionResolver.java
index 66f4dbf5f95..f3fe79c3cc5 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/URLRevisionResolver.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/URLRevisionResolver.java
@@ -14,12 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.registry.client.metadata;
+package org.apache.dubbo.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.compiler.support.ClassUtils;
-import org.apache.dubbo.metadata.MetadataService;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -27,7 +27,9 @@
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+import static java.util.Collections.emptyList;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
@@ -35,29 +37,64 @@
/**
* A class to resolve the version from {@link URL URLs}
*
+ * @revised 2.7.8 repackage and refactor
* @since 2.7.5
*/
public class URLRevisionResolver {
- public static final String NO_REVISION = "N/A";
+ /**
+ * @since 2.7.8
+ */
+ public static final String UNKNOWN_REVISION = "X";
+
+ /**
+ * @since 2.7.8
+ */
+ public static final URLRevisionResolver INSTANCE = new URLRevisionResolver();
+
+ /**
+ * Resolve revision as {@link String} from the specified the {@link URL#toFullString() strings} presenting the {@link URL URLs}.
+ *
+ * @param url one {@link URL}
+ * @param others the others {@link URL}
+ * @return non-null
+ * @since 2.7.8
+ */
+ public String resolve(String url, String... others) {
+ List urls = new ArrayList<>(others.length + 1);
+ urls.add(url);
+ urls.addAll(Arrays.asList(others));
+ return resolve(urls);
+ }
/**
* Resolve revision as {@link String}
*
* @param urls {@link URL#toFullString() strings} presenting the {@link URL URLs}
* @return non-null
+ * @revised 2.7.8 refactor the parameter as the super interface (from Collection to Iterable)
*/
- public String resolve(Collection urls) {
+ public String resolve(Iterable urls) {
+ List urlsList = toURLsList(urls);
+ return resolve(urlsList);
+ }
+
+ /**
+ * Resolve revision as {@link String} from the specified the {@link URL URLs}.
+ *
+ * @param urls the {@link URL URLs}
+ * @return non-null
+ * @since 2.7.8
+ */
+ public String resolve(Collection urls) {
if (isEmpty(urls)) {
- return NO_REVISION;
+ return UNKNOWN_REVISION;
}
- List urlsList = toURLsList(urls);
-
- SortedSet methodSignatures = resolveMethodSignatures(urlsList);
+ SortedSet methodSignatures = resolveMethodSignatures(urls);
- SortedSet urlParameters = resolveURLParameters(urlsList);
+ SortedSet urlParameters = resolveURLParameters(urls);
SortedSet values = new TreeSet<>(methodSignatures);
@@ -66,18 +103,22 @@ public String resolve(Collection urls) {
return values.stream()
.map(this::hashCode) // generate Long hashCode
.reduce(Long::sum) // sum hashCode
- .map(String::valueOf) // Long to String
- .orElse(NO_REVISION); // NO_REVISION as default
+ .map(Long::toHexString) // Using Hex for the shorten content
+ .orElse(UNKNOWN_REVISION); // NO_REVISION as default
}
- private List toURLsList(Collection urls) {
- return urls.stream()
+ private List toURLsList(Iterable urls) {
+ if (urls == null) {
+ return emptyList();
+ }
+ return StreamSupport.
+ stream(urls.spliterator(), false)
.map(URL::valueOf) // String to URL
.filter(url -> isNotMetadataService(url.getServiceInterface())) // filter not MetadataService interface
.collect(Collectors.toList());
}
- private SortedSet resolveMethodSignatures(List urls) {
+ private SortedSet resolveMethodSignatures(Collection urls) {
return urls.stream()
.map(URL::getServiceInterface) // get the service interface
.map(ClassUtils::forName) // load business interface class
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
index 3a17395972b..6cde356ee04 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java
@@ -20,10 +20,10 @@
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.metadata.store.InMemoryWritableMetadataService;
-import org.apache.dubbo.rpc.model.ApplicationModel;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+import static org.apache.dubbo.rpc.model.ApplicationModel.getName;
/**
* Local {@link MetadataService} that extends {@link MetadataService} and provides the modification, which is used for
@@ -40,7 +40,7 @@ public interface WritableMetadataService extends MetadataService {
*/
@Override
default String serviceName() {
- return ApplicationModel.getApplication();
+ return getName();
}
/**
@@ -63,7 +63,9 @@ default String serviceName() {
* fresh Exports
*
* @return If success , return true
+ * @deprecated Recommend to use {@link MetadataServiceExporter} since 2.7.8
*/
+ @Deprecated
default boolean refreshMetadata(String exportedRevision, String subscribedRevision) {
return true;
}
@@ -84,7 +86,7 @@ default boolean refreshMetadata(String exportedRevision, String subscribedRevisi
*/
boolean unsubscribeURL(URL url);
- void publishServiceDefinition(URL providerUrl);
+ void publishServiceDefinition(URL url);
/**
* Get {@link ExtensionLoader#getDefaultExtension() the defautl extension} of {@link WritableMetadataService}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java
index e5fc587c37d..068d3a040ed 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java
@@ -17,34 +17,144 @@
package org.apache.dubbo.metadata.report;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.metadata.URLRevisionResolver;
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import com.google.gson.Gson;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptySortedSet;
+import static org.apache.dubbo.rpc.model.ApplicationModel.getName;
+
/**
+ * The interface to report the metadata
*
+ * @see AutoCloseable since 2.7.8
*/
-public interface MetadataReport {
+public interface MetadataReport extends AutoCloseable {
void storeProviderMetadata(MetadataIdentifier providerMetadataIdentifier, ServiceDefinition serviceDefinition);
void storeConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, Map serviceParameterMap);
- void saveServiceMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url);
+ /**
+ * @deprecated 2.7.8
+ */
+ @Deprecated
+ default void saveServiceMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) {
+ }
- void removeServiceMetadata(ServiceMetadataIdentifier metadataIdentifier);
+ /**
+ * @deprecated 2.7.8
+ */
+ @Deprecated
+ default void removeServiceMetadata(ServiceMetadataIdentifier metadataIdentifier) {
- List getExportedURLs(ServiceMetadataIdentifier metadataIdentifier);
+ }
- void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, Set urls);
+ /**
+ * @deprecated 2.7.8
+ */
+ @Deprecated
+ default List getExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
+ return emptyList();
+ }
- List getSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier);
+ void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, Collection urls);
+
+ Collection getSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier);
String getServiceDefinition(MetadataIdentifier metadataIdentifier);
-}
+
+ /**
+ * Save the exported {@link URL#toFullString() strings} presenting the {@link URL URLs} in bulk.
+ *
+ * @param exportedURLs the exported {@link URL urls}
+ * @return If successful, return true
, or false
+ * @since 2.7.8
+ */
+ default boolean saveExportedURLs(SortedSet exportedURLs) {
+ return saveExportedURLs(getName(), exportedURLs);
+ }
+
+ /**
+ * Save the exported {@link URL#toFullString() strings} presenting the {@link URL URLs} in bulk.
+ *
+ * @param serviceName the specified Dubbo service name
+ * @param exportedURLs the exported {@link URL urls}
+ * @return If successful, return true
, or false
+ * @since 2.7.8
+ */
+ default boolean saveExportedURLs(String serviceName, SortedSet exportedURLs) {
+ return saveExportedURLs(serviceName, new URLRevisionResolver().resolve(exportedURLs), exportedURLs);
+ }
+
+ /**
+ * Save the exported {@link URL#toFullString() strings} presenting the {@link URL URLs} in bulk.
+ *
+ * @param serviceName the specified Dubbo service name
+ * @param exportedServicesRevision the revision of the exported Services
+ * @param exportedURLs the exported {@link URL urls}
+ * @return If successful, return true
, or false
+ * @since 2.7.8
+ */
+ default boolean saveExportedURLs(String serviceName, String exportedServicesRevision, SortedSet exportedURLs) {
+ Gson gson = new Gson();
+ String content = gson.toJson(exportedURLs);
+ return saveExportedURLs(serviceName, exportedServicesRevision, content);
+ }
+
+ /**
+ * Save the exported {@link URL#toFullString() strings} presenting the {@link URL URLs} in bulk.
+ *
+ * @param serviceName the specified Dubbo service name
+ * @param exportedServicesRevision the revision of the exported Services
+ * @param exportedURLsContent the content of the exported {@link URL urls}
+ * @return If successful, return true
, or false
+ * @since 2.7.8
+ */
+ default boolean saveExportedURLs(String serviceName, String exportedServicesRevision, String exportedURLsContent) {
+ return true;
+ }
+
+ /**
+ * Get the {@link URL#toFullString() strings} presenting the {@link URL URLs} that were exported by the provider
+ *
+ * @param serviceName the specified Dubbo service name
+ * @param exportedServicesRevision the revision of the exported Services
+ * @return non-null
+ * @since 2.7.8
+ */
+ default SortedSet getExportedURLs(String serviceName, String exportedServicesRevision) {
+ String exportedURLsContent = getExportedURLsContent(serviceName, exportedServicesRevision);
+ if (StringUtils.isBlank(exportedURLsContent)) {
+ return emptySortedSet();
+ }
+ Gson gson = new Gson();
+ return gson.fromJson(exportedURLsContent, TreeSet.class);
+ }
+
+ /**
+ * Get the {@link URL#toFullString() strings} presenting the {@link URL URLs} that were exported by the provider
+ *
+ * @param serviceName the specified Dubbo service name
+ * @param exportedServicesRevision the revision of the exported Services
+ * @return the content of the exported {@link URL urls} if found, or null
+ * @since 2.7.8
+ */
+ default String getExportedURLsContent(String serviceName, String exportedServicesRevision) {
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/BaseApplicationMetadataIdentifier.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/BaseApplicationMetadataIdentifier.java
index 9e6b76b3c2b..f70678b30d0 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/BaseApplicationMetadataIdentifier.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/BaseApplicationMetadataIdentifier.java
@@ -17,6 +17,7 @@
package org.apache.dubbo.metadata.report.identifier;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
+import static org.apache.dubbo.common.utils.PathUtils.buildPath;
import static org.apache.dubbo.metadata.MetadataConstants.DEFAULT_PATH_TAG;
import static org.apache.dubbo.metadata.MetadataConstants.KEY_SEPARATOR;
@@ -36,9 +37,7 @@ String getUniqueKey(KeyTypeEnum keyType, String... params) {
}
String getIdentifierKey(String... params) {
-
- return application
- + joinParams(KEY_SEPARATOR, params);
+ return application + joinParams(KEY_SEPARATOR, params);
}
private String joinParams(String joinChar, String... params) {
@@ -58,9 +57,7 @@ private String getFilePathKey(String... params) {
}
private String getFilePathKey(String pathTag, String... params) {
- return pathTag
- + application
- + joinParams(PATH_SEPARATOR, params);
+ return buildPath(pathTag, application, joinParams(PATH_SEPARATOR, params));
}
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/KeyTypeEnum.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/KeyTypeEnum.java
index 2c0da572242..3253f85a73e 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/KeyTypeEnum.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/KeyTypeEnum.java
@@ -16,9 +16,47 @@
*/
package org.apache.dubbo.metadata.report.identifier;
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
+import static org.apache.dubbo.common.utils.PathUtils.buildPath;
+import static org.apache.dubbo.common.utils.StringUtils.EMPTY_STRING;
+import static org.apache.dubbo.common.utils.StringUtils.isBlank;
+import static org.apache.dubbo.metadata.MetadataConstants.KEY_SEPARATOR;
+
/**
* 2019-08-15
*/
public enum KeyTypeEnum {
- PATH, UNIQUE_KEY
+
+ PATH(PATH_SEPARATOR) {
+ public String build(String one, String... others) {
+ return buildPath(one, others);
+ }
+ },
+
+ UNIQUE_KEY(KEY_SEPARATOR) {
+ public String build(String one, String... others) {
+ StringBuilder keyBuilder = new StringBuilder(one);
+ for (String other : others) {
+ keyBuilder.append(separator).append(isBlank(other) ? EMPTY_STRING : other);
+ }
+ return keyBuilder.toString();
+ }
+ };
+
+ final String separator;
+
+ KeyTypeEnum(String separator) {
+ this.separator = separator;
+ }
+
+ /**
+ * Build Key
+ *
+ * @param one one
+ * @param others the others
+ * @return
+ * @since 2.7.8
+ */
+ public abstract String build(String one, String... others);
+
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
index 1d394017447..f3b90db5e36 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
@@ -44,6 +44,7 @@
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -52,7 +53,6 @@
import java.util.SortedSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadLocalRandom;
@@ -61,11 +61,15 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import static java.util.concurrent.Executors.newScheduledThreadPool;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.FILE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
+import static org.apache.dubbo.common.utils.StringUtils.replace;
import static org.apache.dubbo.metadata.report.support.Constants.CYCLE_REPORT_KEY;
import static org.apache.dubbo.metadata.report.support.Constants.DEFAULT_METADATA_REPORT_CYCLE_REPORT;
import static org.apache.dubbo.metadata.report.support.Constants.DEFAULT_METADATA_REPORT_RETRY_PERIOD;
@@ -86,24 +90,52 @@ public abstract class AbstractMetadataReport implements MetadataReport {
// Log output
protected final Logger logger = LoggerFactory.getLogger(getClass());
- // Local disk cache, where the special key value.registries records the list of metadata centers, and the others are the list of notified service providers
- final Properties properties = new Properties();
- private final ExecutorService reportCacheExecutor = Executors.newFixedThreadPool(1, new NamedThreadFactory("DubboSaveMetadataReport", true));
+ private final AtomicBoolean initialized = new AtomicBoolean(false);
+
final Map allMetadataReports = new ConcurrentHashMap<>(4);
- private final AtomicLong lastCacheChanged = new AtomicLong();
final Map failedReports = new ConcurrentHashMap<>(4);
+
private URL reportURL;
boolean syncReport;
+
// Local disk cache file
- File file;
- private AtomicBoolean initialized = new AtomicBoolean(false);
- public MetadataReportRetry metadataReportRetry;
+ File localCacheFile;
+ // Local disk cache, where the special key value.registries records the list of metadata centers, and the others are the list of notified service providers
+ final Properties properties = new Properties();
+
+ private final AtomicLong lastCacheChanged = new AtomicLong();
+
+ // ThreadPoolExecutors
+ private final ExecutorService reportCacheExecutor;
+
+ public final MetadataReportRetry metadataReportRetry;
+
+ private final ScheduledExecutorService cycleReportExecutor;
public AbstractMetadataReport(URL reportServerURL) {
setUrl(reportServerURL);
+
+ this.localCacheFile = initializeLocalCacheFile(reportServerURL);
+ loadProperties();
+ syncReport = reportServerURL.getParameter(SYNC_REPORT_KEY, false);
+ metadataReportRetry = new MetadataReportRetry(reportServerURL.getParameter(RETRY_TIMES_KEY, DEFAULT_METADATA_REPORT_RETRY_TIMES),
+ reportServerURL.getParameter(RETRY_PERIOD_KEY, DEFAULT_METADATA_REPORT_RETRY_PERIOD));
+ this.reportCacheExecutor = newSingleThreadExecutor(new NamedThreadFactory("DubboSaveMetadataReport", true));
+ this.cycleReportExecutor = newSingleThreadScheduledExecutor(new NamedThreadFactory("DubboMetadataReportTimer", true));
+ // cycle report the data switch
+ if (reportServerURL.getParameter(CYCLE_REPORT_KEY, DEFAULT_METADATA_REPORT_CYCLE_REPORT)) {
+ cycleReportExecutor.scheduleAtFixedRate(this::publishAll, calculateStartTime(), ONE_DAY_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ private File initializeLocalCacheFile(URL reportServerURL) {
// Start file save timer
- String defaultFilename = System.getProperty("user.home") + "/.dubbo/dubbo-metadata-" + reportServerURL.getParameter(APPLICATION_KEY) + "-" + reportServerURL.getAddress().replaceAll(":", "-") + ".cache";
+ String defaultFilename = System.getProperty("user.home") +
+ "/.dubbo/dubbo-metadata-" +
+ reportServerURL.getParameter(APPLICATION_KEY) + "-" +
+ replace(reportServerURL.getAddress(), ":", "-") +
+ ".cache";
String filename = reportServerURL.getParameter(FILE_KEY, defaultFilename);
File file = null;
if (ConfigUtils.isNotEmpty(filename)) {
@@ -118,16 +150,7 @@ public AbstractMetadataReport(URL reportServerURL) {
file.delete();
}
}
- this.file = file;
- loadProperties();
- syncReport = reportServerURL.getParameter(SYNC_REPORT_KEY, false);
- metadataReportRetry = new MetadataReportRetry(reportServerURL.getParameter(RETRY_TIMES_KEY, DEFAULT_METADATA_REPORT_RETRY_TIMES),
- reportServerURL.getParameter(RETRY_PERIOD_KEY, DEFAULT_METADATA_REPORT_RETRY_PERIOD));
- // cycle report the data switch
- if (reportServerURL.getParameter(CYCLE_REPORT_KEY, DEFAULT_METADATA_REPORT_CYCLE_REPORT)) {
- ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("DubboMetadataReportTimer", true));
- scheduler.scheduleAtFixedRate(this::publishAll, calculateStartTime(), ONE_DAY_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
- }
+ return file;
}
public URL getUrl() {
@@ -145,12 +168,12 @@ private void doSaveProperties(long version) {
if (version < lastCacheChanged.get()) {
return;
}
- if (file == null) {
+ if (localCacheFile == null) {
return;
}
// Save
try {
- File lockfile = new File(file.getAbsolutePath() + ".lock");
+ File lockfile = new File(localCacheFile.getAbsolutePath() + ".lock");
if (!lockfile.exists()) {
lockfile.createNewFile();
}
@@ -158,14 +181,14 @@ private void doSaveProperties(long version) {
FileChannel channel = raf.getChannel()) {
FileLock lock = channel.tryLock();
if (lock == null) {
- throw new IOException("Can not lock the metadataReport cache file " + file.getAbsolutePath() + ", ignore and retry later, maybe multi java process use the file, please config: dubbo.metadata.file=xxx.properties");
+ throw new IOException("Can not lock the metadataReport cache file " + localCacheFile.getAbsolutePath() + ", ignore and retry later, maybe multi java process use the file, please config: dubbo.metadata.file=xxx.properties");
}
// Save
try {
- if (!file.exists()) {
- file.createNewFile();
+ if (!localCacheFile.exists()) {
+ localCacheFile.createNewFile();
}
- try (FileOutputStream outputFile = new FileOutputStream(file)) {
+ try (FileOutputStream outputFile = new FileOutputStream(localCacheFile)) {
properties.store(outputFile, "Dubbo metadataReport Cache");
}
} finally {
@@ -183,20 +206,20 @@ private void doSaveProperties(long version) {
}
void loadProperties() {
- if (file != null && file.exists()) {
- try (InputStream in = new FileInputStream(file)) {
+ if (localCacheFile != null && localCacheFile.exists()) {
+ try (InputStream in = new FileInputStream(localCacheFile)) {
properties.load(in);
if (logger.isInfoEnabled()) {
- logger.info("Load service store file " + file + ", data: " + properties);
+ logger.info("Load service store file " + localCacheFile + ", data: " + properties);
}
} catch (Throwable e) {
- logger.warn("Failed to load service store file " + file, e);
+ logger.warn("Failed to load service store file " + localCacheFile, e);
}
}
}
private void saveProperties(MetadataIdentifier metadataIdentifier, String value, boolean add, boolean sync) {
- if (file == null) {
+ if (localCacheFile == null) {
return;
}
@@ -318,7 +341,7 @@ public List getExportedURLs(ServiceMetadataIdentifier metadataIdentifier
}
@Override
- public void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, Set urls) {
+ public void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, Collection urls) {
if (syncReport) {
doSaveSubscriberData(subscriberMetadataIdentifier, new Gson().toJson(urls));
} else {
@@ -328,7 +351,7 @@ public void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataId
@Override
- public List getSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
+ public Set getSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
String content = doGetSubscribedURLs(subscriberMetadataIdentifier);
Type setType = new TypeToken>() {
}.getType();
@@ -392,7 +415,7 @@ long calculateStartTime() {
class MetadataReportRetry {
protected final Logger logger = LoggerFactory.getLogger(getClass());
- final ScheduledExecutorService retryExecutor = Executors.newScheduledThreadPool(0, new NamedThreadFactory("DubboMetadataReportRetryTimer", true));
+ final ScheduledExecutorService retryExecutor = newScheduledThreadPool(0, new NamedThreadFactory("DubboMetadataReportRetryTimer", true));
volatile ScheduledFuture retryScheduledFuture;
final AtomicInteger retryCounter = new AtomicInteger(0);
// retry task schedule period
@@ -435,8 +458,10 @@ public void run() {
}
void cancelRetryTask() {
- retryScheduledFuture.cancel(false);
- retryExecutor.shutdown();
+ if (retryScheduledFuture != null) {
+ retryScheduledFuture.cancel(false);
+ }
+ shutdown(retryExecutor);
}
}
@@ -451,6 +476,13 @@ private void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadat
doSaveSubscriberData(subscriberMetadataIdentifier, encodedUrlList);
}
+ @Override
+ public final void close() throws Exception {
+ this.shutdownThreadPoolExecutors();
+ this.clearCache();
+ doClose();
+ }
+
protected abstract void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions);
protected abstract void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String serviceParameterString);
@@ -465,4 +497,35 @@ private void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadat
protected abstract String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier);
+ /**
+ * Close other resources
+ *
+ * @since 2.7.8
+ */
+ protected void doClose() throws Exception {
+
+ }
+
+ private void clearCache() {
+ this.properties.clear();
+ this.allMetadataReports.clear();
+ this.failedReports.clear();
+ this.localCacheFile.delete();
+ }
+
+ private void shutdownThreadPoolExecutors() {
+ this.metadataReportRetry.cancelRetryTask();
+ shutdown(this.reportCacheExecutor);
+ shutdown(cycleReportExecutor);
+ }
+
+ private static void shutdown(ExecutorService executorService) {
+ if (executorService == null) {
+ return;
+ }
+ if (!executorService.isShutdown()) {
+ executorService.shutdown();
+ }
+ }
+
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReport.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReport.java
new file mode 100644
index 00000000000..d962ca51872
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReport.java
@@ -0,0 +1,162 @@
+/*
+ * 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.metadata.report.support;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+
+import java.util.List;
+
+import static org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory.getDynamicConfigurationFactory;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.metadata.MetadataConstants.EXPORTED_URLS_TAG;
+
+/**
+ * The generic implementation of {@link MetadataReport} based on {@link DynamicConfiguration
+ * the config-center infrastructure}
+ *
+ * @see AbstractMetadataReport
+ * @since 2.7.8
+ */
+public class ConfigCenterBasedMetadataReport extends AbstractMetadataReport {
+
+ private final KeyTypeEnum keyType;
+
+ private final String group;
+
+ private final DynamicConfiguration dynamicConfiguration;
+
+ public ConfigCenterBasedMetadataReport(URL reportServerURL, KeyTypeEnum keyTypeEnum) {
+ super(reportServerURL);
+ this.keyType = keyTypeEnum;
+ this.group = reportServerURL.getParameter(GROUP_KEY, DEFAULT_ROOT);
+ String extensionName = reportServerURL.getProtocol();
+ DynamicConfigurationFactory dynamicConfigurationFactory = getDynamicConfigurationFactory(extensionName);
+ dynamicConfiguration = dynamicConfigurationFactory.getDynamicConfiguration(reportServerURL);
+ }
+
+
+ @Override
+ protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
+ saveMetadata(providerMetadataIdentifier, serviceDefinitions);
+ }
+
+ @Override
+ protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String serviceParameterString) {
+ saveMetadata(consumerMetadataIdentifier, serviceParameterString);
+ }
+
+ @Override
+ protected void doSaveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) {
+ saveMetadata(metadataIdentifier, URL.encode(url.toFullString()));
+ }
+
+ @Override
+ protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier) {
+ removeMetadata(metadataIdentifier);
+ }
+
+ @Override
+ protected List doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
+ throw new UnsupportedOperationException("doGetExportedURLs method will not be supported!");
+ }
+
+ @Override
+ protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
+ saveMetadata(subscriberMetadataIdentifier, urlListStr);
+ }
+
+ @Override
+ protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
+ return getMetadata(subscriberMetadataIdentifier);
+ }
+
+ @Override
+ public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
+ return getMetadata(metadataIdentifier);
+ }
+
+ @Override
+ public boolean saveExportedURLs(String serviceName, String exportedServicesRevision, String exportedURLsContent) {
+ String key = buildExportedURLsMetadataKey(serviceName, exportedServicesRevision);
+ return dynamicConfiguration.publishConfig(key, group, exportedURLsContent);
+ }
+
+ @Override
+ public String getExportedURLsContent(String serviceName, String exportedServicesRevision) {
+ String key = buildExportedURLsMetadataKey(serviceName, exportedServicesRevision);
+ return dynamicConfiguration.getConfig(key, group);
+ }
+
+ private String buildExportedURLsMetadataKey(String serviceName, String exportedServicesRevision) {
+ return keyType.build(EXPORTED_URLS_TAG, serviceName, exportedServicesRevision);
+ }
+
+ protected void saveMetadata(BaseMetadataIdentifier metadataIdentifier, String value) {
+ String key = getKey(metadataIdentifier);
+ dynamicConfiguration.publishConfig(key, group, value);
+ }
+
+ protected void saveMetadata(MetadataIdentifier metadataIdentifier, String value) {
+ String key = getKey(metadataIdentifier);
+ dynamicConfiguration.publishConfig(key, group, value);
+ }
+
+ protected String getMetadata(ServiceMetadataIdentifier metadataIdentifier) {
+ String key = getKey(metadataIdentifier);
+ return dynamicConfiguration.getConfig(key, group);
+ }
+
+ protected String getMetadata(MetadataIdentifier metadataIdentifier) {
+ String key = getKey(metadataIdentifier);
+ return dynamicConfiguration.getConfig(key, group);
+ }
+
+ protected String getMetadata(SubscriberMetadataIdentifier metadataIdentifier) {
+ String key = getKey(metadataIdentifier);
+ return dynamicConfiguration.getConfig(key, group);
+ }
+
+ protected void removeMetadata(MetadataIdentifier metadataIdentifier) {
+ String key = getKey(metadataIdentifier);
+ dynamicConfiguration.removeConfig(key, group);
+ }
+
+ protected void removeMetadata(ServiceMetadataIdentifier metadataIdentifier) {
+ String key = getKey(metadataIdentifier);
+ dynamicConfiguration.removeConfig(key, group);
+ }
+
+ protected String getKey(BaseMetadataIdentifier metadataIdentifier) {
+ return metadataIdentifier.getUniqueKey(keyType);
+ }
+
+ protected String getKey(MetadataIdentifier metadataIdentifier) {
+ return metadataIdentifier.getUniqueKey(keyType);
+ }
+
+ protected void doClose() throws Exception {
+ this.dynamicConfiguration.close();
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReportFactory.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReportFactory.java
new file mode 100644
index 00000000000..5b0f780ff4e
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReportFactory.java
@@ -0,0 +1,86 @@
+/*
+ * 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.metadata.report.support;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.MetadataReportFactory;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.apache.dubbo.common.config.configcenter.TreePathDynamicConfiguration.CONFIG_BASE_PATH_PARAM_NAME;
+import static org.apache.dubbo.metadata.MetadataConstants.DEFAULT_PATH_TAG;
+import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
+
+/**
+ * The abstract implementation of {@link MetadataReportFactory} based on
+ * {@link DynamicConfiguration the config-center infrastructure}
+ *
+ * @see MetadataReportFactory
+ * @see MetadataReport
+ * @see DynamicConfiguration
+ * @since 2.7.8
+ */
+public abstract class ConfigCenterBasedMetadataReportFactory implements MetadataReportFactory {
+
+ /**
+ * org.apache.dubbo.metadata.report.MetadataReport
+ */
+ private static final String URL_PATH = MetadataReport.class.getName();
+
+ // Registry Collection Map
+ private static final Map metadataReportCache = new ConcurrentHashMap();
+
+ private final KeyTypeEnum keyType;
+
+ public ConfigCenterBasedMetadataReportFactory(KeyTypeEnum keyType) {
+ if (keyType == null) {
+ throw new NullPointerException("The keyType argument must not be null!");
+ }
+ this.keyType = keyType;
+ }
+
+ @Override
+ public ConfigCenterBasedMetadataReport getMetadataReport(URL url) {
+
+ url = url.setPath(URL_PATH).removeParameters(EXPORT_KEY, REFER_KEY);
+
+ final URL actualURL;
+ if (url.getParameter(CONFIG_BASE_PATH_PARAM_NAME) == null) {
+ actualURL = url.addParameter(CONFIG_BASE_PATH_PARAM_NAME, DEFAULT_PATH_TAG);
+ } else {
+ actualURL = url;
+ }
+
+ String key = actualURL.toServiceString();
+ // Lock the metadata access process to ensure a single instance of the metadata instance
+ return metadataReportCache.computeIfAbsent(key, k -> new ConfigCenterBasedMetadataReport(actualURL, keyType));
+ }
+
+ /**
+ * Get {@link KeyTypeEnum the key type}
+ *
+ * @return non-null
+ */
+ protected KeyTypeEnum getKeyType() {
+ return keyType;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/file/FileSystemMetadataReportFactory.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/file/FileSystemMetadataReportFactory.java
new file mode 100644
index 00000000000..c4cc4874b85
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/file/FileSystemMetadataReportFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.metadata.report.support.file;
+
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.support.ConfigCenterBasedMetadataReportFactory;
+
+/**
+ * The implementation of {@link ConfigCenterBasedMetadataReportFactory} based on File System
+ *
+ * @see ConfigCenterBasedMetadataReportFactory
+ * @since 2.7.8
+ */
+public class FileSystemMetadataReportFactory extends ConfigCenterBasedMetadataReportFactory {
+
+ public FileSystemMetadataReportFactory() {
+ super(KeyTypeEnum.PATH);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/AbstractAbstractWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/AbstractAbstractWritableMetadataService.java
new file mode 100644
index 00000000000..35054c9ecb1
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/AbstractAbstractWritableMetadataService.java
@@ -0,0 +1,100 @@
+/*
+ * 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.metadata.store;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+
+import com.google.gson.Gson;
+
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
+import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
+import static org.apache.dubbo.common.utils.ClassUtils.forName;
+import static org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder.buildFullDefinition;
+import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
+import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+import static org.apache.dubbo.rpc.support.ProtocolUtils.isGeneric;
+
+/**
+ * The abstract implementation of {@link WritableMetadataService}
+ *
+ * @see WritableMetadataService
+ * @since 2.7.8
+ */
+public abstract class AbstractAbstractWritableMetadataService implements WritableMetadataService {
+
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Override
+ public void publishServiceDefinition(URL url) {
+ if (SERVICE_INTERFACE_NAME.equals(url.getServiceInterface())) { // Ignore the interface "MetadataService"
+ return;
+ }
+
+ // Remove the useless parameters
+ url = url.removeParameters(PID_KEY, TIMESTAMP_KEY, BIND_IP_KEY, BIND_PORT_KEY, TIMESTAMP_KEY);
+
+ String side = url.getParameter(SIDE_KEY);
+ if (PROVIDER_SIDE.equalsIgnoreCase(side)) {
+ publishProviderServiceDefinition(url);
+ } else {
+ publishConsumerParameters(url);
+ }
+ }
+
+ protected void publishProviderServiceDefinition(URL url) {
+ String serviceDefinition = getServiceDefinition(url);
+ if (!StringUtils.isBlank(serviceDefinition)) {
+ publishServiceDefinition(url.getServiceKey(), serviceDefinition);
+ }
+ }
+
+ protected String getServiceDefinition(URL exportedURL) {
+ String interfaceName = exportedURL.getParameter(INTERFACE_KEY);
+ String json = null;
+ try {
+ if (StringUtils.isNotEmpty(interfaceName) && !isGeneric(exportedURL.getParameter(GENERIC_KEY))) {
+ Class interfaceClass = forName(interfaceName);
+ ServiceDefinition serviceDefinition = buildFullDefinition(interfaceClass, exportedURL.getParameters());
+ Gson gson = new Gson();
+ json = gson.toJson(serviceDefinition);
+ }
+ } catch (ClassNotFoundException e) {
+ //ignore error
+ if (logger.isErrorEnabled()) {
+ logger.error("The interface class[name : " + interfaceName + "] can't be found , providerUrl: "
+ + exportedURL.toFullString());
+ }
+ }
+ return json;
+ }
+
+ protected void publishConsumerParameters(URL url) {
+ }
+
+ protected void publishServiceDefinition(String key, String json) {
+ }
+
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java
deleted file mode 100644
index 84fcd158b69..00000000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.metadata.store;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.metadata.MetadataService;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.concurrent.ConcurrentNavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.function.Consumer;
-
-public class BaseWritableMetadataService {
- final Logger logger = LoggerFactory.getLogger(getClass());
-
- // =================================== Registration =================================== //
-
- /**
- * All exported {@link URL urls} {@link Map} whose key is the return value of {@link URL#getServiceKey()} method
- * and value is the {@link SortedSet sorted set} of the {@link URL URLs}
- */
- static ConcurrentNavigableMap> exportedServiceURLs = new ConcurrentSkipListMap<>();
-
- // ==================================================================================== //
-
- // =================================== Subscription =================================== //
-
- /**
- * The subscribed {@link URL urls} {@link Map} of {@link MetadataService},
- * whose key is the return value of {@link URL#getServiceKey()} method and value is
- * the {@link SortedSet sorted set} of the {@link URL URLs}
- */
- final static ConcurrentNavigableMap> SUBSCRIBED_SERVICE_URLS = new ConcurrentSkipListMap<>();
-
- final static ConcurrentNavigableMap SERVICE_DEFINITIONS = new ConcurrentSkipListMap<>();
-
-
- boolean throwableAction(Consumer consumer, URL url) {
- try {
- consumer.accept(url);
- } catch (Exception e) {
- logger.error("Failed to remove url metadata to remote center, url is: " + url);
- return false;
- }
- return true;
- }
-
- public SortedSet getSubscribedURLs() {
- return getAllUnmodifiableServiceURLs(SUBSCRIBED_SERVICE_URLS);
- }
-
- static SortedSet getAllUnmodifiableServiceURLs(Map> serviceURLs) {
- return MetadataService.toSortedStrings(serviceURLs.values().stream().flatMap(Collection::stream));
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java
index ee1e4d19770..a897d766b6c 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java
@@ -16,17 +16,11 @@
*/
package org.apache.dubbo.metadata.store;
+import org.apache.dubbo.common.BaseServiceMetadata;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
-import org.apache.dubbo.rpc.support.ProtocolUtils;
-
-import com.google.gson.Gson;
import java.util.Comparator;
import java.util.Map;
@@ -39,12 +33,11 @@
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Collections.emptySortedSet;
+import static java.util.Collections.unmodifiableSortedMap;
import static java.util.Collections.unmodifiableSortedSet;
import static org.apache.dubbo.common.URL.buildKey;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
-import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
/**
* The {@link WritableMetadataService} implementation stores the metadata of Dubbo services in memory locally when they
@@ -54,9 +47,7 @@
* @see WritableMetadataService
* @since 2.7.5
*/
-public class InMemoryWritableMetadataService implements WritableMetadataService {
-
- final Logger logger = LoggerFactory.getLogger(getClass());
+public class InMemoryWritableMetadataService extends AbstractAbstractWritableMetadataService {
private final Lock lock = new ReentrantLock();
@@ -66,7 +57,7 @@ public class InMemoryWritableMetadataService implements WritableMetadataService
* All exported {@link URL urls} {@link Map} whose key is the return value of {@link URL#getServiceKey()} method
* and value is the {@link SortedSet sorted set} of the {@link URL URLs}
*/
- ConcurrentNavigableMap> exportedServiceURLs = new ConcurrentSkipListMap<>();
+ private final ConcurrentNavigableMap> exportedServiceURLs = new ConcurrentSkipListMap<>();
// ==================================================================================== //
@@ -77,9 +68,13 @@ public class InMemoryWritableMetadataService implements WritableMetadataService
* whose key is the return value of {@link URL#getServiceKey()} method and value is
* the {@link SortedSet sorted set} of the {@link URL URLs}
*/
- ConcurrentNavigableMap> subscribedServiceURLs = new ConcurrentSkipListMap<>();
+ private final ConcurrentNavigableMap> subscribedServiceURLs = new ConcurrentSkipListMap<>();
- ConcurrentNavigableMap serviceDefinitions = new ConcurrentSkipListMap<>();
+ /**
+ * The {@link Map} caches the json of {@link ServiceDefinition} with
+ * {@link BaseServiceMetadata#buildServiceKey(String, String, String) the service key}
+ */
+ private final ConcurrentNavigableMap serviceDefinitions = new ConcurrentSkipListMap<>();
@Override
public SortedSet getSubscribedURLs() {
@@ -131,33 +126,25 @@ public boolean unsubscribeURL(URL url) {
}
@Override
- public void publishServiceDefinition(URL providerUrl) {
- try {
- String interfaceName = providerUrl.getParameter(INTERFACE_KEY);
- if (StringUtils.isNotEmpty(interfaceName)
- && !ProtocolUtils.isGeneric(providerUrl.getParameter(GENERIC_KEY))) {
- Class interfaceClass = Class.forName(interfaceName);
- ServiceDefinition serviceDefinition = ServiceDefinitionBuilder.build(interfaceClass);
- Gson gson = new Gson();
- String data = gson.toJson(serviceDefinition);
- serviceDefinitions.put(providerUrl.getServiceKey(), data);
- return;
- }
- logger.error("publishProvider interfaceName is empty . providerUrl: " + providerUrl.toFullString());
- } catch (Throwable t) {
- //ignore error
- logger.error("publishProvider getServiceDescriptor error. providerUrl: " + providerUrl.toFullString(), t.getCause());
- }
+ protected void publishServiceDefinition(String key, String json) {
+ serviceDefinitions.put(key, json);
}
@Override
- public String getServiceDefinition(String interfaceName, String version, String group) {
- return serviceDefinitions.get(URL.buildKey(interfaceName, group, version));
+ public String getServiceDefinition(String serviceDefinitionKey) {
+ return serviceDefinitions.get(serviceDefinitionKey);
}
- @Override
- public String getServiceDefinition(String serviceKey) {
- return serviceDefinitions.get(serviceKey);
+ public Map> getExportedServiceURLs() {
+ return unmodifiableSortedMap(exportedServiceURLs);
+ }
+
+ public Map> getSubscribedServiceURLs() {
+ return unmodifiableSortedMap(subscribedServiceURLs);
+ }
+
+ public Map getServiceDefinitions() {
+ return unmodifiableSortedMap(serviceDefinitions);
}
boolean addURL(Map> serviceURLs, URL url) {
@@ -223,7 +210,6 @@ private boolean isAcceptableProtocol(String protocol, URL url) {
|| protocol.equals(url.getProtocol());
}
-
static class URLComparator implements Comparator {
public static final URLComparator INSTANCE = new URLComparator();
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java
index 0a2dd76dd3e..c2ae3e512a6 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java
@@ -17,35 +17,22 @@
package org.apache.dubbo.metadata.store;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.metadata.URLRevisionResolver;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.remoting.Constants;
-import org.apache.dubbo.rpc.RpcException;
-import java.util.Iterator;
-import java.util.Set;
import java.util.SortedSet;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
/**
@@ -55,15 +42,15 @@
*
* @since 2.7.5
*/
-public class RemoteWritableMetadataService implements WritableMetadataService {
+public class RemoteWritableMetadataService extends AbstractAbstractWritableMetadataService {
- protected final Logger logger = LoggerFactory.getLogger(getClass());
- private volatile String exportedRevision;
- private volatile String subscribedRevision;
- private InMemoryWritableMetadataService writableMetadataService;
+ private final InMemoryWritableMetadataService writableMetadataServiceDelegate;
- public RemoteWritableMetadataService(InMemoryWritableMetadataService writableMetadataService) {
- this.writableMetadataService = writableMetadataService;
+ private final URLRevisionResolver urlRevisionResolver;
+
+ public RemoteWritableMetadataService() {
+ this.writableMetadataServiceDelegate = (InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension();
+ urlRevisionResolver = URLRevisionResolver.INSTANCE;
}
public MetadataReport getMetadataReport() {
@@ -71,163 +58,65 @@ public MetadataReport getMetadataReport() {
}
@Override
- public void publishServiceDefinition(URL url) {
- String side = url.getParameter(SIDE_KEY);
- if (PROVIDER_SIDE.equalsIgnoreCase(side)) {
- //TODO, the params part is duplicate with that stored by exportURL(url), can be further optimized in the future.
- publishProvider(url);
- } else {
- //TODO, only useful for ops showing the url parameters, this is duplicate with subscribeURL(url), can be removed in the future.
- publishConsumer(url);
- }
+ protected void publishConsumerParameters(URL consumerURL) {
+ getMetadataReport().storeConsumerMetadata(new MetadataIdentifier(consumerURL.getServiceInterface(),
+ consumerURL.getParameter(VERSION_KEY), consumerURL.getParameter(GROUP_KEY), CONSUMER_SIDE,
+ consumerURL.getParameter(APPLICATION_KEY)), consumerURL.getParameters());
}
- private void publishProvider(URL providerUrl) throws RpcException {
- //first add into the list
- // remove the individual param
- providerUrl = providerUrl.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY,
- Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
-
+ @Override
+ protected void publishProviderServiceDefinition(URL providerURL) {
try {
- String interfaceName = providerUrl.getParameter(INTERFACE_KEY);
+ String interfaceName = providerURL.getParameter(INTERFACE_KEY);
if (StringUtils.isNotEmpty(interfaceName)) {
Class interfaceClass = Class.forName(interfaceName);
FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass,
- providerUrl.getParameters());
- getMetadataReport().storeProviderMetadata(new MetadataIdentifier(providerUrl.getServiceInterface(),
- providerUrl.getParameter(VERSION_KEY), providerUrl.getParameter(GROUP_KEY),
- PROVIDER_SIDE, providerUrl.getParameter(APPLICATION_KEY)), fullServiceDefinition);
+ providerURL.getParameters());
+ getMetadataReport().storeProviderMetadata(new MetadataIdentifier(providerURL.getServiceInterface(),
+ providerURL.getParameter(VERSION_KEY), providerURL.getParameter(GROUP_KEY),
+ PROVIDER_SIDE, providerURL.getParameter(APPLICATION_KEY)), fullServiceDefinition);
return;
}
- logger.error("publishProvider interfaceName is empty . providerUrl: " + providerUrl.toFullString());
- } catch (Throwable t) {
+ logger.error("publishProvider interfaceName is empty . url: " + providerURL.toFullString());
+ } catch (ClassNotFoundException e) {
//ignore error
- logger.error("publishProvider getServiceDescriptor error. providerUrl: " + providerUrl.toFullString(), t.getCause());
+ logger.error("publishProvider getServiceDescriptor error. url: " + providerURL.toFullString(), e);
}
}
- private void publishConsumer(URL consumerURL) throws RpcException {
- consumerURL = consumerURL.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY,
- Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
- getMetadataReport().storeConsumerMetadata(new MetadataIdentifier(consumerURL.getServiceInterface(),
- consumerURL.getParameter(VERSION_KEY), consumerURL.getParameter(GROUP_KEY), CONSUMER_SIDE,
- consumerURL.getParameter(APPLICATION_KEY)), consumerURL.getParameters());
- }
-
@Override
public boolean exportURL(URL url) {
- // do nothing for one single url export, the actual report will be done in callback (refreshMetadata) after all urls are exported.
- return true;
+ return writableMetadataServiceDelegate.exportURL(url);
}
@Override
public boolean unexportURL(URL url) {
- ServiceMetadataIdentifier metadataIdentifier = new ServiceMetadataIdentifier(url);
- metadataIdentifier.setRevision(exportedRevision);
- metadataIdentifier.setProtocol(url.getProtocol());
- return throwableAction(getMetadataReport()::removeServiceMetadata, metadataIdentifier);
+ return writableMetadataServiceDelegate.unexportURL(url);
}
@Override
public boolean subscribeURL(URL url) {
- // do nothing for one single url export, the actual report will be done in callback (refreshMetadata) after all urls are exported.
- return true;
+ return writableMetadataServiceDelegate.subscribeURL(url);
}
@Override
public boolean unsubscribeURL(URL url) {
- // do nothing for one single url export, the actual report will be done in callback (refreshMetadata) after all urls are exported.
- return true;
+ return writableMetadataServiceDelegate.unsubscribeURL(url);
}
- @Override
- public boolean refreshMetadata(String exportedRevision, String subscribedRevision) {
- boolean result = true;
- if (!StringUtils.isEmpty(exportedRevision) && !exportedRevision.equals(this.exportedRevision)) {
- this.exportedRevision = exportedRevision;
- boolean executeResult = saveServiceMetadata();
- if (!executeResult) {
- result = false;
- }
- }
- if (!StringUtils.isEmpty(subscribedRevision) && !subscribedRevision.equals(this.subscribedRevision)
- && CollectionUtils.isNotEmpty(writableMetadataService.getSubscribedURLs())) {
- this.subscribedRevision = subscribedRevision;
- SubscriberMetadataIdentifier metadataIdentifier = new SubscriberMetadataIdentifier();
- metadataIdentifier.setApplication(serviceName());
- metadataIdentifier.setRevision(subscribedRevision);
- boolean executeResult = throwableAction(getMetadataReport()::saveSubscribedData, metadataIdentifier,
- writableMetadataService.getSubscribedURLs());
- if (!executeResult) {
- result = false;
- }
- }
- return result;
- }
-
- private boolean saveServiceMetadata() {
- boolean result = true;
- for (SortedSet urls : writableMetadataService.exportedServiceURLs.values()) {
- Iterator iterator = urls.iterator();
- while (iterator.hasNext()) {
- URL url = iterator.next();
- // refresh revision in urls
- ServiceMetadataIdentifier metadataIdentifier = new ServiceMetadataIdentifier(url);
- metadataIdentifier.setRevision(exportedRevision);
- metadataIdentifier.setProtocol(url.getProtocol());
-
- boolean tmpResult = throwableAction(getMetadataReport()::saveServiceMetadata, metadataIdentifier, url);
- if (!tmpResult) result = tmpResult;
- }
- }
- return result;
- }
-
-
@Override
public SortedSet getExportedURLs(String serviceInterface, String group, String version, String protocol) {
- return null;
- }
-
- @Override
- public String getServiceDefinition(String interfaceName, String version, String group) {
- return null;
+ return writableMetadataServiceDelegate.getExportedURLs(serviceInterface, group, version, protocol);
}
@Override
public String getServiceDefinition(String serviceKey) {
- return null;
- }
-
- boolean throwableAction(BiConsumer consumer,
- ServiceMetadataIdentifier metadataIdentifier, URL url) {
- try {
- consumer.accept(metadataIdentifier, url);
- } catch (Exception e) {
- logger.error("Failed to execute consumer, url is: " + url);
- return false;
- }
- return true;
+ return writableMetadataServiceDelegate.getServiceDefinition(serviceKey);
}
- boolean throwableAction(BiConsumer> consumer,
- SubscriberMetadataIdentifier metadataIdentifier, Set urls) {
- try {
- consumer.accept(metadataIdentifier, urls);
- } catch (Exception e) {
- logger.error("Failed to execute consumer, url is: " + urls);
- return false;
- }
- return true;
+ @Override
+ public SortedSet getSubscribedURLs() {
+ return writableMetadataServiceDelegate.getSubscribedURLs();
}
- boolean throwableAction(Consumer consumer, ServiceMetadataIdentifier metadataIdentifier) {
- try {
- consumer.accept(metadataIdentifier);
- } catch (Exception e) {
- logger.error("Failed to remove url metadata to remote center, metadataIdentifier is: " + metadataIdentifier);
- return false;
- }
- return true;
- }
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegate.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegate.java
deleted file mode 100644
index 132a0cbe034..00000000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegate.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.metadata.store;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.metadata.WritableMetadataService;
-
-import java.util.SortedSet;
-import java.util.function.BiFunction;
-
-/**
- * 2019-08-14
- *
- * @since 2.7.5
- */
-public class RemoteWritableMetadataServiceDelegate implements WritableMetadataService {
- InMemoryWritableMetadataService defaultWritableMetadataService;
- RemoteWritableMetadataService remoteWritableMetadataService;
-
- public RemoteWritableMetadataServiceDelegate() {
- defaultWritableMetadataService = (InMemoryWritableMetadataService) WritableMetadataService.getExtension("local");
- remoteWritableMetadataService = new RemoteWritableMetadataService(defaultWritableMetadataService);
- }
-
- private WritableMetadataService getDefaultWritableMetadataService() {
- return defaultWritableMetadataService;
- }
-
- @Override
- public boolean exportURL(URL url) {
- return doFunction(WritableMetadataService::exportURL, url);
- }
-
- @Override
- public boolean unexportURL(URL url) {
- return doFunction(WritableMetadataService::unexportURL, url);
- }
-
- @Override
- public boolean subscribeURL(URL url) {
- return doFunction(WritableMetadataService::subscribeURL, url);
- }
-
- @Override
- public boolean unsubscribeURL(URL url) {
- return doFunction(WritableMetadataService::unsubscribeURL, url);
- }
-
- @Override
- public boolean refreshMetadata(String exportedRevision, String subscribedRevision) {
- boolean result = true;
- result &= defaultWritableMetadataService.refreshMetadata(exportedRevision, subscribedRevision);
- result &= remoteWritableMetadataService.refreshMetadata(exportedRevision, subscribedRevision);
- return result;
- }
-
- @Override
- public void publishServiceDefinition(URL providerUrl) {
- defaultWritableMetadataService.publishServiceDefinition(providerUrl);
- remoteWritableMetadataService.publishServiceDefinition(providerUrl);
- }
-
- @Override
- public SortedSet getExportedURLs(String serviceInterface, String group, String version, String protocol) {
- return getDefaultWritableMetadataService().getExportedURLs(serviceInterface, group, version, protocol);
- }
-
- @Override
- public SortedSet getSubscribedURLs() {
- return getDefaultWritableMetadataService().getSubscribedURLs();
- }
-
- @Override
- public String getServiceDefinition(String interfaceName, String version, String group) {
- return getDefaultWritableMetadataService().getServiceDefinition(interfaceName, version, group);
- }
-
- @Override
- public String getServiceDefinition(String serviceKey) {
- return getDefaultWritableMetadataService().getServiceDefinition(serviceKey);
- }
-
- private boolean doFunction(BiFunction func, URL url) {
- return func.apply(defaultWritableMetadataService, url) && func.apply(remoteWritableMetadataService, url);
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping
index 3975068fc93..beadd2eb479 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping
@@ -1 +1,9 @@
-default=org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping
\ No newline at end of file
+# "default" implementation has been changed since 2.7.8
+default=org.apache.dubbo.metadata.CompositeServiceNameMapping
+
+# "properties-file" and "parameterized" are introduced since 2.7.8
+properties-file = org.apache.dubbo.metadata.PropertiesFileServiceNameMapping
+parameterized = org.apache.dubbo.metadata.ParameterizedServiceNameMapping
+
+# "dynamic-configuration" has been revised since 2.7.8
+dynamic-configuration = org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
index bfe794bf963..26bc942e704 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
@@ -1,2 +1,2 @@
local=org.apache.dubbo.metadata.store.InMemoryWritableMetadataService
-remote=org.apache.dubbo.metadata.store.RemoteWritableMetadataServiceDelegate
\ No newline at end of file
+remote=org.apache.dubbo.metadata.store.RemoteWritableMetadataService
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
new file mode 100644
index 00000000000..b686fced440
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
@@ -0,0 +1 @@
+file = org.apache.dubbo.metadata.report.support.file.FileSystemMetadataReportFactory
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/CompositeServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/CompositeServiceNameMappingTest.java
new file mode 100644
index 00000000000..48243f8c49e
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/CompositeServiceNameMappingTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.metadata;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.service.EchoService;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static java.util.Collections.singleton;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
+import static org.apache.dubbo.common.utils.CollectionUtils.ofSet;
+import static org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping.buildGroup;
+import static org.apache.dubbo.rpc.model.ApplicationModel.getApplicationConfig;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * {@link CompositeServiceNameMapping} Test
+ *
+ * @since 2.7.8
+ */
+public class CompositeServiceNameMappingTest {
+
+ private static final URL BASE_URL = URL.valueOf("dubbo://127.0.0.1:20880")
+ .setPath(EchoService.class.getName())
+ .addParameter(GROUP_KEY, "default")
+ .addParameter(VERSION_KEY, "1.0.0");
+
+ private static final String APP_NAME = "test-service";
+
+ private ServiceNameMapping serviceNameMapping;
+
+ private FileSystemDynamicConfiguration dynamicConfiguration;
+
+ @BeforeEach
+ public void init() {
+ serviceNameMapping = ServiceNameMapping.getDefaultExtension();
+ dynamicConfiguration = new FileSystemDynamicConfiguration();
+ ApplicationModel.getConfigManager().setApplication(new ApplicationConfig(APP_NAME));
+ ApplicationModel.getEnvironment().setDynamicConfiguration(dynamicConfiguration);
+ }
+
+ @AfterEach
+ public void reset() {
+ FileUtils.deleteQuietly(dynamicConfiguration.getRootDirectory());
+ ApplicationModel.reset();
+ }
+
+ @Test
+ public void testType() {
+ assertEquals(CompositeServiceNameMapping.class, serviceNameMapping.getClass());
+ }
+
+ @Test
+ public void testMap() {
+ serviceNameMapping.map(BASE_URL);
+ assertNotNull(dynamicConfiguration.getConfig(APP_NAME,
+ buildGroup(BASE_URL.getServiceInterface(), null, null, null)));
+ }
+
+ @Test
+ public void testGet() {
+ serviceNameMapping.map(BASE_URL);
+ Set serviceNames = serviceNameMapping.get(BASE_URL);
+ assertEquals(singleton(APP_NAME), serviceNames);
+
+ getApplicationConfig().setName("service1");
+ serviceNameMapping.map(BASE_URL);
+ serviceNames = serviceNameMapping.get(BASE_URL);
+ assertEquals(ofSet(APP_NAME, "service1"), serviceNames);
+
+ serviceNames = serviceNameMapping.get(BASE_URL
+ .setPath("com.acme.Interface1")
+ .removeParameter(VERSION_KEY)
+ );
+ assertEquals(singleton("Service1"), serviceNames);
+
+ serviceNames = serviceNameMapping.get(BASE_URL.addParameter(SUBSCRIBED_SERVICE_NAMES_KEY, "s1 , s2 , s3 "));
+ assertEquals(ofSet("s1", "s2", "s3"), serviceNames);
+ }
+}
+
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java
index 0e677dfa096..d4d25ee85c5 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.metadata;
+import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory;
import org.apache.dubbo.config.ApplicationConfig;
@@ -28,10 +29,13 @@
import java.util.TreeSet;
import static java.util.Arrays.asList;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping.buildGroup;
import static org.apache.dubbo.metadata.ServiceNameMapping.getDefaultExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* {@link DynamicConfigurationServiceNameMapping} Test
@@ -61,6 +65,17 @@ public void testBuildGroup() {
assertEquals("mapping/test", buildGroup("test", "default", "1.0.0", "dubbo"));
}
+ @Test
+ public void testAndGetOnFailed() {
+ assertThrows(UnsupportedOperationException.class, () -> {
+ serviceNameMapping.map(null, null, null, null);
+ });
+
+ assertThrows(UnsupportedOperationException.class, () -> {
+ serviceNameMapping.get(null, null, null, null);
+ });
+ }
+
@Test
public void testMapAndGet() {
@@ -74,14 +89,18 @@ public void testMapAndGet() {
String version = null;
String protocol = null;
- serviceNameMapping.map(serviceInterface, group, version, protocol);
+ URL url = URL.valueOf("dubbo://127.0.0.1:20880").setServiceInterface(serviceInterface)
+ .addParameter(GROUP_KEY, group)
+ .addParameter(VERSION_KEY, version);
+
+ serviceNameMapping.map(url);
ApplicationModel.getConfigManager().removeConfig(new ApplicationConfig(serviceName));
ApplicationModel.getConfigManager().setApplication(new ApplicationConfig(serviceName2));
- serviceNameMapping.map(serviceInterface, group, version, protocol);
+ serviceNameMapping.map(url);
- Set serviceNames = serviceNameMapping.get(serviceInterface, group, version, protocol);
+ Set serviceNames = serviceNameMapping.get(url);
assertEquals(new TreeSet(asList(serviceName, serviceName2)), serviceNames);
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/InMemoryWritableMetadataServiceTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/InMemoryWritableMetadataServiceTest.java
index 461cf28149b..187f12612dd 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/InMemoryWritableMetadataServiceTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/InMemoryWritableMetadataServiceTest.java
@@ -17,10 +17,12 @@
package org.apache.dubbo.metadata;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metadata.store.InMemoryWritableMetadataService;
import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Set;
@@ -54,9 +56,15 @@ public class InMemoryWritableMetadataServiceTest {
private static final URL BASE_URL_GROUP_AND_VERSION = BASE_URL_GROUP.addParameter(VERSION_KEY, "1.0.0");
private static final URL BASE_URL_GROUP_AND_VERSION_AND_PROTOCOL = BASE_URL_GROUP_AND_VERSION.addParameter(PROTOCOL_KEY, "rest");
- @BeforeAll
- public static void init() {
- ApplicationModel.setApplication("test");
+ @BeforeEach
+ public void init() {
+ ApplicationConfig applicationConfig = new ApplicationConfig("test");
+ ApplicationModel.getConfigManager().setApplication(applicationConfig);
+ }
+
+ @AfterEach
+ public void reset() {
+ ApplicationModel.reset();
}
@Test
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataConstantsTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataConstantsTest.java
new file mode 100644
index 00000000000..d0c201b0d7c
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataConstantsTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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.metadata;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link MetadataConstants} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class MetadataConstantsTest {
+
+ @Test
+ public void testConstants() {
+ assertEquals("exported-urls", MetadataConstants.EXPORTED_URLS_TAG);
+ assertEquals("subscribed-urls", MetadataConstants.SUBSCRIBED_URLS_TAG);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataServiceTypeTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataServiceTypeTest.java
new file mode 100644
index 00000000000..11eec1dff4b
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataServiceTypeTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.metadata;
+
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.metadata.MetadataServiceType.COMPOSITE;
+import static org.apache.dubbo.metadata.MetadataServiceType.DEFAULT;
+import static org.apache.dubbo.metadata.MetadataServiceType.REMOTE;
+import static org.apache.dubbo.metadata.MetadataServiceType.getOrDefault;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link MetadataServiceType} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class MetadataServiceTypeTest {
+
+ @Test
+ public void testGetValue() {
+ assertEquals("local", DEFAULT.getValue());
+ assertEquals("remote", REMOTE.getValue());
+ assertEquals("composite", COMPOSITE.getValue());
+ }
+
+ @Test
+ public void testGetOrDefault() {
+ assertEquals(DEFAULT, getOrDefault("local"));
+ assertEquals(REMOTE, getOrDefault("remote"));
+ assertEquals(COMPOSITE, getOrDefault("composite"));
+ assertEquals(DEFAULT, getOrDefault("others"));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/ParameterizedServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/ParameterizedServiceNameMappingTest.java
new file mode 100644
index 00000000000..dbe54540726
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/ParameterizedServiceNameMappingTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.metadata;
+
+import org.apache.dubbo.common.URL;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static java.util.Collections.emptySet;
+import static java.util.Collections.singleton;
+import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link ParameterizedServiceNameMapping} Test
+ *
+ * @see ParameterizedServiceNameMapping
+ * @since 2.7.8
+ */
+public class ParameterizedServiceNameMappingTest {
+
+ private static final URL BASE_URL = URL.valueOf("dubbo://127.0.0.1:20880");
+
+ private ParameterizedServiceNameMapping serviceNameMapping;
+
+ @BeforeEach
+ public void init() {
+ serviceNameMapping = new ParameterizedServiceNameMapping();
+ }
+
+ @Test
+ public void testMap() {
+ // NOTHING to happen
+ serviceNameMapping.map(BASE_URL);
+ }
+
+ @Test
+ public void testGet() {
+ Set serviceNames = serviceNameMapping.get(BASE_URL);
+ assertEquals(emptySet(), serviceNames);
+
+ serviceNames = serviceNameMapping.get(BASE_URL.addParameter(SUBSCRIBED_SERVICE_NAMES_KEY, " Service1 "));
+ assertEquals(singleton("Service1"), serviceNames);
+
+ serviceNames = serviceNameMapping.get(BASE_URL.addParameter(SUBSCRIBED_SERVICE_NAMES_KEY, "Service1 , Service2 "));
+ assertEquals(new LinkedHashSet(Arrays.asList("Service1", "Service2")), serviceNames);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PropertiesFileServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PropertiesFileServiceNameMappingTest.java
new file mode 100644
index 00000000000..68a6ebfcf84
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/PropertiesFileServiceNameMappingTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.metadata;
+
+import org.apache.dubbo.common.URL;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+
+import static java.util.Collections.singleton;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link PropertiesFileServiceNameMapping} Test
+ *
+ * @since 2.7.8
+ */
+public class PropertiesFileServiceNameMappingTest {
+
+ private static final URL BASE_URL = URL.valueOf("dubbo://127.0.0.1:20880");
+
+
+ @Test
+ public void testMap() {
+ PropertiesFileServiceNameMapping serviceNameMapping = new PropertiesFileServiceNameMapping();
+ serviceNameMapping.map(BASE_URL);
+ }
+
+ @Test
+ public void testGet() {
+
+ PropertiesFileServiceNameMapping serviceNameMapping = new PropertiesFileServiceNameMapping();
+ URL url = BASE_URL.setServiceInterface("com.acme.Interface1").addParameter(GROUP_KEY, "default");
+ assertEquals(singleton("Service1"), serviceNameMapping.get(url));
+
+ System.setProperty(SERVICE_NAME_MAPPING_PROPERTIES_FILE_KEY, "///META-INF//dubbo/service-name-mapping.properties");
+ serviceNameMapping = new PropertiesFileServiceNameMapping();
+
+ url = BASE_URL.setProtocol("thirft").setServiceInterface("com.acme.InterfaceX");
+ assertEquals(new LinkedHashSet<>(Arrays.asList("Service1", "Service2")), serviceNameMapping.get(url));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/ServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/ServiceNameMappingTest.java
new file mode 100644
index 00000000000..8c379983d6b
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/ServiceNameMappingTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.metadata;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singleton;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
+import static org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping.buildGroup;
+import static org.apache.dubbo.metadata.ServiceNameMapping.getDefaultExtension;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * {@link ServiceNameMapping} Test
+ *
+ * @since 2.7.8
+ */
+public class ServiceNameMappingTest {
+
+ private static final URL BASE_URL = URL.valueOf("dubbo://127.0.0.1:20880");
+
+ private FileSystemDynamicConfiguration configuration;
+
+ private ServiceNameMapping serviceNameMapping;
+
+ private String applicationName;
+
+ @BeforeEach
+ public void init() {
+
+ ApplicationModel.reset();
+
+ applicationName = getClass().getSimpleName();
+
+ ApplicationModel.getConfigManager().setApplication(new ApplicationConfig(applicationName));
+
+ configuration = new FileSystemDynamicConfiguration();
+
+ FileUtils.deleteQuietly(configuration.getRootDirectory());
+
+ ApplicationModel.getEnvironment().setDynamicConfiguration(configuration);
+
+ serviceNameMapping = getDefaultExtension();
+ }
+
+ @AfterEach
+ public void reset() throws Exception {
+ FileUtils.deleteQuietly(configuration.getRootDirectory());
+ configuration.close();
+ ApplicationModel.reset();
+ }
+
+ @Test
+ public void testDeprecatedMethods() {
+ assertThrows(UnsupportedOperationException.class, () -> {
+ serviceNameMapping.map(null, null, null, null);
+ });
+
+ assertThrows(UnsupportedOperationException.class, () -> {
+ serviceNameMapping.get(null, null, null, null);
+ });
+ }
+
+ @Test
+ public void testMap() {
+ String serviceInterface = ServiceNameMapping.class.getName();
+ String key = applicationName;
+ String group = buildGroup(serviceInterface, null, null, null);
+ URL url = BASE_URL.setServiceInterface(serviceInterface);
+ serviceNameMapping.map(url);
+ assertNotNull(configuration.getConfig(key, group));
+ }
+
+ @Test
+ public void testGet() {
+ String serviceInterface = ServiceNameMapping.class.getName();
+ URL url = BASE_URL.setServiceInterface(serviceInterface);
+ serviceNameMapping.map(url);
+ Set serviceNames = serviceNameMapping.get(url);
+ assertEquals(singleton(applicationName), serviceNames);
+
+ url = url.setServiceInterface("com.acme.Interface1").addParameter(GROUP_KEY, "default");
+ serviceNames = serviceNameMapping.get(url);
+ assertEquals(singleton("Service1"), serviceNames);
+
+
+ url = url.addParameter(SUBSCRIBED_SERVICE_NAMES_KEY, "A , B , C ");
+ serviceNames = serviceNameMapping.get(url);
+ assertEquals(new LinkedHashSet<>(asList("A", "B", "C")), serviceNames);
+
+ }
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/URLRevisionResolverTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/URLRevisionResolverTest.java
similarity index 67%
rename from dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/URLRevisionResolverTest.java
rename to dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/URLRevisionResolverTest.java
index 3386bba0e84..b36ebcb480a 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/URLRevisionResolverTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/URLRevisionResolverTest.java
@@ -14,12 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.registry.client.metadata;
+package org.apache.dubbo.metadata;
import org.junit.jupiter.api.Test;
+import java.util.Arrays;
+import java.util.Collection;
+
import static java.util.Arrays.asList;
-import static org.apache.dubbo.registry.client.metadata.URLRevisionResolver.NO_REVISION;
+import static org.apache.dubbo.metadata.URLRevisionResolver.UNKNOWN_REVISION;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
@@ -29,19 +32,19 @@
*/
public class URLRevisionResolverTest {
- private static final String URL = "dubbo://192.168.0.102:20881/org.apache.dubbo.registry.client.metadata.URLRevisionResolverTest";
+ private static final String URL = "dubbo://192.168.0.102:20881/org.apache.dubbo.metadata.URLRevisionResolverTest";
- private final URLRevisionResolver resolver = new URLRevisionResolver();
+ private final URLRevisionResolver resolver = URLRevisionResolver.INSTANCE;
@Test
public void testResolve() {
- String revision = resolver.resolve(asList());
- assertEquals(NO_REVISION, revision);
+ String revision = resolver.resolve(Arrays.asList());
+ assertEquals(UNKNOWN_REVISION, revision);
- revision = resolver.resolve(null);
- assertEquals(NO_REVISION, revision);
+ revision = resolver.resolve((Collection) null);
+ assertEquals(UNKNOWN_REVISION, revision);
revision = resolver.resolve(asList(URL));
- assertEquals("7960327984321481979", revision);
+ assertEquals("2ca0638f189ce569", revision);
}
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/KeyTypeEnumTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/KeyTypeEnumTest.java
new file mode 100644
index 00000000000..c4dae1f9190
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/KeyTypeEnumTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.metadata.report.identifier;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link KeyTypeEnum} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class KeyTypeEnumTest {
+
+ /**
+ * {@link KeyTypeEnum#build(String, String...)}
+ */
+ @Test
+ public void testBuild() {
+ assertEquals("/A/B/C", KeyTypeEnum.PATH.build("/A", "/B", "C"));
+ assertEquals("A:B:C", KeyTypeEnum.UNIQUE_KEY.build("A", "B", "C"));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java
index 30d4ad1a300..3aa5c029d20 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java
@@ -28,9 +28,9 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -65,7 +65,7 @@ public List getExportedURLs(ServiceMetadataIdentifier metadataIdentifier
@Override
public void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier,
- Set urls) {
+ Collection urls) {
}
@@ -84,6 +84,11 @@ public void storeConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier,
store.put(consumerMetadataIdentifier.getIdentifierKey(), JSON.toJSONString(serviceParameterMap));
}
+ @Override
+ public void close() throws Exception {
+
+ }
+
Map store = new ConcurrentHashMap<>();
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java
index 9d4267f7e3d..c5325a1fa30 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java
@@ -18,14 +18,18 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import com.google.gson.Gson;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -35,10 +39,15 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.SortedSet;
import java.util.concurrent.ConcurrentHashMap;
+import static java.util.Collections.emptySet;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
*
@@ -52,17 +61,25 @@ public class AbstractMetadataReportTest {
public void before() {
URL url = URL.valueOf("zookeeper://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vic");
abstractMetadataReport = new NewMetadataReport(url);
+ // set the simple name of current class as the application name
+ ApplicationModel.getConfigManager().setApplication(new ApplicationConfig(getClass().getSimpleName()));
+ }
+
+ @AfterEach
+ public void reset() {
+ // reset
+ ApplicationModel.reset();
}
@Test
public void testGetProtocol() {
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vic&side=provider");
String protocol = abstractMetadataReport.getProtocol(url);
- Assertions.assertEquals(protocol, "provider");
+ assertEquals(protocol, "provider");
URL url2 = URL.valueOf("consumer://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vic");
String protocol2 = abstractMetadataReport.getProtocol(url2);
- Assertions.assertEquals(protocol2, "consumer");
+ assertEquals(protocol2, "consumer");
}
@Test
@@ -93,7 +110,7 @@ public void testFileExistAfterPut() throws InterruptedException, ClassNotFoundEx
URL singleUrl = URL.valueOf("redis://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.metadata.store.InterfaceNameTestService?version=1.0.0&application=singleTest");
NewMetadataReport singleMetadataReport = new NewMetadataReport(singleUrl);
- Assertions.assertFalse(singleMetadataReport.file.exists());
+ Assertions.assertFalse(singleMetadataReport.localCacheFile.exists());
String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService";
String version = "1.0.0";
@@ -102,8 +119,8 @@ public void testFileExistAfterPut() throws InterruptedException, ClassNotFoundEx
MetadataIdentifier providerMetadataIdentifier = storePrivider(singleMetadataReport, interfaceName, version, group, application);
Thread.sleep(2000);
- Assertions.assertTrue(singleMetadataReport.file.exists());
- Assertions.assertTrue(singleMetadataReport.properties.containsKey(providerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY)));
+ assertTrue(singleMetadataReport.localCacheFile.exists());
+ assertTrue(singleMetadataReport.properties.containsKey(providerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY)));
}
@Test
@@ -117,22 +134,22 @@ public void testRetry() throws InterruptedException, ClassNotFoundException {
retryReport.metadataReportRetry.retryPeriod = 400L;
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vic");
Assertions.assertNull(retryReport.metadataReportRetry.retryScheduledFuture);
- Assertions.assertEquals(0, retryReport.metadataReportRetry.retryCounter.get());
- Assertions.assertTrue(retryReport.store.isEmpty());
- Assertions.assertTrue(retryReport.failedReports.isEmpty());
+ assertEquals(0, retryReport.metadataReportRetry.retryCounter.get());
+ assertTrue(retryReport.store.isEmpty());
+ assertTrue(retryReport.failedReports.isEmpty());
storePrivider(retryReport, interfaceName, version, group, application);
Thread.sleep(150);
- Assertions.assertTrue(retryReport.store.isEmpty());
+ assertTrue(retryReport.store.isEmpty());
Assertions.assertFalse(retryReport.failedReports.isEmpty());
Assertions.assertNotNull(retryReport.metadataReportRetry.retryScheduledFuture);
Thread.sleep(2000L);
- Assertions.assertTrue(retryReport.metadataReportRetry.retryCounter.get() != 0);
- Assertions.assertTrue(retryReport.metadataReportRetry.retryCounter.get() >= 3);
+ assertTrue(retryReport.metadataReportRetry.retryCounter.get() != 0);
+ assertTrue(retryReport.metadataReportRetry.retryCounter.get() >= 3);
Assertions.assertFalse(retryReport.store.isEmpty());
- Assertions.assertTrue(retryReport.failedReports.isEmpty());
+ assertTrue(retryReport.failedReports.isEmpty());
}
@Test
@@ -152,8 +169,8 @@ public void testRetryCancel() throws InterruptedException, ClassNotFoundExceptio
Assertions.assertFalse(retryReport.metadataReportRetry.retryScheduledFuture.isCancelled());
Assertions.assertFalse(retryReport.metadataReportRetry.retryExecutor.isShutdown());
Thread.sleep(1000L);
- Assertions.assertTrue(retryReport.metadataReportRetry.retryScheduledFuture.isCancelled());
- Assertions.assertTrue(retryReport.metadataReportRetry.retryExecutor.isShutdown());
+ assertTrue(retryReport.metadataReportRetry.retryScheduledFuture.isCancelled());
+ assertTrue(retryReport.metadataReportRetry.retryExecutor.isShutdown());
}
@@ -185,42 +202,42 @@ private MetadataIdentifier storeConsumer(AbstractMetadataReport abstractMetadata
@Test
public void testPublishAll() throws ClassNotFoundException, InterruptedException {
- Assertions.assertTrue(abstractMetadataReport.store.isEmpty());
- Assertions.assertTrue(abstractMetadataReport.allMetadataReports.isEmpty());
+ assertTrue(abstractMetadataReport.store.isEmpty());
+ assertTrue(abstractMetadataReport.allMetadataReports.isEmpty());
String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService";
String version = "1.0.0";
String group = null;
String application = "vic";
MetadataIdentifier providerMetadataIdentifier1 = storePrivider(abstractMetadataReport, interfaceName, version, group, application);
Thread.sleep(1000);
- Assertions.assertEquals(abstractMetadataReport.allMetadataReports.size(), 1);
- Assertions.assertTrue(((FullServiceDefinition) abstractMetadataReport.allMetadataReports.get(providerMetadataIdentifier1)).getParameters().containsKey("testPKey"));
+ assertEquals(abstractMetadataReport.allMetadataReports.size(), 1);
+ assertTrue(((FullServiceDefinition) abstractMetadataReport.allMetadataReports.get(providerMetadataIdentifier1)).getParameters().containsKey("testPKey"));
MetadataIdentifier providerMetadataIdentifier2 = storePrivider(abstractMetadataReport, interfaceName, version + "_2", group + "_2", application);
Thread.sleep(1000);
- Assertions.assertEquals(abstractMetadataReport.allMetadataReports.size(), 2);
- Assertions.assertTrue(((FullServiceDefinition) abstractMetadataReport.allMetadataReports.get(providerMetadataIdentifier2)).getParameters().containsKey("testPKey"));
- Assertions.assertEquals(((FullServiceDefinition) abstractMetadataReport.allMetadataReports.get(providerMetadataIdentifier2)).getParameters().get("version"), version + "_2");
+ assertEquals(abstractMetadataReport.allMetadataReports.size(), 2);
+ assertTrue(((FullServiceDefinition) abstractMetadataReport.allMetadataReports.get(providerMetadataIdentifier2)).getParameters().containsKey("testPKey"));
+ assertEquals(((FullServiceDefinition) abstractMetadataReport.allMetadataReports.get(providerMetadataIdentifier2)).getParameters().get("version"), version + "_2");
Map tmpMap = new HashMap<>();
tmpMap.put("testKey", "value");
MetadataIdentifier consumerMetadataIdentifier = storeConsumer(abstractMetadataReport, interfaceName, version + "_3", group + "_3", application, tmpMap);
Thread.sleep(1000);
- Assertions.assertEquals(abstractMetadataReport.allMetadataReports.size(), 3);
+ assertEquals(abstractMetadataReport.allMetadataReports.size(), 3);
Map tmpMapResult = (Map) abstractMetadataReport.allMetadataReports.get(consumerMetadataIdentifier);
- Assertions.assertEquals(tmpMapResult.get("testPKey"), "9090");
- Assertions.assertEquals(tmpMapResult.get("testKey"), "value");
- Assertions.assertEquals(3, abstractMetadataReport.store.size());
+ assertEquals(tmpMapResult.get("testPKey"), "9090");
+ assertEquals(tmpMapResult.get("testKey"), "value");
+ assertEquals(3, abstractMetadataReport.store.size());
abstractMetadataReport.store.clear();
- Assertions.assertEquals(0, abstractMetadataReport.store.size());
+ assertEquals(0, abstractMetadataReport.store.size());
abstractMetadataReport.publishAll();
Thread.sleep(200);
- Assertions.assertEquals(3, abstractMetadataReport.store.size());
+ assertEquals(3, abstractMetadataReport.store.size());
String v = abstractMetadataReport.store.get(providerMetadataIdentifier1.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
Gson gson = new Gson();
@@ -244,11 +261,53 @@ public void testCalculateStartTime() {
long t = abstractMetadataReport.calculateStartTime() + System.currentTimeMillis();
Calendar c = Calendar.getInstance();
c.setTimeInMillis(t);
- Assertions.assertTrue(c.get(Calendar.HOUR_OF_DAY) >= 2);
- Assertions.assertTrue(c.get(Calendar.HOUR_OF_DAY) <= 6);
+ assertTrue(c.get(Calendar.HOUR_OF_DAY) >= 2);
+ assertTrue(c.get(Calendar.HOUR_OF_DAY) <= 6);
}
}
+ /**
+ * Test {@link MetadataReport#saveExportedURLs(String, String, String)} method
+ *
+ * @since 2.7.8
+ */
+ @Test
+ public void testSaveExportedURLs() {
+ String serviceName = null;
+ String exportedServiceRevision = null;
+ String exportedURLsContent = null;
+ SortedSet exportedURLs = null;
+ // Default methods return true
+ assertTrue(abstractMetadataReport.saveExportedURLs(exportedURLs));
+ assertTrue(abstractMetadataReport.saveExportedURLs(exportedServiceRevision, exportedURLs));
+ assertTrue(abstractMetadataReport.saveExportedURLs(serviceName, exportedServiceRevision, exportedURLs));
+ assertTrue(abstractMetadataReport.saveExportedURLs(serviceName, exportedServiceRevision, exportedURLsContent));
+ }
+
+ /**
+ * Test {@link MetadataReport#getExportedURLs(String, String)} method
+ *
+ * @since 2.7.8
+ */
+ @Test
+ public void testGetExportedURLs() {
+ String serviceName = null;
+ String exportedServiceRevision = null;
+ assertEquals(emptySet(), abstractMetadataReport.getExportedURLs(serviceName, exportedServiceRevision));
+ }
+
+ /**
+ * Test {@link MetadataReport#getExportedURLsContent(String, String)} method
+ *
+ * @since 2.7.8
+ */
+ @Test
+ public void testGetExportedURLsContent() {
+ String serviceName = null;
+ String exportedServiceRevision = null;
+ assertNull(abstractMetadataReport.getExportedURLsContent(serviceName, exportedServiceRevision));
+ }
+
private FullServiceDefinition toServiceDefinition(String v) {
Gson gson = new Gson();
FullServiceDefinition data = gson.fromJson(v, FullServiceDefinition.class);
@@ -256,8 +315,8 @@ private FullServiceDefinition toServiceDefinition(String v) {
}
private void checkParam(Map map, String application, String version) {
- Assertions.assertEquals(map.get("application"), application);
- Assertions.assertEquals(map.get("version"), version);
+ assertEquals(map.get("application"), application);
+ assertEquals(map.get("version"), version);
}
private Map queryUrlToMap(String urlQuery) {
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReportTest.java
new file mode 100644
index 00000000000..32205b9a1fd
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/ConfigCenterBasedMetadataReportTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.metadata.report.support;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.metadata.URLRevisionResolver;
+import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.apache.dubbo.metadata.report.support.file.FileSystemMetadataReportFactory;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.service.EchoService;
+
+import com.google.gson.Gson;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import static java.util.Collections.singleton;
+import static java.util.stream.Collectors.toSet;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
+import static org.apache.dubbo.metadata.report.support.Constants.SYNC_REPORT_KEY;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * {@link ConfigCenterBasedMetadataReport} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class ConfigCenterBasedMetadataReportTest {
+
+ private static final URL REPORT_SERVER_URL = URL.valueOf("file://")
+ .addParameter(APPLICATION_KEY, "test")
+ .addParameter(SYNC_REPORT_KEY, "true");
+
+ private static final Class INTERFACE_CLASS = EchoService.class;
+
+ private static final String INTERFACE_NAME = INTERFACE_CLASS.getName();
+
+ private static final String APP_NAME = "test-service";
+
+ private static final URL BASE_URL = URL
+ .valueOf("dubbo://127.0.0.1:20880")
+ .setPath(INTERFACE_NAME)
+ .addParameter(APPLICATION_KEY, APP_NAME)
+ .addParameter(SIDE_KEY, "provider");
+
+ private ConfigCenterBasedMetadataReport metadataReport;
+
+ @BeforeEach
+ public void init() {
+ ApplicationModel.getConfigManager().setApplication(new ApplicationConfig("test-service"));
+ this.metadataReport = new FileSystemMetadataReportFactory().getMetadataReport(REPORT_SERVER_URL);
+ }
+
+ @AfterEach
+ public void reset() throws Exception {
+ ApplicationModel.reset();
+ this.metadataReport.close();
+ }
+
+ /**
+ * Test {@link MetadataReport#storeProviderMetadata(MetadataIdentifier, ServiceDefinition)} and
+ * {@link MetadataReport#getServiceDefinition(MetadataIdentifier)}
+ */
+ @Test
+ public void testStoreProviderMetadataAndGetServiceDefinition() {
+ MetadataIdentifier metadataIdentifier = new MetadataIdentifier(BASE_URL);
+ ServiceDefinition serviceDefinition = ServiceDefinitionBuilder.buildFullDefinition(INTERFACE_CLASS, BASE_URL.getParameters());
+ metadataReport.storeProviderMetadata(metadataIdentifier, serviceDefinition);
+ String serviceDefinitionJSON = metadataReport.getServiceDefinition(metadataIdentifier);
+ assertEquals(serviceDefinitionJSON, new Gson().toJson(serviceDefinition));
+ }
+
+ /**
+ * Test {@link MetadataReport#storeConsumerMetadata(MetadataIdentifier, Map)} and
+ * {@link MetadataReport#getServiceDefinition(MetadataIdentifier)}
+ */
+ @Test
+ public void testStoreConsumerMetadata() {
+ MetadataIdentifier metadataIdentifier = new MetadataIdentifier(BASE_URL);
+ metadataReport.storeConsumerMetadata(metadataIdentifier, BASE_URL.getParameters());
+ String parametersJSON = metadataReport.getServiceDefinition(metadataIdentifier);
+ assertEquals(parametersJSON, new Gson().toJson(BASE_URL.getParameters()));
+ }
+
+ /**
+ * Test {@link MetadataReport#saveServiceMetadata(ServiceMetadataIdentifier, URL)} and
+ * {@link MetadataReport#removeServiceMetadata(ServiceMetadataIdentifier)}
+ */
+ @Test
+ public void testSaveServiceMetadataAndRemoveServiceMetadata() {
+ ServiceMetadataIdentifier metadataIdentifier = new ServiceMetadataIdentifier(BASE_URL);
+ metadataReport.saveServiceMetadata(metadataIdentifier, BASE_URL);
+ String metadata = metadataReport.getMetadata(metadataIdentifier);
+ assertEquals(URL.encode(BASE_URL.toFullString()), metadata);
+ metadataReport.removeServiceMetadata(metadataIdentifier);
+ assertNull(metadataReport.getMetadata(metadataIdentifier));
+ }
+
+ /**
+ * Test {@link MetadataReport#saveSubscribedData(SubscriberMetadataIdentifier, Collection)} and
+ * {@link MetadataReport#getSubscribedURLs(SubscriberMetadataIdentifier)}
+ */
+ @Test
+ public void testSaveSubscribedDataAndGetSubscribedURLs() {
+ SubscriberMetadataIdentifier metadataIdentifier = new SubscriberMetadataIdentifier(BASE_URL);
+ Set urls = singleton(BASE_URL).stream().map(URL::toIdentityString).collect(toSet());
+ metadataReport.saveSubscribedData(metadataIdentifier, urls);
+ Collection subscribedURLs = metadataReport.getSubscribedURLs(metadataIdentifier);
+ assertEquals(1, subscribedURLs.size());
+ assertEquals(urls, subscribedURLs);
+ }
+
+ /**
+ * Test {@link MetadataReport#saveExportedURLs(SortedSet)},
+ * {@link MetadataReport#getExportedURLsContent(String, String)} and
+ * {@link MetadataReport#getExportedURLs(String, String)}
+ */
+ @Test
+ public void testSaveExportedURLsAndGetExportedURLs() {
+ SortedSet urls = singleton(BASE_URL).stream().map(URL::toIdentityString).collect(TreeSet::new, Set::add, Set::addAll);
+ metadataReport.saveExportedURLs(urls);
+
+ URLRevisionResolver urlRevisionResolver = URLRevisionResolver.INSTANCE;
+ String revision = urlRevisionResolver.resolve(urls);
+ assertEquals(urls, metadataReport.getExportedURLs(APP_NAME, revision));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java
index 199564443b0..b7db3fb111f 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java
@@ -68,8 +68,8 @@ public void testExportURL() {
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test567Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.exportURL(url);
- Assertions.assertTrue(inMemoryWritableMetadataService.exportedServiceURLs.size() == 1);
- Assertions.assertEquals(inMemoryWritableMetadataService.exportedServiceURLs.get(url.getServiceKey()).first(), url);
+ Assertions.assertTrue(inMemoryWritableMetadataService.getExportedServiceURLs().size() == 1);
+ Assertions.assertEquals(inMemoryWritableMetadataService.getExportedServiceURLs().get(url.getServiceKey()).first(), url);
}
@Test
@@ -78,8 +78,8 @@ public void testSubscribeURL() {
URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test678Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.subscribeURL(url);
- Assertions.assertTrue(inMemoryWritableMetadataService.subscribedServiceURLs.size() == 1);
- Assertions.assertEquals(inMemoryWritableMetadataService.subscribedServiceURLs.get(url.getServiceKey()).first(), url);
+ Assertions.assertTrue(inMemoryWritableMetadataService.getSubscribedServiceURLs().size() == 1);
+ Assertions.assertEquals(inMemoryWritableMetadataService.getSubscribedServiceURLs().get(url.getServiceKey()).first(), url);
}
@Test
@@ -88,11 +88,11 @@ public void testUnExportURL() {
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test567Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.exportURL(url);
- Assertions.assertTrue(inMemoryWritableMetadataService.exportedServiceURLs.size() == 1);
- Assertions.assertEquals(inMemoryWritableMetadataService.exportedServiceURLs.get(url.getServiceKey()).first(), url);
+ Assertions.assertTrue(inMemoryWritableMetadataService.getExportedServiceURLs().size() == 1);
+ Assertions.assertEquals(inMemoryWritableMetadataService.getExportedServiceURLs().get(url.getServiceKey()).first(), url);
inMemoryWritableMetadataService.unexportURL(url);
- Assertions.assertTrue(inMemoryWritableMetadataService.exportedServiceURLs.size() == 0);
+ Assertions.assertTrue(inMemoryWritableMetadataService.getExportedServiceURLs().size() == 0);
}
@Test
@@ -101,11 +101,11 @@ public void testUnSubscribeURL() {
URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test678Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.subscribeURL(url);
- Assertions.assertTrue(inMemoryWritableMetadataService.subscribedServiceURLs.size() == 1);
- Assertions.assertEquals(inMemoryWritableMetadataService.subscribedServiceURLs.get(url.getServiceKey()).first(), url);
+ Assertions.assertTrue(inMemoryWritableMetadataService.getSubscribedServiceURLs().size() == 1);
+ Assertions.assertEquals(inMemoryWritableMetadataService.getSubscribedServiceURLs().get(url.getServiceKey()).first(), url);
inMemoryWritableMetadataService.unsubscribeURL(url);
- Assertions.assertTrue(inMemoryWritableMetadataService.subscribedServiceURLs.size() == 0);
+ Assertions.assertTrue(inMemoryWritableMetadataService.getSubscribedServiceURLs().size() == 0);
}
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegateTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegateTest.java
deleted file mode 100644
index 8db9534136e..00000000000
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegateTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * 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.metadata.store;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.metadata.report.MetadataReportInstance;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.metadata.test.JTestMetadataReport4Test;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.SortedSet;
-
-
-/**
- * 2019-08-27
- */
-public class RemoteWritableMetadataServiceDelegateTest {
- static URL metadataURL = URL.valueOf("JTest://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Tes33tService?version=1.0.0&application=vic");
-
- RemoteWritableMetadataServiceDelegate metadataReportService;
-
- String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService80", version = "0.6.9", group = null;
- URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/?interface=" + interfaceName + "&version="
- + version + "&application=vicpubprovder&side=provider");
-
- @BeforeAll
- public static void beforeAll() {
- MetadataReportInstance.init(metadataURL);
- }
-
- @BeforeEach
- public void before() {
- metadataReportService = new RemoteWritableMetadataServiceDelegate();
- }
-
-
- @Test
- public void testInstance() {
- WritableMetadataService metadataReportService1 = WritableMetadataService.getExtension("remote");
- WritableMetadataService metadataReportService2 = WritableMetadataService.getExtension("remote");
- Assertions.assertSame(metadataReportService1, metadataReportService2);
- Assertions.assertTrue(metadataReportService1 instanceof RemoteWritableMetadataServiceDelegate);
- }
-
- @Test
- public void testPublishServiceDefinition() throws InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService2", version = "0.9.9", group = null;
- URL tmpUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/?interface=" + interfaceName + "&version="
- + version + "&application=vicpubprovder&side=provider");
- metadataReportService.publishServiceDefinition(tmpUrl);
- Thread.sleep(150);
- String v = metadataReportService.getServiceDefinition(interfaceName, version, group);
- Assertions.assertNotNull(v);
- }
-
- @Test
- public void testExportURL() throws InterruptedException {
- URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test567Service?version=1.0.44&application=vicpubprovder&side=provider");
- metadataReportService.exportURL(url);
- Thread.sleep(100);
- Assertions.assertTrue(getInMemoryWriableMetadataService().exportedServiceURLs.size() == 1);
- Assertions.assertEquals(getInMemoryWriableMetadataService().exportedServiceURLs.get(url.getServiceKey()).first(), url);
- }
-
- @Test
- public void testSubscribeURL() throws InterruptedException {
- URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test0678Service?version=1.3.144&application=vicpubprovder&side=provider");
- int origSize = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
- metadataReportService.subscribeURL(url);
- Thread.sleep(100);
- int size = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
- Assertions.assertTrue(size - origSize == 1);
- Assertions.assertEquals(getInMemoryWriableMetadataService().subscribedServiceURLs.get(url.getServiceKey()).first(), url);
- }
-
- @Test
- public void testUnExportURL() throws InterruptedException {
- URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test0567Service?version=1.2.44&application=vicpubprovder&side=provider");
- int origSize = getInMemoryWriableMetadataService().exportedServiceURLs.size();
- metadataReportService.exportURL(url);
- Thread.sleep(100);
- int size = getInMemoryWriableMetadataService().exportedServiceURLs.size();
- Assertions.assertTrue(size - origSize == 1);
- Assertions.assertEquals(getInMemoryWriableMetadataService().exportedServiceURLs.get(url.getServiceKey()).first(), url);
-
- metadataReportService.unexportURL(url);
- int unexportSize = getInMemoryWriableMetadataService().exportedServiceURLs.size();
- Assertions.assertTrue(size - unexportSize == 1);
- }
-
- @Test
- public void testUnSubscribeURL() throws InterruptedException {
- URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test0678Service?version=1.5.477&application=vicpubprovder&side=provider");
- int origSize = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
- metadataReportService.subscribeURL(url);
- Thread.sleep(100);
- int size = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
- Assertions.assertTrue(size - origSize == 1);
- Assertions.assertEquals(getInMemoryWriableMetadataService().subscribedServiceURLs.get(url.getServiceKey()).first(), url);
-
- metadataReportService.unsubscribeURL(url);
- Thread.sleep(100);
- Assertions.assertTrue(getInMemoryWriableMetadataService().subscribedServiceURLs.size() == 0);
- }
-
- @Test
- public void testRefreshMetadataService() throws InterruptedException {
- URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadataService?version=1.6.8&application=vicpubprovder&side=provider");
- URL publishUrl2 = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata2Service?version=1.6.5&application=vicpubprovder&side=provider");
- metadataReportService.exportURL(publishUrl);
- metadataReportService.exportURL(publishUrl2);
- String exportedRevision = "9999";
- JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) MetadataReportInstance.getMetadataReport(true);
- int origSize = jTestMetadataReport4Test.store.size();
- int num = countNum();
- Assertions.assertTrue(metadataReportService.refreshMetadata(exportedRevision, "1109"));
- Thread.sleep(200);
- int size = jTestMetadataReport4Test.store.size();
- Assertions.assertTrue(size - origSize == num);
- Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl.toFullString());
- Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl2, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl2.toFullString());
- }
-
-
- // unstable test
-// @Test
-// public void testRefreshMetadataSubscription() throws InterruptedException {
-// URL subscriberUrl1 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata00Service?version=2.0.8&application=vicpubprovder&side=provider");
-// URL subscriberUrl2 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata09Service?version=2.0.5&application=vicpubprovder&side=provider");
-// metadataReportService.subscribeURL(subscriberUrl1);
-// metadataReportService.subscribeURL(subscriberUrl2);
-// String exportedRevision = "9999";
-// String subscriberRevision = "2099";
-// String applicationName = "wriableMetadataService";
-// JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) MetadataReportInstance.getMetadataReport(true);
-// int origSize = jTestMetadataReport4Test.store.size();
-// ApplicationModel.setApplication(applicationName);
-// Assertions.assertTrue(metadataReportService.refreshMetadata(exportedRevision, subscriberRevision));
-// Thread.sleep(200);
-// int size = jTestMetadataReport4Test.store.size();
-// Assertions.assertTrue(size - origSize == 1);
-// String r = jTestMetadataReport4Test.store.get(getSubscriberMetadataIdentifier(
-// subscriberRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-// Assertions.assertNotNull(r);
-// }
-
-
- private ServiceMetadataIdentifier getServiceMetadataIdentifier(URL publishUrl, String exportedRevision) {
- ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(publishUrl);
- serviceMetadataIdentifier.setRevision(exportedRevision);
- serviceMetadataIdentifier.setProtocol(publishUrl.getProtocol());
- return serviceMetadataIdentifier;
- }
-
- private SubscriberMetadataIdentifier getSubscriberMetadataIdentifier(String subscriberRevision) {
- SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier();
- subscriberMetadataIdentifier.setRevision(subscriberRevision);
- subscriberMetadataIdentifier.setApplication(ApplicationModel.getApplication());
- return subscriberMetadataIdentifier;
- }
-
- private InMemoryWritableMetadataService getInMemoryWriableMetadataService() {
- return (InMemoryWritableMetadataService) metadataReportService.defaultWritableMetadataService;
- }
-
- private int countNum() {
- int num = 0;
- for (SortedSet tmp : getInMemoryWriableMetadataService().exportedServiceURLs.values()) {
- num += tmp.size();
- }
- if (!getInMemoryWriableMetadataService().subscribedServiceURLs.values().isEmpty()) {
- num++;
- }
- return num;
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceTest.java
similarity index 90%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java
rename to dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceTest.java
index bdd748cf491..e9ca89f6731 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceTest.java
@@ -36,15 +36,13 @@
/**
* 2018/9/14
*/
-public class RemoteWritableMeatadataServiceTest {
+public class RemoteWritableMetadataServiceTest {
URL url = URL.valueOf("JTest://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vic");
RemoteWritableMetadataService metadataReportService1;
- InMemoryWritableMetadataService inMemoryWritableMetadataService;
@BeforeEach
public void before() {
- inMemoryWritableMetadataService = new InMemoryWritableMetadataService();
- metadataReportService1 = new RemoteWritableMetadataService(inMemoryWritableMetadataService);
+ metadataReportService1 = new RemoteWritableMetadataService();
MetadataReportInstance.init(url);
}
@@ -134,25 +132,25 @@ public void testUnexportURL() {
public void testRefreshMetadataService() throws InterruptedException {
URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadataService?version=1.0.8&application=vicpubprovder&side=provider");
URL publishUrl2 = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata2Service?version=1.0.5&application=vicpubprovder&side=provider");
- inMemoryWritableMetadataService.exportURL(publishUrl);
- inMemoryWritableMetadataService.exportURL(publishUrl2);
+ metadataReportService1.exportURL(publishUrl);
+ metadataReportService1.exportURL(publishUrl2);
String exportedRevision = "9999";
JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.getMetadataReport();
int origSize = jTestMetadataReport4Test.store.size();
Assertions.assertTrue(metadataReportService1.refreshMetadata(exportedRevision, "1109"));
Thread.sleep(200);
int size = jTestMetadataReport4Test.store.size();
- Assertions.assertTrue(size - origSize == 2);
- Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl.toFullString());
- Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl2, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl2.toFullString());
+ Assertions.assertEquals(origSize, size);
+ Assertions.assertNull(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)));
+ Assertions.assertNull(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl2, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)));
}
@Test
public void testRefreshMetadataSubscription() throws InterruptedException {
URL subscriberUrl1 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata00Service?version=1.0.8&application=vicpubprovder&side=provider");
URL subscriberUrl2 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata09Service?version=1.0.5&application=vicpubprovder&side=provider");
- inMemoryWritableMetadataService.subscribeURL(subscriberUrl1);
- inMemoryWritableMetadataService.subscribeURL(subscriberUrl2);
+ metadataReportService1.subscribeURL(subscriberUrl1);
+ metadataReportService1.subscribeURL(subscriberUrl2);
String exportedRevision = "9999";
String subscriberRevision = "2099";
String applicationName = "wriableMetadataService";
@@ -162,10 +160,10 @@ public void testRefreshMetadataSubscription() throws InterruptedException {
Assertions.assertTrue(metadataReportService1.refreshMetadata(exportedRevision, subscriberRevision));
Thread.sleep(200);
int size = jTestMetadataReport4Test.store.size();
- Assertions.assertTrue(size - origSize == 1);
+ Assertions.assertEquals(origSize, size);
String r = jTestMetadataReport4Test.store.get(getSubscriberMetadataIdentifier(
subscriberRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
- Assertions.assertNotNull(r);
+ Assertions.assertNull(r);
}
private ServiceMetadataIdentifier getServiceMetadataIdentifier(URL publishUrl, String exportedRevision) {
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/resources/META-INF/dubbo/service-name-mapping.properties b/dubbo-metadata/dubbo-metadata-api/src/test/resources/META-INF/dubbo/service-name-mapping.properties
new file mode 100644
index 00000000000..5f3863d1007
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/resources/META-INF/dubbo/service-name-mapping.properties
@@ -0,0 +1,3 @@
+dubbo\:com.acme.Interface1\:default = Service1
+thirft\:com.acme.InterfaceX = Service1,Service2
+rest\:com.acme.interfaceN = Service3
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-report-consul/pom.xml b/dubbo-metadata/dubbo-metadata-report-consul/pom.xml
index b30001a8b03..8a01b72d49c 100644
--- a/dubbo-metadata/dubbo-metadata-report-consul/pom.xml
+++ b/dubbo-metadata/dubbo-metadata-report-consul/pom.xml
@@ -16,7 +16,8 @@
~ limitations under the License.
-->
-
+
org.apache.dubbo
dubbo-metadata
@@ -33,6 +34,11 @@
dubbo-metadata-api
${project.parent.version}
+
+ org.apache.dubbo
+ dubbo-configcenter-consul
+ ${project.parent.version}
+
com.ecwid.consul
consul-api
diff --git a/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
index c1e0a309bef..e6b70542619 100644
--- a/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
@@ -27,6 +27,7 @@
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
+import org.apache.dubbo.metadata.report.support.ConfigCenterBasedMetadataReport;
import org.apache.dubbo.rpc.RpcException;
import com.ecwid.consul.v1.ConsulClient;
@@ -40,7 +41,10 @@
/**
* metadata report impl for consul
+ *
+ * @deprecated 2.7.8 This class will be removed in the future, {@link ConfigCenterBasedMetadataReport} as a substitute.
*/
+@Deprecated
public class ConsulMetadataReport extends AbstractMetadataReport {
private static final Logger logger = LoggerFactory.getLogger(ConsulMetadataReport.class);
private static final int DEFAULT_PORT = 8500;
diff --git a/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java b/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java
index 1d1f5bbd409..7f5f1901e72 100644
--- a/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java
+++ b/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java
@@ -17,16 +17,15 @@
package org.apache.dubbo.metadata.store.consul;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.metadata.report.MetadataReport;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.support.ConfigCenterBasedMetadataReportFactory;
/**
* metadata report factory impl for consul
*/
-public class ConsulMetadataReportFactory extends AbstractMetadataReportFactory {
- @Override
- protected MetadataReport createMetadataReport(URL url) {
- return new ConsulMetadataReport(url);
+public class ConsulMetadataReportFactory extends ConfigCenterBasedMetadataReportFactory {
+
+ public ConsulMetadataReportFactory() {
+ super(KeyTypeEnum.UNIQUE_KEY);
}
}
diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/pom.xml b/dubbo-metadata/dubbo-metadata-report-nacos/pom.xml
index db76cae7d4d..03211e02ec8 100644
--- a/dubbo-metadata/dubbo-metadata-report-nacos/pom.xml
+++ b/dubbo-metadata/dubbo-metadata-report-nacos/pom.xml
@@ -16,7 +16,8 @@
~ limitations under the License.
-->
-
+
org.apache.dubbo
dubbo-metadata
@@ -33,9 +34,11 @@
dubbo-metadata-api
${project.parent.version}
+
- com.alibaba.nacos
- nacos-client
+ org.apache.dubbo
+ dubbo-configcenter-nacos
+ ${project.parent.version}
diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
index 707d2b8261c..5c413d8fb0a 100644
--- a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
@@ -18,6 +18,7 @@
package org.apache.dubbo.metadata.store.nacos;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.StringUtils;
@@ -27,132 +28,36 @@
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
+import org.apache.dubbo.metadata.report.support.ConfigCenterBasedMetadataReport;
import org.apache.dubbo.rpc.RpcException;
-import com.alibaba.nacos.api.NacosFactory;
-import com.alibaba.nacos.api.config.ConfigService;
-import com.alibaba.nacos.api.exception.NacosException;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Properties;
-
-import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONFIG_RETRY_TIME;
-import static com.alibaba.nacos.api.PropertyKeyConst.CONTEXT_PATH;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
-import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING;
-import static com.alibaba.nacos.api.PropertyKeyConst.IS_USE_ENDPOINT_PARSING_RULE;
-import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_CLIENT_BEAT_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
-import static com.alibaba.nacos.api.PropertyKeyConst.NAMING_POLLING_THREAD_COUNT;
-import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
-import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
-import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
-import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
/**
* metadata report impl for nacos
+ *
+ * @deprecated 2.7.8 This class will be removed in the future, {@link ConfigCenterBasedMetadataReport} as a substitute.
*/
+@Deprecated
public class NacosMetadataReport extends AbstractMetadataReport {
private static final Logger logger = LoggerFactory.getLogger(NacosMetadataReport.class);
- private ConfigService configService;
+ private final DynamicConfiguration dynamicConfiguration;
/**
* The group used to store metadata in Nacos
*/
private String group;
-
- public NacosMetadataReport(URL url) {
+ public NacosMetadataReport(URL url, DynamicConfiguration dynamicConfiguration) {
super(url);
- this.configService = buildConfigService(url);
- group = url.getParameter(GROUP_KEY, DEFAULT_ROOT);
- }
-
- public ConfigService buildConfigService(URL url) {
- Properties nacosProperties = buildNacosProperties(url);
- try {
- configService = NacosFactory.createConfigService(nacosProperties);
- } catch (NacosException e) {
- if (logger.isErrorEnabled()) {
- logger.error(e.getErrMsg(), e);
- }
- throw new IllegalStateException(e);
- }
- return configService;
- }
-
- private Properties buildNacosProperties(URL url) {
- Properties properties = new Properties();
- setServerAddr(url, properties);
- setProperties(url, properties);
- return properties;
- }
-
- private void setServerAddr(URL url, Properties properties) {
- StringBuilder serverAddrBuilder =
- new StringBuilder(url.getHost()) // Host
- .append(":")
- .append(url.getPort()); // Port
- // Append backup parameter as other servers
- String backup = url.getParameter(BACKUP_KEY);
- if (backup != null) {
- serverAddrBuilder.append(",").append(backup);
- }
- String serverAddr = serverAddrBuilder.toString();
- properties.put(SERVER_ADDR, serverAddr);
- }
-
- private static void setProperties(URL url, Properties properties) {
- putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
- putPropertyIfAbsent(url, properties, IS_USE_CLOUD_NAMESPACE_PARSING);
- putPropertyIfAbsent(url, properties, IS_USE_ENDPOINT_PARSING_RULE);
- putPropertyIfAbsent(url, properties, ENDPOINT);
- putPropertyIfAbsent(url, properties, ENDPOINT_PORT);
- putPropertyIfAbsent(url, properties, NAMESPACE);
- putPropertyIfAbsent(url, properties, ACCESS_KEY);
- putPropertyIfAbsent(url, properties, SECRET_KEY);
- putPropertyIfAbsent(url, properties, RAM_ROLE_NAME);
- putPropertyIfAbsent(url, properties, CONTEXT_PATH);
- putPropertyIfAbsent(url, properties, CLUSTER_NAME);
- putPropertyIfAbsent(url, properties, ENCODE);
- putPropertyIfAbsent(url, properties, CONFIG_LONG_POLL_TIMEOUT);
- putPropertyIfAbsent(url, properties, CONFIG_RETRY_TIME);
- putPropertyIfAbsent(url, properties, MAX_RETRY);
- putPropertyIfAbsent(url, properties, ENABLE_REMOTE_SYNC_CONFIG);
- putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, "true");
- putPropertyIfAbsent(url, properties, NAMING_CLIENT_BEAT_THREAD_COUNT);
- putPropertyIfAbsent(url, properties, NAMING_POLLING_THREAD_COUNT);
- }
-
- private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
- String propertyValue = url.getParameter(propertyName);
- if (StringUtils.isNotEmpty(propertyValue)) {
- properties.setProperty(propertyName, propertyValue);
- }
- }
-
- private static void putPropertyIfAbsent(URL url, Properties properties, String propertyName, String defaultValue) {
- String propertyValue = url.getParameter(propertyName);
- if (StringUtils.isNotEmpty(propertyValue)) {
- properties.setProperty(propertyName, propertyValue);
- } else {
- properties.setProperty(propertyName, defaultValue);
- }
+ this.dynamicConfiguration = dynamicConfiguration;
}
@Override
@@ -199,9 +104,19 @@ public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
return getConfig(metadataIdentifier);
}
+ @Override
+ public boolean saveExportedURLs(String serviceName, String exportedServicesRevision, String exportedURLsContent) {
+ return dynamicConfiguration.publishConfig(serviceName, exportedServicesRevision, exportedURLsContent);
+ }
+
+ @Override
+ public String getExportedURLsContent(String serviceName, String exportedServicesRevision) {
+ return dynamicConfiguration.getConfig(serviceName, exportedServicesRevision, SECONDS.toMillis(3));
+ }
+
private void storeMetadata(BaseMetadataIdentifier identifier, String value) {
try {
- boolean publishResult = configService.publishConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, value);
+ boolean publishResult = dynamicConfiguration.publishConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, value);
if (!publishResult) {
throw new RuntimeException("publish nacos metadata failed");
}
@@ -213,7 +128,7 @@ private void storeMetadata(BaseMetadataIdentifier identifier, String value) {
private void deleteMetadata(BaseMetadataIdentifier identifier) {
try {
- boolean publishResult = configService.removeConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group);
+ boolean publishResult = dynamicConfiguration.removeConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group);
if (!publishResult) {
throw new RuntimeException("remove nacos metadata failed");
}
@@ -225,7 +140,7 @@ private void deleteMetadata(BaseMetadataIdentifier identifier) {
private String getConfig(BaseMetadataIdentifier identifier) {
try {
- return configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, 300);
+ return dynamicConfiguration.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, 300);
} catch (Throwable t) {
logger.error("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
throw new RpcException("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java
index 2cff74c9a1b..8c8d5a2efae 100644
--- a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java
+++ b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportFactory.java
@@ -17,16 +17,15 @@
package org.apache.dubbo.metadata.store.nacos;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.metadata.report.MetadataReport;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.support.ConfigCenterBasedMetadataReportFactory;
/**
* metadata report factory impl for nacos
*/
-public class NacosMetadataReportFactory extends AbstractMetadataReportFactory {
- @Override
- protected MetadataReport createMetadataReport(URL url) {
- return new NacosMetadataReport(url);
+public class NacosMetadataReportFactory extends ConfigCenterBasedMetadataReportFactory {
+
+ public NacosMetadataReportFactory() {
+ super(KeyTypeEnum.UNIQUE_KEY);
}
}
diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java
deleted file mode 100644
index 88fc75ab5a4..00000000000
--- a/dubbo-metadata/dubbo-metadata-report-nacos/src/test/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReportTest.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.metadata.store.nacos;
-
-import com.alibaba.nacos.api.exception.NacosException;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-
-import com.alibaba.nacos.api.config.ConfigService;
-import com.google.gson.Gson;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-
-//FIXME: waiting for embedded Nacos suport, then we can open the switch.
-@Disabled("https://github.com/alibaba/nacos/issues/1188")
-public class NacosMetadataReportTest {
-
- private static final String SESSION_TIMEOUT_KEY = "session";
-
- private static final String TEST_SERVICE = "org.apache.dubbo.metadata.store.nacos.NacosMetadata4TstService";
-
- private NacosMetadataReport nacosMetadataReport;
-
- private NacosMetadataReportFactory nacosMetadataReportFactory;
-
- private ConfigService configService;
-
- private static final String NACOS_GROUP = "metadata_test";
-
- /**
- * timeout(ms) for nacos session
- */
- private static final int SESSION_TIMEOUT = 15 * 1000;
-
- /**
- * timeout(ms) for query operation on nacos
- */
- private static final int NACOS_READ_TIMEOUT = 5 * 1000;
-
- /**
- * interval(ms) to make nacos cache refresh
- */
- private static final int INTERVAL_TO_MAKE_NACOS_REFRESH = 1000;
-
- /**
- * version for test
- */
- private static final String VERSION = "1.0.0";
-
- /**
- * group for test
- */
- private static final String METADATA_GROUP = null;
-
- /**
- * application name for test
- */
- private static final String APPLICATION_NAME = "nacos-metdata-report-test";
-
- /**
- * revision for test
- */
- private static final String REVISION = "90980";
-
- /**
- * protocol for test
- */
- private static final String PROTOCOL = "xxx";
-
- @BeforeEach
- public void setUp() {
- URL url = URL.valueOf("nacos://127.0.0.1:8848?group=" + NACOS_GROUP)
- .addParameter(SESSION_TIMEOUT_KEY, SESSION_TIMEOUT);
- nacosMetadataReportFactory = new NacosMetadataReportFactory();
- this.nacosMetadataReport = (NacosMetadataReport) nacosMetadataReportFactory.createMetadataReport(url);
- this.configService = nacosMetadataReport.buildConfigService(url);
- }
-
- @AfterEach
- public void tearDown() throws Exception {
- }
-
-
- @Test
- public void testStoreProvider() throws Exception {
- MetadataIdentifier providerIdentifier =
- storeProvider(nacosMetadataReport, TEST_SERVICE, VERSION, METADATA_GROUP, APPLICATION_NAME);
- String serverContent = configService.getConfig(providerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
- Assertions.assertNotNull(serverContent);
-
- Gson gson = new Gson();
- FullServiceDefinition fullServiceDefinition = gson.fromJson(serverContent, FullServiceDefinition.class);
- Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "nacosTest");
-
- //Clear test data
- configService.removeConfig(providerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
- }
-
- @Test
- public void testStoreConsumer() throws Exception {
- MetadataIdentifier consumerIdentifier = storeConsumer(nacosMetadataReport, TEST_SERVICE, VERSION, METADATA_GROUP, APPLICATION_NAME);
-
- String serverContent = configService.getConfig(consumerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
- Assertions.assertNotNull(serverContent);
- Assertions.assertEquals(serverContent, "{\"paramConsumerTest\":\"nacosConsumer\"}");
-
- //clear test data
- configService.removeConfig(consumerIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
- }
-
- @Test
- public void testDoSaveServiceMetadata() throws Exception {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
- "?paramTest=nacosTest&version=" + VERSION + "&application="
- + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
- ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
- METADATA_GROUP, "provider", REVISION, PROTOCOL);
- nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
- Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
- String serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
- Assertions.assertNotNull(serviceMetaData);
- Assertions.assertEquals(serviceMetaData, URL.encode(url.toFullString()));
-
- //clear test data
- configService.removeConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
- }
-
- @Test
- public void testDoRemoveServiceMetadata() throws Exception {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
- "?paramTest=nacosTest&version=" + VERSION + "&application="
- + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
- ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
- METADATA_GROUP, "provider", REVISION, PROTOCOL);
- nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
- Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
- String serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
- Assertions.assertNotNull(serviceMetaData);
-
- nacosMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
- Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
- serviceMetaData = configService.getConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
- Assertions.assertNull(serviceMetaData);
- }
-
- @Test
- public void testDoGetExportedURLs() throws InterruptedException, NacosException {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
- "?paramTest=nacosTest&version=" + VERSION + "&application="
- + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
- ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, VERSION,
- METADATA_GROUP, "provider", REVISION, PROTOCOL);
-
- nacosMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
- Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-
- List exportedURLs = nacosMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
- Assertions.assertTrue(exportedURLs.size() == 1);
-
- String exportedUrl = exportedURLs.get(0);
- Assertions.assertNotNull(exportedUrl);
- Assertions.assertEquals(exportedUrl, url.toFullString());
-
- //clear test data
- configService.removeConfig(serviceMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
- }
-
- @Test
- public void testDoSaveSubscriberData() throws InterruptedException, NacosException {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + TEST_SERVICE +
- "?paramTest=nacosTest&version=" + VERSION + "&application="
- + APPLICATION_NAME + (METADATA_GROUP == null ? "" : "&group=" + METADATA_GROUP));
- SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(APPLICATION_NAME, REVISION);
- Gson gson = new Gson();
- String urlListJsonString = gson.toJson(Arrays.asList(url));
- nacosMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, urlListJsonString);
- Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
-
- String subscriberMetadata = configService.getConfig(subscriberMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP, NACOS_READ_TIMEOUT);
- Assertions.assertNotNull(subscriberMetadata);
- Assertions.assertEquals(subscriberMetadata, urlListJsonString);
-
- //clear test data
- configService.removeConfig(subscriberMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), NACOS_GROUP);
-
- }
-
- private MetadataIdentifier storeProvider(NacosMetadataReport nacosMetadataReport, String interfaceName, String version,
- String group, String application)
- throws ClassNotFoundException, InterruptedException {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName +
- "?paramTest=nacosTest&version=" + version + "&application="
- + application + (group == null ? "" : "&group=" + group));
-
- MetadataIdentifier providerMetadataIdentifier =
- new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
- Class interfaceClass = Class.forName(interfaceName);
- FullServiceDefinition fullServiceDefinition =
- ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
-
- nacosMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
- Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
- return providerMetadataIdentifier;
- }
-
- private MetadataIdentifier storeConsumer(NacosMetadataReport nacosMetadataReport, String interfaceName,
- String version, String group, String application) throws InterruptedException {
- MetadataIdentifier consumerIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
- Map tmp = new HashMap<>();
- tmp.put("paramConsumerTest", "nacosConsumer");
- nacosMetadataReport.storeConsumerMetadata(consumerIdentifier, tmp);
- Thread.sleep(INTERVAL_TO_MAKE_NACOS_REFRESH);
- return consumerIdentifier;
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-report-zookeeper/pom.xml b/dubbo-metadata/dubbo-metadata-report-zookeeper/pom.xml
index 89a5f9c3dfc..fa614a09f0a 100644
--- a/dubbo-metadata/dubbo-metadata-report-zookeeper/pom.xml
+++ b/dubbo-metadata/dubbo-metadata-report-zookeeper/pom.xml
@@ -34,7 +34,7 @@
org.apache.dubbo
- dubbo-remoting-zookeeper
+ dubbo-configcenter-zookeeper
${project.parent.version}
diff --git a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
index 9ca2e42024a..3a74f8dbfc1 100644
--- a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
@@ -19,6 +19,7 @@
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.PathUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
@@ -26,6 +27,7 @@
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
+import org.apache.dubbo.metadata.report.support.ConfigCenterBasedMetadataReport;
import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
@@ -36,10 +38,15 @@
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
+import static org.apache.dubbo.metadata.MetadataConstants.DEFAULT_PATH_TAG;
+import static org.apache.dubbo.metadata.MetadataConstants.EXPORTED_URLS_TAG;
/**
* ZookeeperMetadataReport
+ *
+ * @deprecated 2.7.8 This class will be removed in the future, {@link ConfigCenterBasedMetadataReport} as a substitute.
*/
+@Deprecated
public class ZookeeperMetadataReport extends AbstractMetadataReport {
private final static Logger logger = LoggerFactory.getLogger(ZookeeperMetadataReport.class);
@@ -120,4 +127,26 @@ String getNodePath(BaseMetadataIdentifier metadataIdentifier) {
return toRootDir() + metadataIdentifier.getUniqueKey(KeyTypeEnum.PATH);
}
+ @Override
+ public boolean saveExportedURLs(String serviceName, String exportedServicesRevision, String exportedURLsContent) {
+ String path = buildExportedURLsMetadataPath(serviceName, exportedServicesRevision);
+ zkClient.create(path, exportedURLsContent, false);
+ return true;
+ }
+
+ @Override
+ public String getExportedURLsContent(String serviceName, String exportedServicesRevision) {
+ String path = buildExportedURLsMetadataPath(serviceName, exportedServicesRevision);
+ String content = zkClient.getContent(path);
+ return content;
+ }
+
+ private String buildExportedURLsMetadataPath(String serviceName, String exportedServicesRevision) {
+ return buildPath(DEFAULT_PATH_TAG, EXPORTED_URLS_TAG, serviceName, exportedServicesRevision);
+ }
+
+ private String buildPath(String... paths) {
+ return PathUtils.buildPath(toRootDir(), paths);
+ }
+
}
diff --git a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportFactory.java b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportFactory.java
index 0ffed8db8e9..4773e1eb77b 100644
--- a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportFactory.java
+++ b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportFactory.java
@@ -16,25 +16,17 @@
*/
package org.apache.dubbo.metadata.store.zookeeper;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.metadata.report.MetadataReport;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
+import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+import org.apache.dubbo.metadata.report.support.ConfigCenterBasedMetadataReportFactory;
/**
* ZookeeperRegistryFactory.
+ *
+ * @revised 2.7.8 {@link ConfigCenterBasedMetadataReportFactory}
*/
-public class ZookeeperMetadataReportFactory extends AbstractMetadataReportFactory {
-
- private ZookeeperTransporter zookeeperTransporter;
+public class ZookeeperMetadataReportFactory extends ConfigCenterBasedMetadataReportFactory {
- public void setZookeeperTransporter(ZookeeperTransporter zookeeperTransporter) {
- this.zookeeperTransporter = zookeeperTransporter;
+ public ZookeeperMetadataReportFactory() {
+ super(KeyTypeEnum.PATH);
}
-
- @Override
- public MetadataReport createMetadataReport(URL url) {
- return new ZookeeperMetadataReport(url, zookeeperTransporter);
- }
-
}
diff --git a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
index 454f25ed13a..4e6ae3d82db 100644
--- a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
+++ b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
@@ -1,277 +1,276 @@
-/*
- * 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.metadata.store.zookeeper;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter;
-
-import com.google.gson.Gson;
-import org.apache.curator.test.TestingServer;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-
-/**
- * 2018/10/9
- */
-public class ZookeeperMetadataReportTest {
- private TestingServer zkServer;
- private ZookeeperMetadataReport zookeeperMetadataReport;
- private URL registryUrl;
- private ZookeeperMetadataReportFactory zookeeperMetadataReportFactory;
-
- @BeforeEach
- public void setUp() throws Exception {
- int zkServerPort = NetUtils.getAvailablePort();
- this.zkServer = new TestingServer(zkServerPort, true);
- this.registryUrl = URL.valueOf("zookeeper://localhost:" + zkServerPort);
-
- zookeeperMetadataReportFactory = new ZookeeperMetadataReportFactory();
- zookeeperMetadataReportFactory.setZookeeperTransporter(new CuratorZookeeperTransporter());
- this.zookeeperMetadataReport = (ZookeeperMetadataReport) zookeeperMetadataReportFactory.createMetadataReport(registryUrl);
- }
-
- @AfterEach
- public void tearDown() throws Exception {
- zkServer.stop();
- }
-
- private void deletePath(MetadataIdentifier metadataIdentifier, ZookeeperMetadataReport zookeeperMetadataReport) {
- String category = zookeeperMetadataReport.toRootDir() + metadataIdentifier.getUniqueKey(KeyTypeEnum.PATH);
- zookeeperMetadataReport.zkClient.delete(category);
- }
-
- @Test
- public void testStoreProvider() throws ClassNotFoundException, InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
- String version = "1.0.0.zk.md";
- String group = null;
- String application = "vic.zk.md";
- MetadataIdentifier providerMetadataIdentifier = storePrivider(zookeeperMetadataReport, interfaceName, version, group, application);
-
- String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
- fileContent = waitSeconds(fileContent, 3500, zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
- Assertions.assertNotNull(fileContent);
-
- deletePath(providerMetadataIdentifier, zookeeperMetadataReport);
- fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
- fileContent = waitSeconds(fileContent, 1000, zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
- Assertions.assertNull(fileContent);
-
-
- providerMetadataIdentifier = storePrivider(zookeeperMetadataReport, interfaceName, version, group, application);
- fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
- fileContent = waitSeconds(fileContent, 3500, zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
- Assertions.assertNotNull(fileContent);
-
- Gson gson = new Gson();
- FullServiceDefinition fullServiceDefinition = gson.fromJson(fileContent, FullServiceDefinition.class);
- Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "zkTest");
- }
-
-
- @Test
- public void testConsumer() throws ClassNotFoundException, InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
- String version = "1.0.0.zk.md";
- String group = null;
- String application = "vic.zk.md";
- MetadataIdentifier consumerMetadataIdentifier = storeConsumer(zookeeperMetadataReport, interfaceName, version, group, application);
-
- String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
- fileContent = waitSeconds(fileContent, 3500, zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
- Assertions.assertNotNull(fileContent);
-
- deletePath(consumerMetadataIdentifier, zookeeperMetadataReport);
- fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
- fileContent = waitSeconds(fileContent, 1000, zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
- Assertions.assertNull(fileContent);
-
- consumerMetadataIdentifier = storeConsumer(zookeeperMetadataReport, interfaceName, version, group, application);
- fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
- fileContent = waitSeconds(fileContent, 3000, zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
- Assertions.assertNotNull(fileContent);
- Assertions.assertEquals(fileContent, "{\"paramConsumerTest\":\"zkCm\"}");
- }
-
- @Test
- public void testDoSaveMetadata() throws ExecutionException, InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
- String version = "1.0.0";
- String group = null;
- String application = "etc-metadata-report-consumer-test";
- String revision = "90980";
- String protocol = "xxx";
- URL url = generateURL(interfaceName, version, group, application);
- ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
- group, "provider", revision, protocol);
- zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-
- String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
- Assertions.assertNotNull(fileContent);
-
- Assertions.assertEquals(fileContent, URL.encode(url.toFullString()));
- }
-
- @Test
- public void testDoRemoveMetadata() throws ExecutionException, InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
- String version = "1.0.0";
- String group = null;
- String application = "etc-metadata-report-consumer-test";
- String revision = "90980";
- String protocol = "xxx";
- URL url = generateURL(interfaceName, version, group, application);
- ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
- group, "provider", revision, protocol);
- zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
- String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
-
- Assertions.assertNotNull(fileContent);
-
-
- zookeeperMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
-
- fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
- Assertions.assertNull(fileContent);
- }
-
- @Test
- public void testDoGetExportedURLs() throws ExecutionException, InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
- String version = "1.0.0";
- String group = null;
- String application = "etc-metadata-report-consumer-test";
- String revision = "90980";
- String protocol = "xxx";
- URL url = generateURL(interfaceName, version, group, application);
- ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
- group, "provider", revision, protocol);
- zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-
- List r = zookeeperMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
- Assertions.assertTrue(r.size() == 1);
-
- String fileContent = r.get(0);
- Assertions.assertNotNull(fileContent);
-
- Assertions.assertEquals(fileContent, url.toFullString());
- }
-
- @Test
- public void testDoSaveSubscriberData() throws ExecutionException, InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
- String version = "1.0.0";
- String group = null;
- String application = "etc-metadata-report-consumer-test";
- String revision = "90980";
- String protocol = "xxx";
- URL url = generateURL(interfaceName, version, group, application);
- SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
- Gson gson = new Gson();
- String r = gson.toJson(Arrays.asList(url));
- zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
-
- String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
-
- Assertions.assertNotNull(fileContent);
-
- Assertions.assertEquals(fileContent, r);
- }
-
- @Test
- public void testDoGetSubscribedURLs() throws ExecutionException, InterruptedException {
- String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
- String version = "1.0.0";
- String group = null;
- String application = "etc-metadata-report-consumer-test";
- String revision = "90980";
- String protocol = "xxx";
- URL url = generateURL(interfaceName, version, group, application);
- SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
- Gson gson = new Gson();
- String r = gson.toJson(Arrays.asList(url));
- zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
-
- String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
-
- Assertions.assertNotNull(fileContent);
-
- Assertions.assertEquals(fileContent, r);
- }
-
-
- private MetadataIdentifier storePrivider(ZookeeperMetadataReport zookeeperMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException, InterruptedException {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?paramTest=zkTest&version=" + version + "&application="
- + application + (group == null ? "" : "&group=" + group));
-
- MetadataIdentifier providerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
- Class interfaceClass = Class.forName(interfaceName);
- FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
-
- zookeeperMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
- Thread.sleep(2000);
- return providerMetadataIdentifier;
- }
-
- private MetadataIdentifier storeConsumer(ZookeeperMetadataReport zookeeperMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException, InterruptedException {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?version=" + version + "&application="
- + application + (group == null ? "" : "&group=" + group));
-
- MetadataIdentifier consumerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
- Class interfaceClass = Class.forName(interfaceName);
-
- Map tmp = new HashMap<>();
- tmp.put("paramConsumerTest", "zkCm");
- zookeeperMetadataReport.storeConsumerMetadata(consumerMetadataIdentifier, tmp);
- Thread.sleep(2000);
-
- return consumerMetadataIdentifier;
- }
-
- private String waitSeconds(String value, long moreTime, String path) throws InterruptedException {
- if (value == null) {
- Thread.sleep(moreTime);
- return zookeeperMetadataReport.zkClient.getContent(path);
- }
- return value;
- }
-
- private URL generateURL(String interfaceName, String version, String group, String application) {
- URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":8989/" + interfaceName +
- "?paramTest=etcdTest&version=" + version + "&application="
- + application + (group == null ? "" : "&group=" + group));
- return url;
- }
-}
+///*
+// * 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.metadata.store.zookeeper;
+//
+//import org.apache.dubbo.common.URL;
+//import org.apache.dubbo.common.utils.NetUtils;
+//import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
+//import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+//import org.apache.dubbo.metadata.report.MetadataReport;
+//import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
+//import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+//import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
+//import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+//
+//import com.google.gson.Gson;
+//import org.apache.curator.test.TestingServer;
+//import org.junit.jupiter.api.AfterEach;
+//import org.junit.jupiter.api.Assertions;
+//import org.junit.jupiter.api.BeforeEach;
+//import org.junit.jupiter.api.Test;
+//
+//import java.util.Arrays;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.concurrent.ExecutionException;
+//
+//import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
+//import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
+//
+///**
+// * 2018/10/9
+// */
+//public class ZookeeperMetadataReportTest {
+// private TestingServer zkServer;
+// private MetadataReport zookeeperMetadataReport;
+// private URL registryUrl;
+// private ZookeeperMetadataReportFactory zookeeperMetadataReportFactory;
+//
+// @BeforeEach
+// public void setUp() throws Exception {
+// int zkServerPort = NetUtils.getAvailablePort();
+// this.zkServer = new TestingServer(zkServerPort, true);
+// this.registryUrl = URL.valueOf("zookeeper://127.0.0.1:" + zkServerPort);
+//
+// zookeeperMetadataReportFactory = new ZookeeperMetadataReportFactory();
+// this.zookeeperMetadataReport = zookeeperMetadataReportFactory.getMetadataReport(registryUrl);
+// }
+//
+// @AfterEach
+// public void tearDown() throws Exception {
+// zkServer.stop();
+// }
+//
+// private void deletePath(MetadataIdentifier metadataIdentifier, MetadataReport zookeeperMetadataReport) {
+// String category = zookeeperMetadataReport.toRootDir() + metadataIdentifier.getUniqueKey(KeyTypeEnum.PATH);
+// zookeeperMetadataReport.zkClient.delete(category);
+// }
+//
+// @Test
+// public void testStoreProvider() throws ClassNotFoundException, InterruptedException {
+// String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
+// String version = "1.0.0.zk.md";
+// String group = null;
+// String application = "vic.zk.md";
+// MetadataIdentifier providerMetadataIdentifier = storePrivider(zookeeperMetadataReport, interfaceName, version, group, application);
+//
+// String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
+// fileContent = waitSeconds(fileContent, 3500, zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
+// Assertions.assertNotNull(fileContent);
+//
+// deletePath(providerMetadataIdentifier, zookeeperMetadataReport);
+// fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
+// fileContent = waitSeconds(fileContent, 1000, zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
+// Assertions.assertNull(fileContent);
+//
+//
+// providerMetadataIdentifier = storePrivider(zookeeperMetadataReport, interfaceName, version, group, application);
+// fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
+// fileContent = waitSeconds(fileContent, 3500, zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
+// Assertions.assertNotNull(fileContent);
+//
+// Gson gson = new Gson();
+// FullServiceDefinition fullServiceDefinition = gson.fromJson(fileContent, FullServiceDefinition.class);
+// Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "zkTest");
+// }
+//
+//
+// @Test
+// public void testConsumer() throws ClassNotFoundException, InterruptedException {
+// String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
+// String version = "1.0.0.zk.md";
+// String group = null;
+// String application = "vic.zk.md";
+// MetadataIdentifier consumerMetadataIdentifier = storeConsumer(zookeeperMetadataReport, interfaceName, version, group, application);
+//
+// String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
+// fileContent = waitSeconds(fileContent, 3500, zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
+// Assertions.assertNotNull(fileContent);
+//
+// deletePath(consumerMetadataIdentifier, zookeeperMetadataReport);
+// fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
+// fileContent = waitSeconds(fileContent, 1000, zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
+// Assertions.assertNull(fileContent);
+//
+// consumerMetadataIdentifier = storeConsumer(zookeeperMetadataReport, interfaceName, version, group, application);
+// fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
+// fileContent = waitSeconds(fileContent, 3000, zookeeperMetadataReport.getNodePath(consumerMetadataIdentifier));
+// Assertions.assertNotNull(fileContent);
+// Assertions.assertEquals(fileContent, "{\"paramConsumerTest\":\"zkCm\"}");
+// }
+//
+// @Test
+// public void testDoSaveMetadata() throws ExecutionException, InterruptedException {
+// String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
+// String version = "1.0.0";
+// String group = null;
+// String application = "etc-metadata-report-consumer-test";
+// String revision = "90980";
+// String protocol = "xxx";
+// URL url = generateURL(interfaceName, version, group, application);
+// ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
+// group, "provider", revision, protocol);
+// zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+//
+// String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
+// Assertions.assertNotNull(fileContent);
+//
+// Assertions.assertEquals(fileContent, URL.encode(url.toFullString()));
+// }
+//
+// @Test
+// public void testDoRemoveMetadata() throws ExecutionException, InterruptedException {
+// String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
+// String version = "1.0.0";
+// String group = null;
+// String application = "etc-metadata-report-consumer-test";
+// String revision = "90980";
+// String protocol = "xxx";
+// URL url = generateURL(interfaceName, version, group, application);
+// ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
+// group, "provider", revision, protocol);
+// zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+// String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
+//
+// Assertions.assertNotNull(fileContent);
+//
+//
+// zookeeperMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
+//
+// fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
+// Assertions.assertNull(fileContent);
+// }
+//
+// @Test
+// public void testDoGetExportedURLs() throws ExecutionException, InterruptedException {
+// String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
+// String version = "1.0.0";
+// String group = null;
+// String application = "etc-metadata-report-consumer-test";
+// String revision = "90980";
+// String protocol = "xxx";
+// URL url = generateURL(interfaceName, version, group, application);
+// ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
+// group, "provider", revision, protocol);
+// zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
+//
+// List r = zookeeperMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
+// Assertions.assertTrue(r.size() == 1);
+//
+// String fileContent = r.get(0);
+// Assertions.assertNotNull(fileContent);
+//
+// Assertions.assertEquals(fileContent, url.toFullString());
+// }
+//
+// @Test
+// public void testDoSaveSubscriberData() throws ExecutionException, InterruptedException {
+// String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
+// String version = "1.0.0";
+// String group = null;
+// String application = "etc-metadata-report-consumer-test";
+// String revision = "90980";
+// String protocol = "xxx";
+// URL url = generateURL(interfaceName, version, group, application);
+// SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
+// Gson gson = new Gson();
+// String r = gson.toJson(Arrays.asList(url));
+// zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
+//
+// String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
+//
+// Assertions.assertNotNull(fileContent);
+//
+// Assertions.assertEquals(fileContent, r);
+// }
+//
+// @Test
+// public void testDoGetSubscribedURLs() throws ExecutionException, InterruptedException {
+// String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
+// String version = "1.0.0";
+// String group = null;
+// String application = "etc-metadata-report-consumer-test";
+// String revision = "90980";
+// String protocol = "xxx";
+// URL url = generateURL(interfaceName, version, group, application);
+// SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
+// Gson gson = new Gson();
+// String r = gson.toJson(Arrays.asList(url));
+// zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
+//
+// String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
+//
+// Assertions.assertNotNull(fileContent);
+//
+// Assertions.assertEquals(fileContent, r);
+// }
+//
+//
+// private MetadataIdentifier storePrivider(MetadataReport zookeeperMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException, InterruptedException {
+// URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?paramTest=zkTest&version=" + version + "&application="
+// + application + (group == null ? "" : "&group=" + group));
+//
+// MetadataIdentifier providerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
+// Class interfaceClass = Class.forName(interfaceName);
+// FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
+//
+// zookeeperMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
+// Thread.sleep(2000);
+// return providerMetadataIdentifier;
+// }
+//
+// private MetadataIdentifier storeConsumer(MetadataReport zookeeperMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException, InterruptedException {
+// URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?version=" + version + "&application="
+// + application + (group == null ? "" : "&group=" + group));
+//
+// MetadataIdentifier consumerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
+// Class interfaceClass = Class.forName(interfaceName);
+//
+// Map tmp = new HashMap<>();
+// tmp.put("paramConsumerTest", "zkCm");
+// zookeeperMetadataReport.storeConsumerMetadata(consumerMetadataIdentifier, tmp);
+// Thread.sleep(2000);
+//
+// return consumerMetadataIdentifier;
+// }
+//
+// private String waitSeconds(String value, long moreTime, String path) throws InterruptedException {
+// if (value == null) {
+// Thread.sleep(moreTime);
+// return zookeeperMetadataReport.zkClient.getContent(path);
+// }
+// return value;
+// }
+//
+// private URL generateURL(String interfaceName, String version, String group, String application) {
+// URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":8989/" + interfaceName +
+// "?paramTest=etcdTest&version=" + version + "&application="
+// + application + (group == null ? "" : "&group=" + group));
+// return url;
+// }
+//}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
index 7459da153f6..db03a3cc34d 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
@@ -22,7 +22,6 @@
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.ServiceNameMapping;
@@ -57,12 +56,8 @@
import static java.lang.String.format;
import static java.util.Collections.emptyList;
-import static java.util.Collections.emptySet;
-import static java.util.Collections.unmodifiableSet;
-import static java.util.stream.Collectors.toSet;
-import static java.util.stream.Stream.of;
import static org.apache.dubbo.common.URLBuilder.from;
-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
+import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR_CHAR;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
@@ -71,6 +66,8 @@
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDED_BY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
@@ -79,7 +76,7 @@
import static org.apache.dubbo.common.function.ThrowableAction.execute;
import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
import static org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty;
-import static org.apache.dubbo.common.utils.StringUtils.isBlank;
+import static org.apache.dubbo.common.utils.StringUtils.splitToSet;
import static org.apache.dubbo.metadata.MetadataService.toURLs;
import static org.apache.dubbo.registry.client.ServiceDiscoveryFactory.getExtension;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision;
@@ -107,7 +104,7 @@
* {@link ServiceNameMapping} will help to figure out one or more services that exported correlative Dubbo services. If
* the service names can be found, the exported {@link URL URLs} will be get from the remote {@link MetadataService}
* being deployed on all {@link ServiceInstance instances} of services. The whole process runs under the
- * {@link #subscribeURLs(URL, NotifyListener, String, Collection)} method. It's very expensive to invoke
+ * {@link #subscribeURLs(URL, List, String, Collection)} method. It's very expensive to invoke
* {@link MetadataService} for each {@link ServiceInstance service instance}, thus {@link ServiceDiscoveryRegistry}
* introduces a cache to optimize the calculation with "revisions". If the revisions of N
* {@link ServiceInstance service instances} are same, {@link MetadataService} is invoked just only once, and then it
@@ -129,7 +126,7 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
private final ServiceDiscovery serviceDiscovery;
- private final Set subscribedServices;
+ private Set subscribedServices;
private final ServiceNameMapping serviceNameMapping;
@@ -151,7 +148,6 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
public ServiceDiscoveryRegistry(URL registryURL) {
super(registryURL);
this.serviceDiscovery = createServiceDiscovery(registryURL);
- this.subscribedServices = parseServices(registryURL.getParameter(SUBSCRIBED_SERVICE_NAMES_KEY));
this.serviceNameMapping = ServiceNameMapping.getDefaultExtension();
String metadataStorageType = getMetadataStorageType(registryURL);
this.writableMetadataService = WritableMetadataService.getExtension(metadataStorageType);
@@ -169,12 +165,7 @@ public ServiceDiscovery getServiceDiscovery() {
* @return non-null
*/
public static Set getSubscribedServices(URL registryURL) {
- String subscribedServiceNames = registryURL.getParameter(SUBSCRIBED_SERVICE_NAMES_KEY);
- return isBlank(subscribedServiceNames) ? emptySet() :
- unmodifiableSet(of(subscribedServiceNames.split(","))
- .map(String::trim)
- .filter(StringUtils::isNotEmpty)
- .collect(toSet()));
+ return parseServices(registryURL.getParameter(SUBSCRIBED_SERVICE_NAMES_KEY));
}
/**
@@ -326,28 +317,73 @@ protected void subscribeURLs(URL url, NotifyListener listener) {
writableMetadataService.subscribeURL(url);
Set serviceNames = getServices(url);
- if (CollectionUtils.isEmpty(serviceNames)) {
- throw new IllegalStateException("Should has at least one way to know which services this interface belongs to, subscription url: " + url);
- }
- serviceNames.forEach(serviceName -> subscribeURLs(url, listener, serviceName));
+ List subscribedURLs = new LinkedList<>();
- }
+ serviceNames.forEach(serviceName -> {
- protected void subscribeURLs(URL url, NotifyListener listener, String serviceName) {
+ subscribeURLs(url, subscribedURLs, serviceName);
- List serviceInstances = serviceDiscovery.getInstances(serviceName);
+ // register ServiceInstancesChangedListener
+ registerServiceInstancesChangedListener(url, new ServiceInstancesChangedListener(serviceName) {
- subscribeURLs(url, listener, serviceName, serviceInstances);
+ @Override
+ public void onEvent(ServiceInstancesChangedEvent event) {
+ List subscribedURLs = new LinkedList<>();
+ Set others = new HashSet<>(serviceNames);
+ others.remove(serviceName);
- // register ServiceInstancesChangedListener
- registerServiceInstancesChangedListener(url, new ServiceInstancesChangedListener(serviceName) {
+ // Collect the subscribedURLs
+ subscribeURLs(url, subscribedURLs, serviceName, () -> event.getServiceInstances());
+ subscribeURLs(url, subscribedURLs, others.toString(), () -> getServiceInstances(others));
- @Override
- public void onEvent(ServiceInstancesChangedEvent event) {
- subscribeURLs(url, listener, event.getServiceName(), new ArrayList<>(event.getServiceInstances()));
- }
+ // Notify all
+ notifyAllSubscribedURLs(url, subscribedURLs, listener);
+
+ }
+ });
});
+
+ // Notify all
+ notifyAllSubscribedURLs(url, subscribedURLs, listener);
+
+ }
+
+ private void notifyAllSubscribedURLs(URL url, List subscribedURLs, NotifyListener listener) {
+
+ if (subscribedURLs.isEmpty()) {
+ // Add the EMPTY_PROTOCOL URL
+ subscribedURLs.add(from(url).setProtocol(EMPTY_PROTOCOL).removeParameter(CATEGORY_KEY).build());
+ }
+
+ // Notify all
+ listener.notify(subscribedURLs);
+ }
+
+ private List getServiceInstances(Set serviceNames) {
+ if (isEmpty(serviceNames)) {
+ return emptyList();
+ }
+ List allServiceInstances = new LinkedList<>();
+ for (String serviceName : serviceNames) {
+ List serviceInstances = serviceDiscovery.getInstances(serviceName);
+ if (!isEmpty(serviceInstances)) {
+ allServiceInstances.addAll(serviceInstances);
+ }
+ }
+ return allServiceInstances;
+ }
+
+ protected void subscribeURLs(URL subscribedURL, List subscribedURLs,
+ String serviceName, Supplier> serviceInstancesSupplier) {
+ Collection serviceInstances = serviceInstancesSupplier.get();
+ subscribeURLs(subscribedURL, subscribedURLs, serviceName, serviceInstances);
+ }
+
+
+ protected void subscribeURLs(URL url, List subscribedURLs, String serviceName) {
+ List serviceInstances = serviceDiscovery.getInstances(serviceName);
+ subscribeURLs(url, subscribedURLs, serviceName, serviceInstances);
}
/**
@@ -374,13 +410,13 @@ private String createListenerId(URL url, ServiceInstancesChangedListener listene
* the instances of {@link SubscribedURLsSynthesizer}
*
* @param subscribedURL the subscribed {@link URL url}
- * @param listener {@link NotifyListener}
+ * @param subscribedURLs {@link NotifyListener}
* @param serviceName
* @param serviceInstances
* @see #getExportedURLs(URL, Collection)
* @see #synthesizeSubscribedURLs(URL, Collection)
*/
- protected void subscribeURLs(URL subscribedURL, NotifyListener listener, String serviceName,
+ protected void subscribeURLs(URL subscribedURL, List subscribedURLs, String serviceName,
Collection serviceInstances) {
if (isEmpty(serviceInstances)) {
@@ -388,8 +424,6 @@ protected void subscribeURLs(URL subscribedURL, NotifyListener listener, String
return;
}
- List subscribedURLs = new LinkedList<>();
-
/**
* Add the exported URLs from {@link MetadataService}
*/
@@ -401,8 +435,6 @@ protected void subscribeURLs(URL subscribedURL, NotifyListener listener, String
*/
subscribedURLs.addAll(synthesizeSubscribedURLs(subscribedURL, serviceInstances));
}
-
- listener.notify(subscribedURLs);
}
/**
@@ -805,9 +837,11 @@ private Collection extends URL> synthesizeSubscribedURLs(URL subscribedURL, Co
*
* @param subscribedURL
* @return
+ * @throws IllegalStateException If no service name is not found
*/
- protected Set getServices(URL subscribedURL) {
- Set subscribedServices = new LinkedHashSet<>();
+ protected Set getServices(URL subscribedURL) throws IllegalStateException {
+
+ Set subscribedServices = null;
String serviceNames = subscribedURL.getParameter(PROVIDED_BY);
if (StringUtils.isNotEmpty(serviceNames)) {
@@ -816,19 +850,21 @@ protected Set getServices(URL subscribedURL) {
if (isEmpty(subscribedServices)) {
subscribedServices = findMappedServices(subscribedURL);
- if (isEmpty(subscribedServices)) {
- subscribedServices = getSubscribedServices();
- }
}
+
+ if (isEmpty(subscribedServices)) {
+ subscribedServices = getSubscribedServices();
+ }
+
+ if (isEmpty(subscribedServices)) {
+ throw new IllegalStateException("Should has at least one way to know which services this interface belongs to, subscription url: " + subscribedURL);
+ }
+
return subscribedServices;
}
public static Set parseServices(String literalServices) {
- return isBlank(literalServices) ? emptySet() :
- unmodifiableSet(of(literalServices.split(","))
- .map(String::trim)
- .filter(StringUtils::isNotEmpty)
- .collect(toSet()));
+ return splitToSet(literalServices, COMMA_SEPARATOR_CHAR, true);
}
/**
@@ -837,21 +873,20 @@ public static Set parseServices(String literalServices) {
* @return non-null
*/
public Set getSubscribedServices() {
+ if (subscribedServices == null) {
+ subscribedServices = findMappedServices(getUrl());
+ }
return subscribedServices;
}
/**
* Get the mapped services name by the specified {@link URL}
*
- * @param subscribedURL
- * @return
+ * @param url the specified {@link URL}
+ * @return empty {@link Set} if not found
*/
- protected Set findMappedServices(URL subscribedURL) {
- String serviceInterface = subscribedURL.getServiceInterface();
- String group = subscribedURL.getParameter(GROUP_KEY);
- String version = subscribedURL.getParameter(VERSION_KEY);
- String protocol = subscribedURL.getParameter(PROTOCOL_KEY, DUBBO_PROTOCOL);
- return serviceNameMapping.get(serviceInterface, group, version, protocol);
+ protected Set findMappedServices(URL url) {
+ return serviceNameMapping.get(url);
}
/**
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java
index 0422925593a..896af9ca4ad 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceInstance.java
@@ -82,6 +82,28 @@ default boolean isHealthy() {
*/
Map getMetadata();
+ /**
+ * Get the value of metadata by the specified name
+ *
+ * @param name the specified name
+ * @return the value of metadata if found, or null
+ * @since 2.7.8
+ */
+ default String getMetadata(String name) {
+ return getMetadata(name, null);
+ }
+
+ /**
+ * Get the value of metadata by the specified name
+ *
+ * @param name the specified name
+ * @return the value of metadata if found, or defaultValue
+ * @since 2.7.8
+ */
+ default String getMetadata(String name, String defaultValue) {
+ return getMetadata().getOrDefault(name, defaultValue);
+ }
+
/**
* @return the hash code of current instance.
*/
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/CustomizableServiceInstanceListener.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/CustomizableServiceInstanceListener.java
index d2ee50fa856..f739ca825f2 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/CustomizableServiceInstanceListener.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/CustomizableServiceInstanceListener.java
@@ -26,7 +26,9 @@
* Customize the {@link ServiceInstance} before registering to Registry.
*
* @since 2.7.5
+ * @deprecated 2.7.8 Current class will be removed since 3.0.0
*/
+@Deprecated
public class CustomizableServiceInstanceListener implements EventListener {
@Override
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java
index a356068b228..951f957ca44 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ExportedServicesRevisionMetadataCustomizer.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.registry.client.metadata;
+import org.apache.dubbo.metadata.URLRevisionResolver;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstanceMetadataCustomizer;
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RefreshServiceMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RefreshServiceMetadataCustomizer.java
deleted file mode 100644
index 07b6bc7d824..00000000000
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RefreshServiceMetadataCustomizer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.registry.client.metadata;
-
-import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
-
-import static org.apache.dubbo.metadata.WritableMetadataService.getExtension;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataStorageType;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getSubscribedServicesRevision;
-
-/**
- * An {@link ServiceInstanceCustomizer} to refresh metadata.
- */
-public class RefreshServiceMetadataCustomizer implements ServiceInstanceCustomizer {
-
- public int getPriority() {
- return MIN_PRIORITY;
- }
-
- @Override
- public void customize(ServiceInstance serviceInstance) {
-
- String metadataStoredType = getMetadataStorageType(serviceInstance);
-
- WritableMetadataService writableMetadataService = getExtension(metadataStoredType);
-
- writableMetadataService.refreshMetadata(getExportedServicesRevision(serviceInstance),
- getSubscribedServicesRevision(serviceInstance));
- }
-}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
index b66ae793fba..14c79883e8f 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
@@ -207,10 +207,10 @@ public static boolean isDubboServiceInstance(ServiceInstance serviceInstance) {
|| metadata.containsKey(METADATA_SERVICE_URLS_PROPERTY_NAME);
}
- public static void setEndpoints(ServiceInstance serviceInstance, Map protocolPortss) {
+ public static void setEndpoints(ServiceInstance serviceInstance, Map protocolPorts) {
Map metadata = serviceInstance.getMetadata();
List endpoints = new ArrayList<>();
- protocolPortss.forEach((k, v) -> {
+ protocolPorts.forEach((k, v) -> {
Endpoint endpoint = new Endpoint(v, k);
endpoints.add(endpoint);
});
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
index 026146e4241..216e832f5f1 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
@@ -37,6 +37,7 @@
* @since 2.7.5
*/
public class StandardMetadataServiceURLBuilder implements MetadataServiceURLBuilder {
+
public static final String NAME = "standard";
/**
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedServicesRevisionMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedServicesRevisionMetadataCustomizer.java
index fd5646b9cde..c9e6b04ab50 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedServicesRevisionMetadataCustomizer.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedServicesRevisionMetadataCustomizer.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.registry.client.metadata;
+import org.apache.dubbo.metadata.URLRevisionResolver;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstanceMetadataCustomizer;
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/BaseMetadataServiceProxyFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/BaseMetadataServiceProxyFactory.java
index 1e8d9fab01b..d599891bf46 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/BaseMetadataServiceProxyFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/BaseMetadataServiceProxyFactory.java
@@ -18,21 +18,41 @@
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision;
/**
* base class for remote and local implementations.
+ *
+ * @since 2.7.5
*/
abstract class BaseMetadataServiceProxyFactory implements MetadataServiceProxyFactory {
- private final Map proxies = new HashMap<>();
+
+ private final ConcurrentMap proxiesCache = new ConcurrentHashMap<>();
public final MetadataService getProxy(ServiceInstance serviceInstance) {
- return proxies.computeIfAbsent(serviceInstance.getServiceName() + "##" +
- ServiceInstanceMetadataUtils.getExportedServicesRevision(serviceInstance), id -> createProxy(serviceInstance));
+ return proxiesCache.computeIfAbsent(createProxyCacheKey(serviceInstance), id -> createProxy(serviceInstance));
+ }
+
+ /**
+ * Create the cache key of the proxy of {@link MetadataService}
+ *
+ * @param serviceInstance {@link ServiceInstance}
+ * @return non-null
+ * @since 2.7.8
+ */
+ protected String createProxyCacheKey(ServiceInstance serviceInstance) {
+ return serviceInstance.getServiceName() + "#" + getExportedServicesRevision(serviceInstance);
}
+ /**
+ * Create the instance proxy of {@link MetadataService}
+ *
+ * @param serviceInstance {@link ServiceInstance}
+ * @return non-null
+ */
protected abstract MetadataService createProxy(ServiceInstance serviceInstance);
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/CompositeMetadataServiceProxyFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/CompositeMetadataServiceProxyFactory.java
new file mode 100644
index 00000000000..f8c95d6fc10
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/CompositeMetadataServiceProxyFactory.java
@@ -0,0 +1,133 @@
+/*
+ * 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.client.metadata.proxy;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.registry.client.ServiceInstance;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import static java.lang.String.format;
+import static java.lang.reflect.Proxy.newProxyInstance;
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+
+/**
+ * The composite implementation of {@link MetadataServiceProxyFactory}
+ *
+ * @since 2.7.8
+ */
+public class CompositeMetadataServiceProxyFactory extends BaseMetadataServiceProxyFactory {
+
+ private static final Logger logger = LoggerFactory.getLogger(CompositeMetadataServiceProxyFactory.class);
+
+ @Override
+ public MetadataService createProxy(ServiceInstance serviceInstance) {
+ MetadataService metadataService = (MetadataService) newProxyInstance(
+ getClass().getClassLoader(),
+ new Class[]{MetadataService.class},
+ new MetadataServiceInvocationHandler(serviceInstance, this)
+ );
+ return metadataService;
+ }
+
+ static class MetadataServiceInvocationHandler implements InvocationHandler {
+
+ private final ServiceInstance serviceInstance;
+
+ private final MetadataServiceProxyFactory excluded;
+
+ private volatile List metadataServices;
+
+ MetadataServiceInvocationHandler(ServiceInstance serviceInstance,
+ MetadataServiceProxyFactory excluded) {
+ this.serviceInstance = serviceInstance;
+ this.excluded = excluded;
+ }
+
+ private List loadMetadataServices() {
+ return getExtensionLoader(MetadataServiceProxyFactory.class)
+ .getSupportedExtensionInstances()
+ .stream()
+ .filter(this::isRequiredFactory)
+ .map(this::getProxy)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ private List getMetadataServices() {
+ if (metadataServices == null) {
+ metadataServices = loadMetadataServices();
+ if (metadataServices.isEmpty()) {
+ throw new IllegalStateException(format("No valid proxy of %s can't be loaded.",
+ MetadataService.class.getName()));
+ }
+ }
+ return metadataServices;
+ }
+
+ private boolean isRequiredFactory(MetadataServiceProxyFactory factory) {
+ return !factory.equals(excluded);
+ }
+
+ private MetadataService getProxy(MetadataServiceProxyFactory factory) {
+ MetadataService metadataService = null;
+ try {
+ metadataService = factory.getProxy(serviceInstance);
+ } catch (Exception e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(format("The proxy of %s can't be gotten by %s [from : %s].",
+ MetadataService.class.getName(),
+ factory.getClass().getName(),
+ serviceInstance.toString()));
+ }
+ }
+ return metadataService;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+
+ if (Object.class.equals(method.getDeclaringClass())) {
+ return method.invoke(proxy, args);
+ }
+
+ Object result = null;
+
+ for (MetadataService metadataService : getMetadataServices()) {
+ try {
+ result = method.invoke(metadataService, args);
+ if (result != null) {
+ break;
+ }
+ } catch (Exception e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(format("MetadataService[type : %s] executes failed.", metadataService.getClass().getName()), e);
+ }
+ }
+ }
+
+ return result;
+ }
+ }
+
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/MetadataServiceProxyFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/MetadataServiceProxyFactory.java
index 14523ace0a4..e49003fbb9a 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/MetadataServiceProxyFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/MetadataServiceProxyFactory.java
@@ -31,7 +31,6 @@
* @since 2.7.5
*/
@SPI(DEFAULT_METADATA_STORAGE_TYPE)
-
public interface MetadataServiceProxyFactory {
/**
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxy.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxy.java
index e6bc86ddfc7..a92cafb6721 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxy.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/proxy/RemoteMetadataServiceProxy.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.registry.client.metadata.proxy;
+import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.UrlUtils;
@@ -23,30 +24,36 @@
import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import static java.util.Collections.unmodifiableSortedSet;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-import static org.apache.dubbo.registry.client.metadata.URLRevisionResolver.NO_REVISION;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.metadata.URLRevisionResolver.UNKNOWN_REVISION;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
+/**
+ * The proxy of {@link MetadataService} is based on {@link MetadataReport}
+ *
+ * @since 2.7.5
+ */
public class RemoteMetadataServiceProxy implements MetadataService {
+
protected final Logger logger = LoggerFactory.getLogger(getClass());
- private String serviceName;
- private String revision;
+ private final String serviceName;
+ private final String revision;
public RemoteMetadataServiceProxy(ServiceInstance serviceInstance) {
this.serviceName = serviceInstance.getServiceName();
// this is ServiceInstance of registry(Provider)
- this.revision = serviceInstance.getMetadata()
- .getOrDefault(ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME, NO_REVISION);
+ this.revision = serviceInstance.getMetadata(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, UNKNOWN_REVISION);
}
@Override
@@ -56,12 +63,23 @@ public String serviceName() {
@Override
public SortedSet getExportedURLs(String serviceInterface, String group, String version, String protocol) {
- return toSortedStrings(getMetadataReport().getExportedURLs(
- new ServiceMetadataIdentifier(serviceInterface, group, version, PROVIDER_SIDE, revision, protocol)));
- }
- private static SortedSet toSortedStrings(Collection values) {
- return Collections.unmodifiableSortedSet(new TreeSet<>(values));
+ SortedSet exportedURLs = getMetadataReport().getExportedURLs(serviceName, revision);
+ if (ALL_SERVICE_INTERFACES.equals(serviceInterface)) {
+ return exportedURLs;
+ }
+
+ return unmodifiableSortedSet(
+ exportedURLs
+ .stream()
+ .map(URL::valueOf)
+ .filter(url -> serviceInterface == null || serviceInterface.equals(url.getServiceInterface()))
+ .filter(url -> group == null || group.equals(url.getParameter(GROUP_KEY)))
+ .filter(url -> version == null || version.equals(url.getParameter(VERSION_KEY)))
+ .filter(url -> protocol == null || protocol.equals(url.getProtocol()))
+ .map(URL::toFullString)
+ .collect(TreeSet::new, Set::add, Set::addAll)
+ );
}
@Override
@@ -71,8 +89,8 @@ public String getServiceDefinition(String interfaceName, String version, String
}
@Override
- public String getServiceDefinition(String serviceKey) {
- String[] services = UrlUtils.parseServiceKey(serviceKey);
+ public String getServiceDefinition(String serviceDefinitionKey) {
+ String[] services = UrlUtils.parseServiceKey(serviceDefinitionKey);
String serviceInterface = services[0];
// if version or group is not exist
String version = null;
@@ -90,6 +108,4 @@ public String getServiceDefinition(String serviceKey) {
MetadataReport getMetadataReport() {
return MetadataReportInstance.getMetadataReport(true);
}
-
-
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
index 729e8a510ac..a7fb58de0e8 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
+++ b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
@@ -1,2 +1,4 @@
-service-instance=org.apache.dubbo.registry.client.event.listener.CustomizableServiceInstanceListener
-registry-logging=org.apache.dubbo.registry.client.event.listener.LoggingEventListener
\ No newline at end of file
+# "service-instance" has been deprecated since 2.7.8
+# service-instance=org.apache.dubbo.registry.client.event.listener.CustomizableServiceInstanceListener
+
+registry-logging=org.apache.dubbo.registry.client.event.listener.LoggingEventListener
diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer
index 3451e0014b8..9307410ac49 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer
+++ b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer
@@ -1,6 +1,5 @@
metadata-url=org.apache.dubbo.registry.client.metadata.MetadataServiceURLParamsMetadataCustomizer
exported-revision=org.apache.dubbo.registry.client.metadata.ExportedServicesRevisionMetadataCustomizer
-subscribe-revision=org.apache.dubbo.registry.client.metadata.SubscribedServicesRevisionMetadataCustomizer
-refresh=org.apache.dubbo.registry.client.metadata.RefreshServiceMetadataCustomizer
+subscribed-revision=org.apache.dubbo.registry.client.metadata.SubscribedServicesRevisionMetadataCustomizer
protocol-ports=org.apache.dubbo.registry.client.metadata.ProtocolPortsMetadataCustomizer
instance-port=org.apache.dubbo.config.metadata.ServiceInstancePortCustomizer
diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
index d9283dec444..a42e022abb1 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
+++ b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
@@ -1,2 +1,3 @@
local=org.apache.dubbo.registry.client.metadata.proxy.DefaultMetadataServiceProxyFactory
-remote=org.apache.dubbo.registry.client.metadata.proxy.RemoteMetadataServiceProxyFactory
\ No newline at end of file
+remote=org.apache.dubbo.registry.client.metadata.proxy.RemoteMetadataServiceProxyFactory
+composite = org.apache.dubbo.registry.client.metadata.proxy.CompositeMetadataServiceProxyFactory
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java
index e55b223bf6f..85b63de95dc 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/DefaultServiceInstanceTest.java
@@ -20,8 +20,11 @@
import org.junit.jupiter.api.Test;
import static java.lang.String.valueOf;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
@@ -64,4 +67,10 @@ public void testSetAndGetValues() {
assertFalse(instance.isHealthy());
assertFalse(instance.getMetadata().isEmpty());
}
+
+ @Test
+ public void testGetMetadata() {
+ assertNotNull(instance.getMetadata(METADATA_SERVICE_URLS_PROPERTY_NAME));
+ assertNotNull(instance.getMetadata(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME));
+ }
}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/BaseMetadataServiceProxyFactoryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/BaseMetadataServiceProxyFactoryTest.java
new file mode 100644
index 00000000000..6aca4c64eff
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/BaseMetadataServiceProxyFactoryTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.client.metadata.proxy;
+
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.registry.client.DefaultServiceInstance;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static java.lang.String.valueOf;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+/**
+ * {@link BaseMetadataServiceProxyFactory} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class BaseMetadataServiceProxyFactoryTest {
+
+ private MyMetadataServiceProxyFactory factory;
+
+ private DefaultServiceInstance instance;
+
+ @BeforeEach
+ public void init() {
+ factory = new MyMetadataServiceProxyFactory();
+ instance = createServiceInstance();
+ }
+
+ private DefaultServiceInstance createServiceInstance() {
+ DefaultServiceInstance serviceInstance = new DefaultServiceInstance(valueOf(System.nanoTime()), "A", "127.0.0.1", 8080);
+ Map metadata = new HashMap<>();
+ metadata.put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, "X");
+ serviceInstance.setMetadata(metadata);
+ return serviceInstance;
+ }
+
+ @Test
+ public void testCreateProxyCacheKey() {
+ assertEquals("A#X", factory.createProxyCacheKey(instance));
+ }
+
+ @Test
+ public void testCreateProxy() {
+ MetadataService metadataService = factory.createProxy(instance);
+ MetadataService metadataService2 = factory.createProxy(instance);
+ assertNotSame(metadataService, metadataService2);
+ }
+
+ @Test
+ public void testGetProxy() {
+ MetadataService metadataService = factory.getProxy(instance);
+ MetadataService metadataService2 = factory.getProxy(instance);
+ assertSame(metadataService, metadataService2);
+ }
+
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/CompositeMetadataServiceProxyFactoryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/CompositeMetadataServiceProxyFactoryTest.java
new file mode 100644
index 00000000000..ddd78e04b04
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/CompositeMetadataServiceProxyFactoryTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.client.metadata.proxy;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.metadata.report.MetadataReportInstance;
+import org.apache.dubbo.registry.client.DefaultServiceInstance;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+
+import static java.lang.String.valueOf;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.metadata.report.support.Constants.SYNC_REPORT_KEY;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link CompositeMetadataServiceProxyFactory} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class CompositeMetadataServiceProxyFactoryTest {
+
+ private static final URL METADATA_REPORT_URL = URL.valueOf("file://")
+ .addParameter(APPLICATION_KEY, "test")
+ .addParameter(SYNC_REPORT_KEY, "true");
+
+ private static final String APP_NAME = "test-service";
+
+ private MetadataServiceProxyFactory factory;
+
+ private DefaultServiceInstance instance;
+
+ @BeforeEach
+ public void init() {
+ ApplicationModel.getConfigManager().setApplication(new ApplicationConfig(APP_NAME));
+ MetadataReportInstance.init(METADATA_REPORT_URL);
+ factory = MetadataServiceProxyFactory.getExtension(COMPOSITE_METADATA_STORAGE_TYPE);
+ instance = createServiceInstance();
+ }
+
+ @AfterEach
+ public void reset() throws Exception {
+ ApplicationModel.reset();
+ MetadataReportInstance.getMetadataReport().close();
+ }
+
+ private DefaultServiceInstance createServiceInstance() {
+ DefaultServiceInstance serviceInstance = new DefaultServiceInstance(valueOf(System.nanoTime()), "A", "127.0.0.1", 8080);
+ Map metadata = new HashMap<>();
+ metadata.put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, "X");
+ metadata.put(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME, "{\"dubbo\":{\"application\":\"dubbo-provider-demo\",\"deprecated\":\"false\",\"group\":\"dubbo-provider-demo\",\"version\":\"1.0.0\",\"timestamp\":\"1564845042651\",\"dubbo\":\"2.0.2\",\"host\":\"192.168.0.102\",\"port\":\"20880\"}}");
+ serviceInstance.setMetadata(metadata);
+ return serviceInstance;
+ }
+
+ @Test
+ public void testGetProxy() {
+ MetadataService metadataService = factory.getProxy(instance);
+ MetadataService metadataService2 = factory.getProxy(instance);
+ assertSame(metadataService, metadataService2);
+ }
+
+ @Test
+ public void testGetExportedURLs() {
+ MetadataService metadataService = factory.getProxy(instance);
+ SortedSet exportedURLs = metadataService.getExportedURLs();
+ assertTrue(exportedURLs.isEmpty());
+ }
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/MetadataServiceProxyFactoryTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/MetadataServiceProxyFactoryTest.java
new file mode 100644
index 00000000000..2c31c225947
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/MetadataServiceProxyFactoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.client.metadata.proxy;
+
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.common.constants.CommonConstants.COMPOSITE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory.getDefaultExtension;
+import static org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory.getExtension;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link MetadataServiceProxyFactory} Test-Cases
+ *
+ * @since 2.7.8
+ */
+public class MetadataServiceProxyFactoryTest {
+
+ @Test
+ public void testExtension() {
+ MetadataServiceProxyFactory defaultFactory = getDefaultExtension();
+ MetadataServiceProxyFactory factory = getExtension(DEFAULT_METADATA_STORAGE_TYPE);
+ assertEquals(defaultFactory, factory);
+
+ assertEquals(MyMetadataServiceProxyFactory.class, factory.getClass());
+
+ factory = getExtension(REMOTE_METADATA_STORAGE_TYPE);
+ assertEquals(RemoteMetadataServiceProxyFactory.class, factory.getClass());
+
+ factory = getExtension(COMPOSITE_METADATA_STORAGE_TYPE);
+ assertEquals(CompositeMetadataServiceProxyFactory.class, factory.getClass());
+ }
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/MyMetadataServiceProxyFactory.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/MyMetadataServiceProxyFactory.java
new file mode 100644
index 00000000000..86247e1155c
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/proxy/MyMetadataServiceProxyFactory.java
@@ -0,0 +1,29 @@
+/*
+ * 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.client.metadata.proxy;
+
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.ServiceInstance;
+
+public class MyMetadataServiceProxyFactory extends BaseMetadataServiceProxyFactory {
+
+ @Override
+ protected MetadataService createProxy(ServiceInstance serviceInstance) {
+ return new InMemoryWritableMetadataService();
+ }
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/resources/META-INF/dubbo/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory b/dubbo-registry/dubbo-registry-api/src/test/resources/META-INF/dubbo/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
new file mode 100644
index 00000000000..6d2b9dd19c0
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/test/resources/META-INF/dubbo/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
@@ -0,0 +1,2 @@
+# Override "local" implementation
+local=org.apache.dubbo.registry.client.metadata.proxy.MyMetadataServiceProxyFactory
\ No newline at end of file
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 00000000000..f3fb024c9ce
--- /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 defaultValue
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 defaultValue
if not found
+ */
+ public T getValue(URL registryURL, Class 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 5d5e98b7973..b05f1d83614 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.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.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.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_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 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 void initialize(URL registryURL) throws Exception {
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 getTags(URL registryURL) {
+ String value = TAGS.getValue(registryURL);
+ return StringUtils.splitToList(value, COMMA_SEPARATOR_CHAR);
}
private List getRegisteringTags(URL url) {
@@ -122,7 +184,7 @@ public void destroy() {
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 void update(ServiceInstance serviceInstance) throws RuntimeException {
public void unregister(ServiceInstance serviceInstance) throws RuntimeException {
String id = buildId(serviceInstance);
ttlScheduler.remove(id);
- client.agentServiceDeregister(id);
+ client.agentServiceDeregister(id, aclToken);
}
@Override
public Set 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 @@ private NewService buildService(ServiceInstance serviceInstance) {
service.setName(serviceInstance.getServiceName());
service.setCheck(buildCheck(serviceInstance));
service.setTags(buildTags(serviceInstance));
-// service.setMeta(buildMetadata(serviceInstance));
return service;
}
@@ -240,10 +305,21 @@ private String buildId(ServiceInstance serviceInstance) {
}
private List buildTags(ServiceInstance serviceInstance) {
+ List tags = new LinkedList<>(this.tags);
+
+ if (StringUtils.isNotEmpty(instanceZone)) {
+ tags.add(defaultZoneMetadataName + "=" + instanceZone);
+ }
+
+ if (StringUtils.isNotEmpty(instanceGroup)) {
+ tags.add("group=" + instanceGroup);
+ }
+
Map params = serviceInstance.getMetadata();
- List 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 @@ private NewService.Check buildCheck(ServiceInstance serviceInstance) {
check.setTtl((checkPassInterval / 1000) + "s");
String deregister = serviceInstance.getMetadata().get(DEREGISTER_AFTER);
check.setDeregisterCriticalServiceAfter(deregister == null ? DEFAULT_DEREGISTER_TIME : deregister);
-
return check;
}
diff --git a/dubbo-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryTest.java b/dubbo-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryTest.java
index e106248fa33..9f10d0ab16b 100644
--- a/dubbo-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryTest.java
+++ b/dubbo-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryTest.java
@@ -16,12 +16,13 @@
*/
package org.apache.dubbo.registry.consul;
-import com.pszymczyk.consul.ConsulProcess;
-import com.pszymczyk.consul.ConsulStarterBuilder;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstance;
+
+import com.pszymczyk.consul.ConsulProcess;
+import com.pszymczyk.consul.ConsulStarterBuilder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -36,9 +37,9 @@
public class ConsulServiceDiscoveryTest {
- private static ConsulProcess consul;
private URL url;
- static ConsulServiceDiscovery consulServiceDiscovery;
+ private ConsulServiceDiscovery consulServiceDiscovery;
+ private ConsulProcess consul;
private static final String SERVICE_NAME = "A";
private static final String LOCALHOST = "127.0.0.1";
@@ -49,7 +50,6 @@ public void init() throws Exception {
.start();
url = URL.valueOf("consul://localhost:" + consul.getHttpPort());
consulServiceDiscovery = new ConsulServiceDiscovery();
- Assertions.assertNull(consulServiceDiscovery.getServices());
consulServiceDiscovery.initialize(url);
}
@@ -60,7 +60,7 @@ public void close() {
}
@Test
- public void testRegistration() throws InterruptedException{
+ public void testRegistration() throws InterruptedException {
DefaultServiceInstance serviceInstance = createServiceInstance(SERVICE_NAME, LOCALHOST, NetUtils.getAvailablePort());
consulServiceDiscovery.register(serviceInstance);
Thread.sleep(5000);
@@ -94,8 +94,8 @@ public void testGetInstances() throws Exception {
Thread.sleep(5000);
Assertions.assertFalse(consulServiceDiscovery.getInstances(serviceName).isEmpty());
List r = convertToIpPort(consulServiceDiscovery.getInstances(serviceName));
- assertTrue(r.contains("127.0.0.1:"+portA));
- assertTrue(r.contains("127.0.0.1:"+portB));
+ assertTrue(r.contains("127.0.0.1:" + portA));
+ assertTrue(r.contains("127.0.0.1:" + portB));
}
private List convertToIpPort(List serviceInstances) {
diff --git a/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java b/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java
index bb49c100ecd..516c9e55848 100644
--- a/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-eureka/src/main/java/org/apache/dubbo/registry/eureka/EurekaServiceDiscovery.java
@@ -46,9 +46,8 @@
import java.util.Set;
import static java.util.Collections.emptyList;
-import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
import static org.apache.dubbo.event.EventDispatcher.getDefaultExtension;
-import static org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.parseServices;
+import static org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.getSubscribedServices;
/**
* Eureka {@link ServiceDiscovery} implementation based on Eureka API
@@ -100,7 +99,7 @@ private Properties buildEurekaConfigProperties(URL registryURL) {
* @param registryURL the {@link URL url} to connect Eureka
*/
private void initSubscribedServices(URL registryURL) {
- this.subscribedServices = parseServices(registryURL.getParameter(SUBSCRIBED_SERVICE_NAMES_KEY));
+ this.subscribedServices = getSubscribedServices(registryURL);
}
private boolean filterEurekaProperty(Map.Entry propertyEntry) {
diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java
index 9c4f1b84828..b301a784e5b 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServer.java
@@ -16,7 +16,6 @@
*/
package org.apache.dubbo.remoting.transport.netty4;
-import io.netty.channel.socket.SocketChannel;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
@@ -37,6 +36,7 @@
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import java.net.InetSocketAddress;
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java
index b34245aadbd..380b2c3c40e 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcContextTest.java
@@ -25,8 +25,6 @@
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
public class RpcContextTest {
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java
index c3ccb331168..4bc08005a1b 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ArgumentCallbackTest.java
@@ -16,27 +16,28 @@
*/
package org.apache.dubbo.rpc.protocol.dubbo;
-import static org.apache.dubbo.common.constants.CommonConstants.CALLBACK_INSTANCES_LIMIT_KEY;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
+
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
-import org.apache.dubbo.remoting.Constants;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CALLBACK_INSTANCES_LIMIT_KEY;
public class ArgumentCallbackTest {