Merge branch 'apache-3.1' into apache-3.2

# Conflicts:
#	dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
#	dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd
#	dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
#	dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
#	dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
#	dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java
#	dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
This commit is contained in:
Albumen Kevin 2023-01-11 15:05:01 +08:00
commit a278feb372
66 changed files with 2136 additions and 289 deletions

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.convert.ConverterUtil;
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
@ -33,6 +34,7 @@ public class CommonScopeModelInitializer implements ScopeModelInitializer {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(FrameworkExecutorRepository.class);
beanFactory.registerBean(ConverterUtil.class);
beanFactory.registerBean(SerializeSecurityManager.class);
}
@Override

View File

@ -435,6 +435,8 @@ public interface CommonConstants {
String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist";
String SERIALIZE_ALLOW_LIST_FILE_PATH = "security/serialize.allowlist";
String QOS_LIVE_PROBE_EXTENSION = "dubbo.application.liveness-probe";
String QOS_READY_PROBE_EXTENSION = "dubbo.application.readiness-probe";

View File

@ -291,6 +291,8 @@ public interface LoggerCodeConstants {
String PROTOCOL_FAILED_DECODE = "4-20";
String PROTOCOL_UNTRUSTED_SERIALIZE_CLASS = "4-21";
// Config module
String CONFIG_FAILED_CONNECT_REGISTRY = "5-1";

View File

@ -0,0 +1,26 @@
/*
* 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.util.Set;
public interface AllowClassNotifyListener {
SerializeCheckStatus DEFAULT_STATUS = SerializeCheckStatus.WARN;
void notify(SerializeCheckStatus status, Set<String> prefixList);
}

View File

@ -24,11 +24,11 @@ import java.io.IOException;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ -46,7 +46,7 @@ public class ClassLoaderResourceLoader {
GlobalResourcesRepository.registerGlobalDisposable(() -> destroy());
}
public static Map<ClassLoader, Set<URL>> loadResources(String fileName, List<ClassLoader> classLoaders) throws InterruptedException {
public static Map<ClassLoader, Set<URL>> loadResources(String fileName, Collection<ClassLoader> classLoaders) throws InterruptedException {
Map<ClassLoader, Set<URL>> resources = new ConcurrentHashMap<>();
CountDownLatch countDownLatch = new CountDownLatch(classLoaders.size());
for (ClassLoader classLoader : classLoaders) {

View File

@ -0,0 +1,23 @@
/*
* 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;
public enum SerializeCheckStatus {
DISABLED,
WARN,
STRICT,
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -52,10 +51,10 @@ public class SerializeClassChecker {
private final AtomicLong counter = new AtomicLong(0);
private SerializeClassChecker() {
String openCheckClass = ConfigurationUtils.getProperty(CommonConstants.CLASS_DESERIALIZE_OPEN_CHECK, "true");
String openCheckClass = System.getProperty(CommonConstants.CLASS_DESERIALIZE_OPEN_CHECK, "true");
OPEN_CHECK_CLASS = Boolean.parseBoolean(openCheckClass);
String blockAllClassExceptAllow = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCK_ALL, "false");
String blockAllClassExceptAllow = System.getProperty(CLASS_DESERIALIZE_BLOCK_ALL, "false");
BLOCK_ALL_CLASS_EXCEPT_ALLOW = Boolean.parseBoolean(blockAllClassExceptAllow);
@ -79,8 +78,8 @@ public class SerializeClassChecker {
logger.error(COMMON_IO_EXCEPTION, "", "", "Failed to load blocked class list! Will ignore default blocked list.", e);
}
String allowedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_ALLOWED_LIST, "").trim().toLowerCase(Locale.ROOT);
String blockedClassList = ConfigurationUtils.getProperty(CLASS_DESERIALIZE_BLOCKED_LIST, "").trim().toLowerCase(Locale.ROOT);
String allowedClassList = System.getProperty(CLASS_DESERIALIZE_ALLOWED_LIST, "").trim().toLowerCase(Locale.ROOT);
String blockedClassList = System.getProperty(CLASS_DESERIALIZE_BLOCKED_LIST, "").trim().toLowerCase(Locale.ROOT);
if (StringUtils.isNotEmpty(allowedClassList)) {
String[] classStrings = allowedClassList.trim().split(",");
@ -120,34 +119,45 @@ public class SerializeClassChecker {
* @throws IllegalArgumentException if class is blocked
*/
public void validateClass(String name) {
validateClass(name, true);
}
public boolean validateClass(String name, boolean failOnError) {
if (!OPEN_CHECK_CLASS) {
return;
return true;
}
name = name.toLowerCase(Locale.ROOT);
if (CACHE == CLASS_ALLOW_LFU_CACHE.get(name)) {
return;
return true;
}
if (CACHE == CLASS_BLOCK_LFU_CACHE.get(name)) {
error(name);
if (failOnError) {
error(name);
}
return false;
}
for (String allowedPrefix : CLASS_DESERIALIZE_ALLOWED_SET) {
if (name.startsWith(allowedPrefix)) {
CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
return;
return true;
}
}
for (String blockedPrefix : CLASS_DESERIALIZE_BLOCKED_SET) {
if (BLOCK_ALL_CLASS_EXCEPT_ALLOW || name.startsWith(blockedPrefix)) {
CLASS_BLOCK_LFU_CACHE.put(name, CACHE);
error(name);
if (failOnError) {
error(name);
}
return false;
}
}
CLASS_ALLOW_LFU_CACHE.put(name, CACHE);
return true;
}
private void error(String name) {

View File

@ -0,0 +1,224 @@
/*
* 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.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.net.URL;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.rpc.model.FrameworkModel;
import static org.apache.dubbo.common.constants.CommonConstants.SERIALIZE_ALLOW_LIST_FILE_PATH;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_IO_EXCEPTION;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_INTERRUPTED;
public class SerializeSecurityManager {
private final Set<String> allowedPrefix = new LinkedHashSet<>();
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(SerializeSecurityManager.class);
private final SerializeClassChecker checker = SerializeClassChecker.getInstance();
private final Set<AllowClassNotifyListener> listeners = new ConcurrentHashSet<>();
private volatile SerializeCheckStatus checkStatus = AllowClassNotifyListener.DEFAULT_STATUS;
public SerializeSecurityManager(FrameworkModel frameworkModel) {
try {
Set<ClassLoader> classLoaders = frameworkModel.getClassLoaders();
List<URL> urls = ClassLoaderResourceLoader.loadResources(SERIALIZE_ALLOW_LIST_FILE_PATH, classLoaders)
.values()
.stream()
.flatMap(Set::stream)
.collect(Collectors.toList());
for (URL u : urls) {
try {
logger.info("Read serialize allow list from " + u);
String[] lines = IOUtils.readLines(u.openStream());
for (String line : lines) {
line = line.trim();
if (StringUtils.isEmpty(line) || line.startsWith("#")) {
continue;
}
allowedPrefix.add(line);
}
} catch (IOException e) {
logger.error(COMMON_IO_EXCEPTION, "", "", "Failed to load allow class list! Will ignore allow lis from " + u, e);
}
}
} catch (InterruptedException e) {
logger.error(INTERNAL_INTERRUPTED, "", "", "Failed to load allow class list! Will ignore allow list from configuration.", e);
Thread.currentThread().interrupt();
}
}
public void registerInterface(Class<?> clazz) {
Set<Class<?>> markedClass = new HashSet<>();
markedClass.add(clazz);
addToAllow(clazz.getName());
Method[] methodsToExport = clazz.getMethods();
for (Method method : methodsToExport) {
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
checkClass(markedClass, parameterType);
}
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
checkType(markedClass, genericParameterType);
}
Class<?> returnType = method.getReturnType();
checkClass(markedClass, returnType);
Type genericReturnType = method.getGenericReturnType();
checkType(markedClass, genericReturnType);
Class<?>[] exceptionTypes = method.getExceptionTypes();
for (Class<?> exceptionType : exceptionTypes) {
checkClass(markedClass, exceptionType);
}
Type[] genericExceptionTypes = method.getGenericExceptionTypes();
for (Type genericExceptionType : genericExceptionTypes) {
checkType(markedClass, genericExceptionType);
}
}
}
private void checkType(Set<Class<?>> markedClass, Type type) {
if (type instanceof Class) {
checkClass(markedClass, (Class<?>) type);
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
checkClass(markedClass, (Class<?>) parameterizedType.getRawType());
for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
checkType(markedClass, actualTypeArgument);
}
} else if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType) type;
checkType(markedClass, genericArrayType.getGenericComponentType());
} else if (type instanceof TypeVariable) {
TypeVariable typeVariable = (TypeVariable) type;
for (Type bound : typeVariable.getBounds()) {
checkType(markedClass, bound);
}
} else if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
for (Type bound : wildcardType.getUpperBounds()) {
checkType(markedClass, bound);
}
for (Type bound : wildcardType.getLowerBounds()) {
checkType(markedClass, bound);
}
}
}
private void checkClass(Set<Class<?>> markedClass, Class<?> clazz) {
if (markedClass.contains(clazz)) {
return;
}
markedClass.add(clazz);
addToAllow(clazz.getName());
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> interfaceClass : interfaces) {
checkClass(markedClass, interfaceClass);
}
Class<?> superclass = clazz.getSuperclass();
if (superclass != null) {
checkClass(markedClass, superclass);
}
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isTransient(field.getModifiers())) {
continue;
}
Class<?> fieldClass = field.getType();
checkClass(markedClass, fieldClass);
checkType(markedClass, field.getGenericType());
}
}
protected void addToAllow(String className) {
if (!checker.validateClass(className, false)) {
return;
}
boolean modified;
// ignore jdk
if (className.startsWith("java.") || className.startsWith("javax.") || className.startsWith("com.sun.") ||
className.startsWith("sun.") || className.startsWith("jdk.")) {
modified = allowedPrefix.add(className);
if (modified) {
notifyListeners();
}
return;
}
// add group package
String[] subs = className.split("\\.");
if (subs.length > 3) {
modified = allowedPrefix.add(subs[0] + "." + subs[1] + "." + subs[2]);
} else {
modified = allowedPrefix.add(className);
}
if (modified) {
notifyListeners();
}
}
public void registerListener(AllowClassNotifyListener listener) {
listeners.add(listener);
listener.notify(checkStatus, allowedPrefix);
}
private void notifyListeners() {
for (AllowClassNotifyListener listener : listeners) {
listener.notify(checkStatus, allowedPrefix);
}
}
protected Set<String> getAllowedPrefix() {
return allowedPrefix;
}
}

View File

@ -16,6 +16,23 @@
*/
package org.apache.dubbo.config;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
import org.apache.dubbo.common.infra.InfraAdapter;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
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.config.support.Parameter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
@ -213,6 +230,11 @@ public class ApplicationConfig extends AbstractConfig {
*/
private Integer metadataServicePort;
/**
* The retry interval of service name mapping
*/
private Integer mappingRetryInterval;
/**
* used to set extensions of probe in qos
*/
@ -617,6 +639,14 @@ public class ApplicationConfig extends AbstractConfig {
this.metadataServicePort = metadataServicePort;
}
public Integer getMappingRetryInterval() {
return mappingRetryInterval;
}
public void setMappingRetryInterval(Integer mappingRetryInterval) {
this.mappingRetryInterval = mappingRetryInterval;
}
@Parameter(key = METADATA_SERVICE_PROTOCOL_KEY)
public String getMetadataServiceProtocol() {
return metadataServiceProtocol;

View File

@ -0,0 +1,125 @@
#
#
# 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.
#
#
boolean
byte
char
double
float
int
long
short
java.lang.AutoCloseable
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Class
java.lang.Cloneable
java.lang.Double
java.lang.Exception
java.lang.Float
java.lang.IllegalAccessError
java.lang.IllegalAccessException
java.lang.IllegalArgumentException
java.lang.IllegalMonitorStateException
java.lang.IllegalStateException
java.lang.IllegalThreadStateException
java.lang.IndexOutOfBoundsException
java.lang.InstantiationError
java.lang.InstantiationException
java.lang.Integer
java.lang.InternalError
java.lang.InterruptedException
java.lang.LinkageError
java.lang.Long
java.lang.NegativeArraySizeException
java.lang.NoClassDefFoundError
java.lang.NoSuchFieldError
java.lang.NoSuchFieldException
java.lang.NoSuchMethodError
java.lang.NoSuchMethodException
java.lang.NullPointerException
java.lang.Number
java.lang.NumberFormatException
java.lang.Object
java.lang.OutOfMemoryError
java.lang.RuntimeException
java.lang.SecurityException
java.lang.Short
java.lang.StackOverflowError
java.lang.StackTraceElement
java.lang.String
java.lang.StringIndexOutOfBoundsException
java.lang.TypeNotPresentException
java.lang.VerifyError
java.math.BigDecimal
java.math.BigInteger
java.text.SimpleDateFormat
java.time.format.DateTimeFormatter
java.time.Instant
java.time.LocalDate
java.time.LocalDateTime
java.time.LocalTime
java.util.ArrayList
java.util.Arrays$ArrayList
java.util.BitSet
java.util.Calendar
java.util.Collections$EmptyList
java.util.Collections$EmptyMap
java.util.Collections$SingletonSet
java.util.Collections$UnmodifiableCollection
java.util.Collections$UnmodifiableList
java.util.Collections$UnmodifiableMap
java.util.Collections$UnmodifiableNavigableMap
java.util.Collections$UnmodifiableNavigableSet
java.util.Collections$UnmodifiableRandomAccessList
java.util.Collections$UnmodifiableSet
java.util.Collections$UnmodifiableSortedMap
java.util.Collections$UnmodifiableSortedSet
java.util.concurrent.atomic.AtomicBoolean
java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicIntegerArray
java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicLongArray
java.util.concurrent.atomic.AtomicReference
java.util.concurrent.ConcurrentHashMap
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ConcurrentMap
java.util.concurrent.ConcurrentSkipListMap
java.util.concurrent.ConcurrentSkipListSet
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.TimeUnit
java.util.Currency
java.util.Date
java.util.EnumSet
java.util.HashMap
java.util.HashSet
java.util.Hashtable
java.util.IdentityHashMap
java.util.LinkedHashMap
java.util.LinkedHashSet
java.util.LinkedList
java.util.List
java.util.Locale
java.util.Map
java.util.Set
java.util.TreeMap
java.util.TreeSet
java.util.UUID
java.util.WeakHashMap
org.apache.dubbo

View File

@ -18,33 +18,38 @@
#
aj.org.objectweb.asm.
br.com.anteros.
bsh.
ch.qos.logback.
clojure.core$constantly
clojure.main$eval_opt
com.alibaba.citrus.springext.support.parser.abstractnamedproxybeandefinitionparser$proxytargetfactory
com.alibaba.citrus.springext.util.springextutil.abstractproxy
com.alibaba.druid.pool.druiddatasource
clojure.
com.alibaba.citrus.springext.support.parser.
com.alibaba.citrus.springext.util.SpringExtUtil.
com.alibaba.druid.pool.
com.alibaba.druid.stat.jdbcdatasourcestat
com.alibaba.fastjson.annotation
com.alipay.custrelation.service.model.redress.pair
com.alibaba.hotcode.internal.org.apache.commons.collections.functors.
com.alipay.custrelation.service.model.redress.
com.alipay.oceanbase.obproxy.druid.pool.
com.caucho.
com.ibatis.
com.ibm.jtc.jax.xml.bind.v2.runtime.unmarshaller.
com.ibm.xltxe.rnm1.xtq.bcel.util.
com.mchange
com.mysql.cj.jdbc.admin.
com.mysql.cj.jdbc.mysqlconnectionpooldatasource
com.mysql.cj.jdbc.mysqldatasource
com.mysql.cj.jdbc.mysqlxadatasource
com.mysql.cj.log.
com.mysql.jdbc.util.
com.p6spy.engine.
com.rometools.rome.feed.impl.equalsbean
com.rometools.rome.feed.impl.tostringbean
com.rometools.rome.feed.
com.sun.
com.taobao.eagleeye.wrapper
com.taobao.vipserver.commons.collections.functors.
com.zaxxer.hikari.
flex.messaging.util.concurrent.
java.awt.i
java.awt.p
java.beans.expression
groovy.lang.
java.awt.
java.beans.
java.io.closeable
java.io.serializable
java.lang.autocloseable
@ -52,41 +57,46 @@ java.lang.class
java.lang.cloneable
java.lang.iterable
java.lang.object
java.lang.ProcessBuilder
java.lang.readable
java.lang.runnable
java.lang.Runtime
java.lang.thread
java.lang.unixprocess
java.net.inetaddress
java.net.socket
java.net.url
java.rmi
java.security.signedobject
java.security.
java.util.collection
java.util.eventlistener
java.util.jar.
java.util.logging.
java.util.prefs.
java.util.ServiceLoader
java.util.serviceloader$lazyiterator
java.util.StringTokenizer
javassist.
javax.activation.
javax.imageio.imageio$containsfilter
javax.imageio.spi.serviceregistry
javax.imageio.
javax.management.
javax.media.jai.remote.
javax.naming.
javax.net.
javax.print.
javax.script.
javax.sound.
javax.swing.j
javax.swing.
javax.tools.
javax.xml
jdk.internal.
jodd.db.connection.
junit.
net.bytebuddy.dynamic.loading.bytearrayclassloader
net.bytebuddy.dynamic.loading.
net.sf.cglib.
net.sf.ehcache.hibernate.
net.sf.ehcache.transaction.manager.
ognl.
oracle.jdbc.
oracle.jms.aq
oracle.net
@ -100,10 +110,12 @@ org.apache.aries.transaction.
org.apache.axis2.jaxws.spi.handler.
org.apache.axis2.transport.jms.
org.apache.bcel
org.apache.carbondata.core.scan.expression.
org.apache.carbondata.core.scan.expression.expressionresult
org.apache.catalina.
org.apache.cocoon.
org.apache.commons.beanutils
org.apache.commons.codec.
org.apache.commons.collections.comparators.
org.apache.commons.collections.functors
org.apache.commons.collections.functors.
@ -112,6 +124,7 @@ org.apache.commons.collections4.comparators
org.apache.commons.collections4.functors
org.apache.commons.collections4.transformer
org.apache.commons.configuration
org.apache.commons.configuration2.
org.apache.commons.dbcp
org.apache.commons.fileupload
org.apache.commons.jelly.
@ -130,32 +143,43 @@ org.apache.ibatis.ognl.
org.apache.ibatis.parsing.
org.apache.ibatis.reflection.
org.apache.ibatis.scripting.
org.apache.ignite.cache.
org.apache.ignite.cache.jta.
org.apache.log.output.db.
org.apache.log4j.
org.apache.logging.
org.apache.myfaces.context.servlet
org.apache.myfaces.view.facelets.el.
org.apache.openjpa.ee.
org.apache.shiro.jndi.
org.apache.shiro.realm.
org.apache.shiro.
org.apache.tomcat
org.apache.velocity.
org.apache.wicket.util
org.apache.xalan
org.apache.xbean.
org.apache.xpath.xpathcontext
org.apache.xpath.
org.apache.zookeeper.
org.aspectj.
org.codehaus.groovy.runtime
org.codehaus.jackson.
org.datanucleus.store.rdbms.datasource.dbcp.datasources.
org.dom4j.
org.eclipse.jetty.
org.geotools.filter.constantexpression
org.geotools.filter.
org.h2.jdbcx.
org.h2.server.
org.h2.value.
org.hibernate
org.javasimon.
org.jaxen.
org.jboss
org.jdom.
org.jdom2.transform.
org.junit.
org.logicalcobwebs.
org.mockito.
org.mortbay.jetty.
org.mortbay.log.
org.mozilla.javascript
org.objectweb.asm.
org.osjava.sj.
@ -163,5 +187,11 @@ org.python.core
org.quartz.
org.slf4j.
org.springframework.
org.yaml.snakeyaml.tokens.directivetoken
sun.rmi.server.unicastref
org.thymeleaf.
org.yaml.snakeyaml.tokens.
pstore.shaded.org.apache.commons.collections.
sun.print.
sun.rmi.server.
sun.rmi.transport.
weblogic.ejb20.internal.
weblogic.jms.common.

View File

@ -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 com.pojo;
public class Demo1 {
private Simple simple;
public Simple getSimple() {
return simple;
}
public void setSimple(Simple simple) {
this.simple = simple;
}
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Demo2 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Demo3 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Demo4 extends Demo3 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Demo5 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Demo6 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Demo7 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Demo8 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class DemoException1 extends Exception{
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class DemoException2 extends Exception {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class DemoException3 extends DemoException2 {
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.pojo;
public class Simple {
}

View File

@ -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 com.service;
import com.pojo.Demo1;
import com.pojo.Demo2;
import com.pojo.Demo4;
import com.pojo.Demo5;
import com.pojo.Demo6;
import com.pojo.Demo7;
import com.pojo.Demo8;
import com.pojo.DemoException1;
import com.pojo.DemoException3;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public interface DemoService1<T extends Demo8> {
Demo1 getDemo1();
void setDemo2(Demo2 demo2);
List<Demo4> getDemo4s();
List<HashSet<LinkedList<Set<Vector<Map<? extends Demo5, ? super Demo6>>>>>> getDemo5s();
List<Demo7>[] getDemo7s();
List<T> getTs();
void echo1() throws DemoException1;
void echo2() throws DemoException3;
}

View File

@ -0,0 +1,20 @@
/*
* 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 com.service;
public interface DemoService2 extends DemoService1 {
}

View File

@ -0,0 +1,128 @@
/*
* 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.apache.dubbo.rpc.model.FrameworkModel;
import com.service.DemoService1;
import com.service.DemoService2;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
public class SerializeSecurityManagerTest {
@Test
public void test() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.HashMap"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.DemoInterface"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.sun.Interface1"));
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
@Test
public void addToAllow() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("com.sun.Interface2");
Assertions.assertFalse(ssm.getAllowedPrefix().contains("com.sun.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("java.util.Interface1");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.Interface1"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("java.util.package.Interface1");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("java.util.package.Interface1"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("com.example.Interface2");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.Interface2"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
ssm.addToAllow("com.example.package.Interface1");
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.example.package"));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
@Test
public void testRegister1() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
ssm.registerInterface(DemoService1.class);
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.service.DemoService1"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo1"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo2"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo3"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo4"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo5"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo6"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo7"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo8"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Simple"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(List.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Set.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Map.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(LinkedList.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Vector.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(HashSet.class.getName()));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
@Test
public void testRegister2() {
SerializeSecurityManager ssm = new SerializeSecurityManager(FrameworkModel.defaultModel());
ssm.registerListener(new TestAllowClassNotifyListener());
ssm.registerInterface(DemoService2.class);
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.service.DemoService2"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo1"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo2"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo3"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo4"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo5"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo6"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo7"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Demo8"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains("com.pojo.Simple"));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(List.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Set.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Map.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(LinkedList.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(Vector.class.getName()));
Assertions.assertTrue(ssm.getAllowedPrefix().contains(HashSet.class.getName()));
Assertions.assertEquals(ssm.getAllowedPrefix(), TestAllowClassNotifyListener.getPrefixList());
}
}

View File

@ -14,18 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.hessian2.dubbo;
package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
public class TestAllowClassNotifyListener implements AllowClassNotifyListener {
private final static AtomicReference<Set<String>> prefixList = new AtomicReference<>();
public class DefaultHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer {
@Override
protected SerializerFactory createSerializerFactory() {
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory();
hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
hessian2SerializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return hessian2SerializerFactory;
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
TestAllowClassNotifyListener.prefixList.set(prefixList);
}
public static Set<String> getPrefixList() {
return prefixList.get();
}
}

View File

@ -0,0 +1,20 @@
#
#
# 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.
#
#
com.example.DemoInterface
com.sun.Interface1

View File

@ -16,6 +16,18 @@
*/
package org.apache.dubbo.config;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.Version;
@ -24,6 +36,7 @@ import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
@ -49,17 +62,6 @@ import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ServiceDescriptor;
import org.apache.dubbo.rpc.service.GenericService;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
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.COMMA_SEPARATOR;
@ -264,21 +266,41 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
exportedURLs.forEach(url -> {
if (url.getParameters().containsKey(SERVICE_NAME_MAPPING_KEY)) {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(getScopeModel());
try {
boolean succeeded = serviceNameMapping.map(url);
if (succeeded) {
logger.info("Successfully registered interface application mapping for service " + url.getServiceKey());
} else {
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey());
}
} catch (Exception e) {
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey(), e);
}
ScheduledExecutorService scheduledExecutor = getScopeModel().getBeanFactory()
.getBean(FrameworkExecutorRepository.class).getSharedScheduledExecutor();
mapServiceName(url, serviceNameMapping, scheduledExecutor);
}
});
onExported();
}
protected void mapServiceName(URL url, ServiceNameMapping serviceNameMapping, ScheduledExecutorService scheduledExecutor) {
if (!exported) {
return;
}
logger.info("Try to register interface application mapping for service " + url.getServiceKey());
boolean succeeded = false;
try {
succeeded = serviceNameMapping.map(url);
if (succeeded) {
logger.info("Successfully registered interface application mapping for service " + url.getServiceKey());
} else {
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey());
}
} catch (Exception e) {
logger.error(CONFIG_SERVER_DISCONNECTED, "configuration server disconnected", "", "Failed register interface application mapping for service " + url.getServiceKey(), e);
}
if (!succeeded) {
scheduleToMapping(scheduledExecutor, serviceNameMapping, url);
}
}
private void scheduleToMapping(ScheduledExecutorService scheduledExecutor, ServiceNameMapping serviceNameMapping, URL url) {
Integer mappingRetryInterval = getApplication().getMappingRetryInterval();
scheduledExecutor.schedule(() -> mapServiceName(url, serviceNameMapping, scheduledExecutor),
mappingRetryInterval == null ? 5000 : mappingRetryInterval, TimeUnit.MILLISECONDS);
}
private void checkAndUpdateSubConfigs() {
// Use default configs defined explicitly with global scope

View File

@ -1038,6 +1038,7 @@ class ReferenceConfigTest {
@Test
@DisabledForJreRange(min = JRE.JAVA_16)
public void testDifferentClassLoaderRequest() throws Exception {
FrameworkModel frameworkModel = FrameworkModel.defaultModel();
String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
@ -1046,7 +1047,7 @@ class ReferenceConfigTest {
TestClassLoader2 classLoader3 = new TestClassLoader2(classLoader2, basePath);
ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
ApplicationModel applicationModel = new ApplicationModel(frameworkModel);
applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
ModuleModel moduleModel = new ModuleModel(applicationModel);

View File

@ -17,6 +17,14 @@
package org.apache.dubbo.config;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.config.api.DemoService;
@ -27,22 +35,22 @@ import org.apache.dubbo.config.mock.MockRegistryFactory2;
import org.apache.dubbo.config.mock.MockServiceListener;
import org.apache.dubbo.config.mock.TestProxyFactory;
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
import org.apache.dubbo.metadata.MappingListener;
import org.apache.dubbo.metadata.ServiceNameMapping;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.service.GenericService;
import com.google.common.collect.Lists;
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 org.mockito.Mockito;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import com.google.common.collect.Lists;
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
@ -59,6 +67,7 @@ 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.cluster.Constants.EXPORT_KEY;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
@ -529,4 +538,80 @@ class ServiceConfigTest {
service.export();
});
}
@Test
void testMappingRetry() {
FrameworkModel frameworkModel = new FrameworkModel();
ApplicationModel applicationModel = frameworkModel.newApplication();
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>(applicationModel.newModule());
serviceConfig.exported();
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
AtomicInteger count = new AtomicInteger(0);
ServiceNameMapping serviceNameMapping = new ServiceNameMapping() {
@Override
public boolean map(URL url) {
if (count.incrementAndGet() < 5) {
throw new RuntimeException();
}
return count.get() > 10;
}
@Override
public void initInterfaceAppMapping(URL subscribedURL) {
}
@Override
public Set<String> getAndListen(URL registryURL, URL subscribedURL, MappingListener listener) {
return null;
}
@Override
public MappingListener stopListen(URL subscribeURL, MappingListener listener) {
return null;
}
@Override
public void putCachedMapping(String serviceKey, Set<String> apps) {
}
@Override
public Set<String> getCachedMapping(String mappingKey) {
return null;
}
@Override
public Set<String> getCachedMapping(URL consumerURL) {
return null;
}
@Override
public Set<String> getRemoteMapping(URL consumerURL) {
return null;
}
@Override
public Map<String, Set<String>> getCachedMapping() {
return null;
}
@Override
public Set<String> removeCachedMapping(String serviceKey) {
return null;
}
@Override
public void $destroy() {
}
};
ApplicationConfig applicationConfig = new ApplicationConfig("app");
applicationConfig.setMappingRetryInterval(10);
serviceConfig.setApplication(applicationConfig);
serviceConfig.mapServiceName(URL.valueOf(""), serviceNameMapping, scheduledExecutorService);
await().until(() -> count.get() > 10);
scheduledExecutorService.shutdown();
}
}

View File

@ -0,0 +1,19 @@
#
#
# 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.
#
#
demo.

View File

@ -482,6 +482,11 @@
<xsd:documentation><![CDATA[ Saving thread dump or not, default true. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="mapping-retry-interval" type="xsd:integer">
<xsd:annotation>
<xsd:documentation><![CDATA[ The retry interval of service name mapping. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="moduleType">

View File

@ -34,6 +34,7 @@
<skip_maven_deploy>true</skip_maven_deploy>
<source.level>1.8</source.level>
<target.level>1.8</target.level>
<protobuf-java.version>3.18.3</protobuf-java.version>
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
</properties>
@ -118,6 +119,7 @@
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf-java.version}</version>
</dependency>
</dependencies>
@ -141,7 +143,7 @@
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
<protocArtifact>com.google.protobuf:protoc:${protobuf-java.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>triple-java</pluginId>
<outputDirectory>build/generated/source/proto/main/java</outputDirectory>
</configuration>

View File

@ -113,7 +113,7 @@
<cxf_version>3.1.15</cxf_version>
<thrift_version>0.15.0</thrift_version>
<hessian_version>4.0.38</hessian_version>
<protobuf-java_version>3.16.3</protobuf-java_version>
<protobuf-java_version>3.18.3</protobuf-java_version>
<javax_annotation-api_version>1.3.2</javax_annotation-api_version>
<servlet_version>3.1.0</servlet_version>
<jetty_version>9.4.43.v20210629</jetty_version>
@ -914,4 +914,5 @@
</build>
</profile>
</profiles>
</project>

View File

@ -644,12 +644,6 @@
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>

View File

@ -274,12 +274,6 @@
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>

View File

@ -1065,19 +1065,6 @@
}
]
},
{
"name": "org.apache.dubbo.common.serialize.hessian2.dubbo.DefaultHessian2FactoryInitializer",
"allPublicMethods": true,
"methods": [
{
"name": "<init>",
"parameterTypes": []
}
]
},
{
"name": "org.apache.dubbo.common.serialize.hessian2.dubbo.WhitelistHessian2FactoryInitializer"
},
{
"name": "org.apache.dubbo.common.status.reporter.FrameworkStatusReportService",
"methods": [

View File

@ -28,9 +28,6 @@
{
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization\\E"
},
{
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer\\E"
},
{
"pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool\\E"
},

View File

@ -0,0 +1,40 @@
/*
* 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.nacos.function;
import java.util.function.Function;
import com.alibaba.nacos.api.exception.NacosException;
/**
* A function interface for action with {@link NacosException}
*
* @see Function
* @see NacosException
* @since 3.1.5
*/
@FunctionalInterface
public interface NacosConsumer<T> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @throws NacosException if met with any error
*/
void accept(T t) throws NacosException;
}

View File

@ -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.registry.nacos.function;
import java.util.function.Function;
import com.alibaba.nacos.api.exception.NacosException;
/**
* A function interface for action with {@link NacosException}
*
* @see Function
* @see NacosException
* @since 3.1.5
*/
@FunctionalInterface
public interface NacosFunction<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
* @throws NacosException if met with any error
*/
R apply(T t) throws NacosException;
}

View File

@ -0,0 +1,289 @@
/*
* 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.nacos;
import java.util.List;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.selector.AbstractSelector;
public class MockNamingService implements NamingService {
@Override
public void registerInstance(String serviceName, String ip, int port) throws NacosException {
}
@Override
public void registerInstance(String serviceName, String groupName, String ip, int port) throws NacosException {
}
@Override
public void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException {
}
@Override
public void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {
}
@Override
public void registerInstance(String serviceName, Instance instance) throws NacosException {
}
@Override
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
}
@Override
public void batchRegisterInstance(String serviceName, String groupName, List<Instance> instances) throws NacosException {
}
@Override
public void deregisterInstance(String serviceName, String ip, int port) throws NacosException {
}
@Override
public void deregisterInstance(String serviceName, String groupName, String ip, int port) throws NacosException {
}
@Override
public void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException {
}
@Override
public void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException {
}
@Override
public void deregisterInstance(String serviceName, Instance instance) throws NacosException {
}
@Override
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
}
@Override
public List<Instance> getAllInstances(String serviceName) throws NacosException {
return null;
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName) throws NacosException {
return null;
}
@Override
public List<Instance> getAllInstances(String serviceName, boolean subscribe) throws NacosException {
return null;
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName, boolean subscribe) throws NacosException {
return null;
}
@Override
public List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException {
return null;
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters) throws NacosException {
return null;
}
@Override
public List<Instance> getAllInstances(String serviceName, List<String> clusters, boolean subscribe) throws NacosException {
return null;
}
@Override
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, boolean healthy, boolean subscribe) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException {
return null;
}
@Override
public List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe) throws NacosException {
return null;
}
@Override
public Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
return null;
}
@Override
public void subscribe(String serviceName, EventListener listener) throws NacosException {
}
@Override
public void subscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
}
@Override
public void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
}
@Override
public void subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException {
}
@Override
public void unsubscribe(String serviceName, EventListener listener) throws NacosException {
}
@Override
public void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException {
}
@Override
public void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException {
}
@Override
public void unsubscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException {
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException {
return null;
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException {
return null;
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException {
return null;
}
@Override
public ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException {
return null;
}
@Override
public List<ServiceInfo> getSubscribeServices() throws NacosException {
return null;
}
@Override
public String getServerStatus() {
return null;
}
@Override
public void shutDown() throws NacosException {
}
}

View File

@ -16,9 +16,19 @@
*/
package org.apache.dubbo.registry.nacos;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.registry.NotifyListener;
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 com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
@ -26,16 +36,6 @@ import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.client.naming.NacosNamingService;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
@ -103,7 +103,7 @@ class NacosRegistryTest {
// ignore
}
NacosNamingServiceWrapper nacosNamingServiceWrapper = new NacosNamingServiceWrapper(new NacosConnectionManager(namingService));
NacosNamingServiceWrapper nacosNamingServiceWrapper = new NacosNamingServiceWrapper(new NacosConnectionManager(namingService, 0, 0));
nacosRegistry = new NacosRegistry(this.registryUrl, nacosNamingServiceWrapper);
Set<URL> registered;
@ -143,7 +143,7 @@ class NacosRegistryTest {
// ignore
}
NacosNamingServiceWrapper nacosNamingServiceWrapper = new NacosNamingServiceWrapper(new NacosConnectionManager(namingService));
NacosNamingServiceWrapper nacosNamingServiceWrapper = new NacosNamingServiceWrapper(new NacosConnectionManager(namingService, 0, 0));
nacosRegistry = new NacosRegistry(this.registryUrl, nacosNamingServiceWrapper);
nacosRegistry.register(serviceUrl);
@ -183,7 +183,7 @@ class NacosRegistryTest {
// ignore
}
NacosNamingServiceWrapper nacosNamingServiceWrapper = new NacosNamingServiceWrapper(new NacosConnectionManager(namingService));
NacosNamingServiceWrapper nacosNamingServiceWrapper = new NacosNamingServiceWrapper(new NacosConnectionManager(namingService, 0, 0));
nacosRegistry = new NacosRegistry(this.registryUrl, nacosNamingServiceWrapper);
NotifyListener listener = mock(NotifyListener.class);
@ -222,7 +222,7 @@ class NacosRegistryTest {
}
NacosNamingServiceWrapper nacosNamingServiceWrapper = new
NacosNamingServiceWrapper(new NacosConnectionManager(namingService));
NacosNamingServiceWrapper(new NacosConnectionManager(namingService, 0, 0));
nacosRegistry = new NacosRegistry(this.registryUrl, nacosNamingServiceWrapper);
NotifyListener listener = mock(NotifyListener.class);
@ -276,7 +276,7 @@ class NacosRegistryTest {
}
NacosNamingServiceWrapper nacosNamingServiceWrapper = new
NacosNamingServiceWrapper(new NacosConnectionManager(namingService));
NacosNamingServiceWrapper(new NacosConnectionManager(namingService, 0, 0));
nacosRegistry = new NacosRegistry(this.registryUrl, nacosNamingServiceWrapper);
Set<URL> registered;

View File

@ -0,0 +1,91 @@
/*
* 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.rpc.protocol;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProtocolServer;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import org.apache.dubbo.rpc.model.ServiceDescriptor;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.util.List;
import java.util.Optional;
@Activate(order = 200)
public class ProtocolSecurityWrapper implements Protocol {
private final Protocol protocol;
public ProtocolSecurityWrapper(Protocol protocol) {
if (protocol == null) {
throw new IllegalArgumentException("protocol == null");
}
this.protocol = protocol;
}
@Override
public int getDefaultPort() {
return protocol.getDefaultPort();
}
@Override
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
ServiceModel serviceModel = invoker.getUrl().getServiceModel();
ScopeModel scopeModel = invoker.getUrl().getScopeModel();
Optional.ofNullable(serviceModel)
.map(ServiceModel::getServiceModel)
.map(ServiceDescriptor::getServiceInterfaceClass)
.ifPresent((interfaceClass) -> {
SerializeSecurityManager serializeSecurityManager = ScopeModelUtil.getFrameworkModel(scopeModel)
.getBeanFactory().getBean(SerializeSecurityManager.class);
serializeSecurityManager.registerInterface(interfaceClass);
});
return protocol.export(invoker);
}
@Override
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
ServiceModel serviceModel = url.getServiceModel();
ScopeModel scopeModel = url.getScopeModel();
SerializeSecurityManager serializeSecurityManager = ScopeModelUtil.getFrameworkModel(scopeModel)
.getBeanFactory().getBean(SerializeSecurityManager.class);
Optional.ofNullable(serviceModel)
.map(ServiceModel::getServiceModel)
.map(ServiceDescriptor::getServiceInterfaceClass)
.ifPresent(serializeSecurityManager::registerInterface);
serializeSecurityManager.registerInterface(type);
return protocol.refer(type, url);
}
@Override
public void destroy() {
protocol.destroy();
}
@Override
public List<ProtocolServer> getServers() {
return protocol.getServers();
}
}

View File

@ -1,3 +1,4 @@
listener=org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=org.apache.dubbo.rpc.support.MockProtocol
serializationwrapper=org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper
securitywrapper=org.apache.dubbo.rpc.protocol.ProtocolSecurityWrapper

View File

@ -32,6 +32,7 @@
<dubbo.compiler.version>0.0.4.1-SNAPSHOT</dubbo.compiler.version>
<reactive.version>1.0.4</reactive.version>
<reactor.version>3.4.19</reactor.version>
<protobuf-java.version>3.18.3</protobuf-java.version>
</properties>
<dependencies>
<dependency>
@ -52,6 +53,7 @@
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf-java.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
@ -112,7 +114,7 @@
<version>0.6.1</version>
<configuration>
<protocArtifact>
com.google.protobuf:protoc:3.11.0:exe:${os.detected.classifier}
com.google.protobuf:protoc:${protobuf-java.version}:exe:${os.detected.classifier}
</protocArtifact>
<protocPlugins>
<protocPlugin>

View File

@ -32,11 +32,15 @@ public class FastJson2ObjectInput implements ObjectInput {
private final Fastjson2CreatorManager fastjson2CreatorManager;
private final Fastjson2SecurityManager fastjson2SecurityManager;
private volatile ClassLoader classLoader;
private final InputStream is;
public FastJson2ObjectInput(Fastjson2CreatorManager fastjson2CreatorManager, InputStream in) {
public FastJson2ObjectInput(Fastjson2CreatorManager fastjson2CreatorManager,
Fastjson2SecurityManager fastjson2SecurityManager, InputStream in) {
this.fastjson2CreatorManager = fastjson2CreatorManager;
this.fastjson2SecurityManager = fastjson2SecurityManager;
this.classLoader = Thread.currentThread().getContextClassLoader();
this.is = in;
fastjson2CreatorManager.setCreator(classLoader);
@ -107,8 +111,9 @@ public class FastJson2ObjectInput implements ObjectInput {
if (read != length) {
throw new IllegalArgumentException("deserialize failed. expected read length: " + length + " but actual read: " + read);
}
return (T) JSONB.parseObject(bytes, Object.class, JSONReader.Feature.SupportAutoType,
return (T) JSONB.parseObject(bytes, Object.class, fastjson2SecurityManager.getSecurityFilter(),
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.ErrorOnNoneSerializable,
JSONReader.Feature.UseNativeObject,
JSONReader.Feature.FieldBased);
}
@ -123,8 +128,9 @@ public class FastJson2ObjectInput implements ObjectInput {
if (read != length) {
throw new IllegalArgumentException("deserialize failed. expected read length: " + length + " but actual read: " + read);
}
return (T) JSONB.parseObject(bytes, Object.class, JSONReader.Feature.SupportAutoType,
return (T) JSONB.parseObject(bytes, Object.class, fastjson2SecurityManager.getSecurityFilter(),
JSONReader.Feature.UseDefaultConstructorAsPossible,
JSONReader.Feature.ErrorOnNoneSerializable,
JSONReader.Feature.UseNativeObject,
JSONReader.Feature.FieldBased);
}

View File

@ -98,6 +98,7 @@ public class FastJson2ObjectOutput implements ObjectOutput {
updateClassLoaderIfNeed();
byte[] bytes = JSONB.toBytes(obj, JSONWriter.Feature.WriteClassName,
JSONWriter.Feature.FieldBased,
JSONWriter.Feature.ErrorOnNoneSerializable,
JSONWriter.Feature.ReferenceDetection,
JSONWriter.Feature.WriteNulls,
JSONWriter.Feature.NotWriteDefaultValue,

View File

@ -39,8 +39,11 @@ public class FastJson2Serialization implements Serialization {
private final Fastjson2CreatorManager fastjson2CreatorManager;
private final Fastjson2SecurityManager fastjson2SecurityManager;
public FastJson2Serialization(FrameworkModel frameworkModel) {
this.fastjson2CreatorManager = frameworkModel.getBeanFactory().getBean(Fastjson2CreatorManager.class);
this.fastjson2SecurityManager = frameworkModel.getBeanFactory().getBean(Fastjson2SecurityManager.class);
}
@Override
@ -60,7 +63,7 @@ public class FastJson2Serialization implements Serialization {
@Override
public ObjectInput deserialize(URL url, InputStream input) throws IOException {
return new FastJson2ObjectInput(fastjson2CreatorManager, input);
return new FastJson2ObjectInput(fastjson2CreatorManager, fastjson2SecurityManager, input);
}
}

View File

@ -23,10 +23,12 @@ import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
public class Fastjson2ScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(Fastjson2CreatorManager.class);
beanFactory.registerBean(Fastjson2SecurityManager.class);
}
@Override

View File

@ -0,0 +1,128 @@
/*
* 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.serialize.fastjson2;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.AllowClassNotifyListener;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.SerializeCheckStatus;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.fastjson2.filter.ContextAutoTypeBeforeHandler;
import com.alibaba.fastjson2.filter.Filter;
import com.alibaba.fastjson2.util.TypeUtils;
import static com.alibaba.fastjson2.util.TypeUtils.loadClass;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNTRUSTED_SERIALIZE_CLASS;
import static org.apache.dubbo.common.utils.SerializeCheckStatus.STRICT;
public class Fastjson2SecurityManager implements AllowClassNotifyListener {
private Filter securityFilter = new Handler(AllowClassNotifyListener.DEFAULT_STATUS, new String[0]);
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(Fastjson2SecurityManager.class);
private static final Set<String> warnedClasses = new ConcurrentHashSet<>(1);
public Fastjson2SecurityManager(FrameworkModel frameworkModel) {
SerializeSecurityManager securityManager = frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
securityManager.registerListener(this);
}
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
this.securityFilter = new Handler(status, prefixList.toArray(new String[0]));
}
public Filter getSecurityFilter() {
return securityFilter;
}
public static class Handler extends ContextAutoTypeBeforeHandler {
final SerializeCheckStatus status;
final Map<String, Class<?>> classCache = new ConcurrentHashMap<>(16, 0.75f, 1);
public Handler(SerializeCheckStatus status, String[] acceptNames) {
super(true, acceptNames);
this.status = status;
}
@Override
public Class<?> apply(String typeName, Class<?> expectClass, long features) {
Class<?> tryLoad = super.apply(typeName, expectClass, features);
// 1. in allow list, return
if (tryLoad != null) {
return tryLoad;
}
// 2. check if in strict mode
if (status == STRICT) {
String msg = "[Serialization Security] Serialized class " + typeName + " is not in allow list. " +
"Current mode is `STRICT`, will disallow to deserialize it by default. " +
"Please add it into security/serialize.allowlist or follow FAQ to configure it.";
if (warnedClasses.add(typeName)) {
logger.error(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "", msg);
}
return null;
}
// 3. try load
Class<?> localClass = loadClassDirectly(typeName);
if (localClass != null) {
if (status == SerializeCheckStatus.WARN && warnedClasses.add(typeName)) {
logger.error(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "",
"[Serialization Security] Serialized class " + localClass.getName() + " is not in allow list. " +
"Current mode is `WARN`, will allow to deserialize it by default. " +
"Dubbo will set to `STRICT` mode by default in the future. " +
"Please add it into security/serialize.allowlist or follow FAQ to configure it.");
}
return localClass;
}
// 4. class not found
return null;
}
public Class<?> loadClassDirectly(String typeName) {
Class<?> clazz = classCache.get(typeName);
if (clazz == null) {
clazz = TypeUtils.getMapping(typeName);
}
if (clazz == null) {
clazz = loadClass(typeName);
}
if (clazz != null) {
Class<?> origin = classCache.putIfAbsent(typeName, clazz);
if (origin != null) {
clazz = origin;
}
}
return clazz;
}
}
}

View File

@ -0,0 +1,120 @@
/*
* 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.serialize.hessian2;
import java.util.Arrays;
import java.util.Set;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.AllowClassNotifyListener;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.SerializeCheckStatus;
import org.apache.dubbo.common.utils.SerializeSecurityManager;
import org.apache.dubbo.rpc.model.FrameworkModel;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_UNTRUSTED_SERIALIZE_CLASS;
/**
* Inspired by Fastjson2
* see com.alibaba.fastjson2.filter.ContextAutoTypeBeforeHandler#apply(java.lang.String, java.lang.Class, long)
*/
public class Hessian2AllowClassManager implements AllowClassNotifyListener {
private static final long MAGIC_HASH_CODE = 0xcbf29ce484222325L;
private static final long MAGIC_PRIME = 0x100000001b3L;
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(Hessian2AllowClassManager.class);
private volatile SerializeCheckStatus checkStatus = AllowClassNotifyListener.DEFAULT_STATUS;
private static final Set<String> warnedClasses = new ConcurrentHashSet<>(1);
private volatile long[] allowPrefixes = new long[0];
public Hessian2AllowClassManager(FrameworkModel frameworkModel) {
SerializeSecurityManager serializeSecurityManager = frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
serializeSecurityManager.registerListener(this);
}
@Override
public void notify(SerializeCheckStatus status, Set<String> prefixList) {
this.checkStatus = status;
long[] array = new long[prefixList.size()];
int index = 0;
for (String name : prefixList) {
if (name == null || name.isEmpty()) {
continue;
}
long hashCode = MAGIC_HASH_CODE;
for (int j = 0; j < name.length(); ++j) {
char ch = name.charAt(j);
if (ch == '$') {
ch = '.';
}
hashCode ^= ch;
hashCode *= MAGIC_PRIME;
}
array[index++] = hashCode;
}
if (index != array.length) {
array = Arrays.copyOf(array, index);
}
Arrays.sort(array);
this.allowPrefixes = array;
}
public Class<?> loadClass(ClassLoader classLoader, String className) throws ClassNotFoundException {
if (checkStatus == SerializeCheckStatus.DISABLED) {
return Class.forName(className, false, classLoader);
}
long hash = MAGIC_HASH_CODE;
for (int i = 0, typeNameLength = className.length(); i < typeNameLength; ++i) {
char ch = className.charAt(i);
if (ch == '$') {
ch = '.';
}
hash ^= ch;
hash *= MAGIC_PRIME;
if (Arrays.binarySearch(allowPrefixes, hash) >= 0) {
return Class.forName(className, false, classLoader);
}
}
if (checkStatus == SerializeCheckStatus.STRICT) {
String msg = "[Serialization Security] Serialized class " + className + " is not in allow list. " +
"Current mode is `STRICT`, will disallow to deserialize it by default. " +
"Please add it into security/serialize.allowlist or follow FAQ to configure it.";
if (warnedClasses.add(className)) {
logger.error(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "", msg);
}
throw new IllegalArgumentException(msg);
} else {
Class<?> clazz = Class.forName(className, false, classLoader);
if (warnedClasses.add(className)) {
logger.error(PROTOCOL_UNTRUSTED_SERIALIZE_CLASS, "", "",
"[Serialization Security] Serialized class " + clazz.getName() + " is not in allow list. " +
"Current mode is `WARN`, will allow to deserialize it by default. " +
"Dubbo will set to `STRICT` mode by default in the future. " +
"Please add it into security/serialize.allowlist or follow FAQ to configure it.");
}
return clazz;
}
}
}

View File

@ -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.common.serialize.hessian2;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ScopeClassLoaderListener;
public class Hessian2ClassLoaderListener implements ScopeClassLoaderListener<FrameworkModel> {
@Override
public void onAddClassLoader(FrameworkModel scopeModel, ClassLoader classLoader) {
// noop
}
@Override
public void onRemoveClassLoader(FrameworkModel scopeModel, ClassLoader classLoader) {
Hessian2FactoryManager hessian2FactoryManager = scopeModel.getBeanFactory().getBean(Hessian2FactoryManager.class);
hessian2FactoryManager.onRemoveClassLoader(classLoader);
}
}

View File

@ -0,0 +1,110 @@
/*
* 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.serialize.hessian2;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Hessian2FactoryManager {
String WHITELIST = "dubbo.application.hessian2.whitelist";
String ALLOW = "dubbo.application.hessian2.allow";
String DENY = "dubbo.application.hessian2.deny";
private volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
private final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
private final Hessian2AllowClassManager hessian2AllowClassManager;
public Hessian2FactoryManager(FrameworkModel frameworkModel) {
hessian2AllowClassManager = new Hessian2AllowClassManager(frameworkModel);
}
public SerializerFactory getSerializerFactory(ClassLoader classLoader) {
if (classLoader == null) {
// system classloader
if (SYSTEM_SERIALIZER_FACTORY == null) {
synchronized (this) {
if (SYSTEM_SERIALIZER_FACTORY == null) {
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory();
}
}
}
return SYSTEM_SERIALIZER_FACTORY;
}
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
synchronized (this) {
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
SerializerFactory serializerFactory = createSerializerFactory();
CL_2_SERIALIZER_FACTORY.put(classLoader, serializerFactory);
return serializerFactory;
}
}
}
return CL_2_SERIALIZER_FACTORY.get(classLoader);
}
private SerializerFactory createSerializerFactory() {
String whitelist = System.getProperty(WHITELIST);
if (StringUtils.isNotEmpty(whitelist)) {
return createWhiteListSerializerFactory();
}
return createDefaultSerializerFactory();
}
private SerializerFactory createDefaultSerializerFactory() {
Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory(hessian2AllowClassManager);
hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
hessian2SerializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return hessian2SerializerFactory;
}
public SerializerFactory createWhiteListSerializerFactory() {
SerializerFactory serializerFactory = new Hessian2SerializerFactory(hessian2AllowClassManager);
String whiteList = System.getProperty(WHITELIST);
if ("true".equals(whiteList)) {
serializerFactory.getClassFactory().setWhitelist(true);
String allowPattern = System.getProperty(ALLOW);
if (StringUtils.isNotEmpty(allowPattern)) {
for (String pattern : allowPattern.split(";")) {
serializerFactory.getClassFactory().allow(pattern);
}
}
} else {
serializerFactory.getClassFactory().setWhitelist(false);
String denyPattern = System.getProperty(DENY);
if (StringUtils.isNotEmpty(denyPattern)) {
for (String pattern : denyPattern.split(";")) {
serializerFactory.getClassFactory().deny(pattern);
}
}
}
serializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false")));
serializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return serializerFactory;
}
public void onRemoveClassLoader(ClassLoader classLoader) {
CL_2_SERIALIZER_FACTORY.remove(classLoader);
}
}

View File

@ -18,7 +18,7 @@ package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.serialize.Cleanable;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.Hessian2Input;
@ -31,12 +31,19 @@ import java.lang.reflect.Type;
*/
public class Hessian2ObjectInput implements ObjectInput, Cleanable {
private final Hessian2Input mH2i;
private final Hessian2FactoryInitializer hessian2FactoryInitializer;
private final Hessian2FactoryManager hessian2FactoryManager;
@Deprecated
public Hessian2ObjectInput(InputStream is) {
mH2i = new Hessian2Input(is);
hessian2FactoryInitializer = Hessian2FactoryInitializer.getInstance();
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
this.hessian2FactoryManager = FrameworkModel.defaultModel().getBeanFactory().getOrRegisterBean(Hessian2FactoryManager.class);
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
public Hessian2ObjectInput(InputStream is, Hessian2FactoryManager hessian2FactoryManager) {
mH2i = new Hessian2Input(is);
this.hessian2FactoryManager = hessian2FactoryManager;
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
@Override
@ -87,7 +94,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
@Override
public Object readObject() throws IOException {
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
return mH2i.readObject();
}
@ -97,7 +104,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
public <T> T readObject(Class<T> cls) throws IOException,
ClassNotFoundException {
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
return (T) mH2i.readObject(cls);
}
@ -105,7 +112,7 @@ public class Hessian2ObjectInput implements ObjectInput, Cleanable {
@Override
public <T> T readObject(Class<T> cls, Type type) throws IOException, ClassNotFoundException {
if (!mH2i.getSerializerFactory().getClassLoader().equals(Thread.currentThread().getContextClassLoader())) {
mH2i.setSerializerFactory(hessian2FactoryInitializer.getSerializerFactory());
mH2i.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
return readObject(cls);
}

View File

@ -18,7 +18,7 @@ package org.apache.dubbo.common.serialize.hessian2;
import org.apache.dubbo.common.serialize.Cleanable;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.hessian2.dubbo.Hessian2FactoryInitializer;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.Hessian2Output;
@ -32,9 +32,16 @@ public class Hessian2ObjectOutput implements ObjectOutput, Cleanable {
private final Hessian2Output mH2o;
@Deprecated
public Hessian2ObjectOutput(OutputStream os) {
mH2o = new Hessian2Output(os);
mH2o.setSerializerFactory(Hessian2FactoryInitializer.getInstance().getSerializerFactory());
Hessian2FactoryManager hessian2FactoryManager = FrameworkModel.defaultModel().getBeanFactory().getOrRegisterBean(Hessian2FactoryManager.class);
mH2o.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
public Hessian2ObjectOutput(OutputStream os, Hessian2FactoryManager hessian2FactoryManager) {
mH2o = new Hessian2Output(os);
mH2o.setSerializerFactory(hessian2FactoryManager.getSerializerFactory(Thread.currentThread().getContextClassLoader()));
}
@Override

View File

@ -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.serialize.hessian2;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(Hessian2FactoryManager.class);
}
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
}
@Override
public void initializeModuleModel(ModuleModel moduleModel) {
}
}

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.Serialization;
import org.apache.dubbo.rpc.model.FrameworkModel;
import java.io.IOException;
import java.io.InputStream;
@ -36,6 +37,12 @@ import static org.apache.dubbo.common.serialize.Constants.HESSIAN2_SERIALIZATION
*/
public class Hessian2Serialization implements Serialization {
private final Hessian2FactoryManager hessian2FactoryManager;
public Hessian2Serialization(FrameworkModel frameworkModel) {
hessian2FactoryManager = frameworkModel.getBeanFactory().getBean(Hessian2FactoryManager.class);
}
@Override
public byte getContentTypeId() {
return HESSIAN2_SERIALIZATION_ID;
@ -48,12 +55,12 @@ public class Hessian2Serialization implements Serialization {
@Override
public ObjectOutput serialize(URL url, OutputStream out) throws IOException {
return new Hessian2ObjectOutput(out);
return new Hessian2ObjectOutput(out, hessian2FactoryManager);
}
@Override
public ObjectInput deserialize(URL url, InputStream is) throws IOException {
return new Hessian2ObjectInput(is);
return new Hessian2ObjectInput(is, hessian2FactoryManager);
}
}

View File

@ -20,7 +20,14 @@ import com.alibaba.com.caucho.hessian.io.SerializerFactory;
public class Hessian2SerializerFactory extends SerializerFactory {
public Hessian2SerializerFactory() {
private Hessian2AllowClassManager hessian2AllowClassManager;
public Hessian2SerializerFactory(Hessian2AllowClassManager hessian2AllowClassManager) {
this.hessian2AllowClassManager = hessian2AllowClassManager;
}
@Override
public Class<?> loadSerializedClass(String className) throws ClassNotFoundException {
return hessian2AllowClassManager.loadClass(getClassLoader(), className);
}
}

View File

@ -1,56 +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.common.serialize.hessian2.dubbo;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class AbstractHessian2FactoryInitializer implements Hessian2FactoryInitializer {
private static final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY = new ConcurrentHashMap<>();
private static volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
@Override
public SerializerFactory getSerializerFactory() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
// system classloader
if (SYSTEM_SERIALIZER_FACTORY == null) {
synchronized (AbstractHessian2FactoryInitializer.class) {
if (SYSTEM_SERIALIZER_FACTORY == null) {
SYSTEM_SERIALIZER_FACTORY = createSerializerFactory();
}
}
}
return SYSTEM_SERIALIZER_FACTORY;
}
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
synchronized (AbstractHessian2FactoryInitializer.class) {
if (!CL_2_SERIALIZER_FACTORY.containsKey(classLoader)) {
SerializerFactory serializerFactory = createSerializerFactory();
CL_2_SERIALIZER_FACTORY.put(classLoader, serializerFactory);
return serializerFactory;
}
}
}
return CL_2_SERIALIZER_FACTORY.get(classLoader);
}
protected abstract SerializerFactory createSerializerFactory();
}

View File

@ -1,45 +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.common.serialize.hessian2.dubbo;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.FrameworkModel;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
@SPI(value = "default", scope = ExtensionScope.FRAMEWORK)
public interface Hessian2FactoryInitializer {
String ALLOW = System.getProperty("dubbo.application.hessian2.allow");
String DENY = System.getProperty("dubbo.application.hessian2.deny");
String WHITELIST = System.getProperty("dubbo.application.hessian2.whitelist");
String ALLOW_NON_SERIALIZABLE = System.getProperty("dubbo.hessian.allowNonSerializable", "false");
SerializerFactory getSerializerFactory();
static Hessian2FactoryInitializer getInstance() {
ExtensionLoader<Hessian2FactoryInitializer> loader = FrameworkModel.defaultModel().getExtensionLoader(Hessian2FactoryInitializer.class);
if (StringUtils.isNotEmpty(WHITELIST)) {
return loader.getExtension("whitelist");
}
return loader.getDefaultExtension();
}
}

View File

@ -1,52 +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.common.serialize.hessian2.dubbo;
import org.apache.dubbo.common.serialize.hessian2.Hessian2SerializerFactory;
import org.apache.dubbo.common.utils.StringUtils;
import com.alibaba.com.caucho.hessian.io.SerializerFactory;
/**
* see https://github.com/ebourg/hessian/commit/cf851f5131707891e723f7f6a9718c2461aed826
*/
public class WhitelistHessian2FactoryInitializer extends AbstractHessian2FactoryInitializer {
@Override
public SerializerFactory createSerializerFactory() {
SerializerFactory serializerFactory = new Hessian2SerializerFactory();
if ("true".equals(WHITELIST)) {
serializerFactory.getClassFactory().setWhitelist(true);
if (StringUtils.isNotEmpty(ALLOW)) {
for (String pattern : ALLOW.split(";")) {
serializerFactory.getClassFactory().allow(pattern);
}
}
} else {
serializerFactory.getClassFactory().setWhitelist(false);
if (StringUtils.isNotEmpty(DENY)) {
for (String pattern : DENY.split(";")) {
serializerFactory.getClassFactory().deny(pattern);
}
}
}
serializerFactory.setAllowNonSerializable(Boolean.parseBoolean(ALLOW_NON_SERIALIZABLE));
serializerFactory.getClassFactory().allow("org.apache.dubbo.*");
return serializerFactory;
}
}

View File

@ -1,2 +0,0 @@
default=org.apache.dubbo.common.serialize.hessian2.dubbo.DefaultHessian2FactoryInitializer
whitelist=org.apache.dubbo.common.serialize.hessian2.dubbo.WhitelistHessian2FactoryInitializer

View File

@ -0,0 +1 @@
hessian2=org.apache.dubbo.common.serialize.hessian2.Hessian2ScopeModelInitializer

View File

@ -31,6 +31,8 @@
<description>The xDS Integration</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
<protobuf-java.version>3.18.3</protobuf-java.version>
<grpc.version>1.41.0</grpc.version>
</properties>
<dependencies>
@ -50,16 +52,19 @@
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
@ -67,9 +72,16 @@
<artifactId>api</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf-java.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf-java.version}</version>
</dependency>
<dependency>
@ -101,9 +113,9 @@
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
<protocArtifact>com.google.protobuf:protoc:${protobuf-java.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.31.1:exe:${os.detected.classifier}</pluginArtifact>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>

View File

@ -885,4 +885,5 @@
</plugins>
</pluginManagement>
</build>
</project>