[3.0] Multi Instances Related Refactor (#8737)

* Refactor some ExtensionLoader usage

* Fix ut

* Refactor some ExtensionLoader usage

* Introduce Initializer for ScopeModel

* Fix ut

* Fix ut

* Add TCCL Changer

* remove some default model usage

* remove some default model usage

* Fix NPE

* Remove Hessian2 TL

* Fix NPE

* Fix NPE

* Fix Shade

* Fix DubboBootstrap init

* Fix Metadata Serialize

* Fix not support multi classloader

* Add Multi ClassLoader Test case

* Fix UT

* add ant

* Fix UT

* Fix Merge Directory
This commit is contained in:
Albumen Kevin 2021-09-10 14:43:34 +08:00 committed by GitHub
parent 1b100f84cb
commit 1dfb114734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
116 changed files with 1148 additions and 474 deletions

View File

@ -17,11 +17,12 @@
package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
/**
* Cluster. (SPI, Singleton, ThreadSafe)
@ -46,14 +47,14 @@ public interface Cluster {
@Adaptive
<T> Invoker<T> join(Directory<T> directory) throws RpcException;
static Cluster getCluster(String name) {
return getCluster(name, true);
static Cluster getCluster(ScopeModel scopeModel, String name) {
return getCluster(scopeModel, name, true);
}
static Cluster getCluster(String name, boolean wrap) {
static Cluster getCluster(ScopeModel scopeModel, String name, boolean wrap) {
if (StringUtils.isEmpty(name)) {
name = Cluster.DEFAULT;
}
return ExtensionLoader.getExtensionLoader(Cluster.class).getExtension(name, wrap);
return ScopeModelUtil.getApplicationModel(scopeModel).getExtensionLoader(Cluster.class).getExtension(name, wrap);
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.cluster;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
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 ClusterScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
}
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(MergerFactory.class);
beanFactory.registerBean(ClusterUtils.class);
}
@Override
public void initializeModuleModel(ModuleModel moduleModel) {
}
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.CollectionUtils;
import java.util.ArrayList;
@ -74,7 +73,7 @@ public interface Configurator extends Comparable<Configurator> {
return Optional.empty();
}
ConfiguratorFactory configuratorFactory = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
ConfiguratorFactory configuratorFactory = urls.get(0).getOrDefaultApplicationModel().getExtensionLoader(ConfiguratorFactory.class)
.getAdaptiveExtension();
List<Configurator> configurators = new ArrayList<>(urls.size());

View File

@ -18,7 +18,6 @@ package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
@ -71,8 +70,7 @@ public class RouterChain<T> {
private List<StateRouter> builtinStateRouters = Collections.emptyList();
private List<StateRouter> stateRouters = Collections.emptyList();
private final ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class)
.getDefaultExtension();
private final ExecutorRepository executorRepository;
protected URL url;
@ -90,8 +88,10 @@ public class RouterChain<T> {
}
private RouterChain(URL url) {
executorRepository = url.getOrDefaultApplicationModel().getExtensionLoader(ExecutorRepository.class)
.getDefaultExtension();
loopPool = executorRepository.nextExecutorExecutor();
List<RouterFactory> extensionFactories = ExtensionLoader.getExtensionLoader(RouterFactory.class)
List<RouterFactory> extensionFactories = url.getOrDefaultApplicationModel().getExtensionLoader(RouterFactory.class)
.getActivateExtension(url, ROUTER_KEY);
List<Router> routers = extensionFactories.stream()
@ -101,8 +101,8 @@ public class RouterChain<T> {
initWithRouters(routers);
List<StateRouterFactory> extensionStateRouterFactories = ExtensionLoader.getExtensionLoader(
StateRouterFactory.class)
List<StateRouterFactory> extensionStateRouterFactories = url.getOrDefaultApplicationModel()
.getExtensionLoader(StateRouterFactory.class)
.getActivateExtension(url, STATE_ROUTER_KEY);
List<StateRouter> stateRouters = extensionStateRouterFactories.stream()

View File

@ -27,6 +27,7 @@ import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.Router;
import org.apache.dubbo.rpc.cluster.RouterChain;
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Collections;
import java.util.List;
@ -84,7 +85,8 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
}
// remove some local only parameters
this.queryMap = ClusterUtils.mergeLocalParams(queryMap);
ApplicationModel applicationModel = url.getOrDefaultApplicationModel();
this.queryMap = applicationModel.getBeanFactory().getBean(ClusterUtils.class).mergeLocalParams(queryMap);
if (consumerUrl == null) {
String host = StringUtils.isNotEmpty(queryMap.get("register.ip")) ? queryMap.get("register.ip") : this.url.getHost();
@ -98,7 +100,7 @@ public abstract class AbstractDirectory<T> implements Directory<T> {
.setPath(path == null ? queryMap.get(INTERFACE_KEY) : path);
if (isUrlFromRegistry) {
// reserve parameters if url is already a consumer url
consumerUrlFrom = consumerUrlFrom.clearParameters();
consumerUrlFrom = consumerUrlFrom.clearParameters().setServiceModel(url.getServiceModel()).setScopeModel(url.getScopeModel());
}
this.consumerUrl = consumerUrlFrom.addParameters(queryMap).removeAttribute(MONITOR_KEY);
}

View File

@ -31,6 +31,7 @@ import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.TimeoutCountDown;
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Map;
import java.util.Set;
@ -49,6 +50,12 @@ import static org.apache.dubbo.common.constants.CommonConstants.TIME_COUNTDOWN_K
@Activate(group = CONSUMER, order = -10000)
public class ConsumerContextFilter implements ClusterFilter, ClusterFilter.Listener {
private ApplicationModel applicationModel;
public ConsumerContextFilter(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
RpcContext.getServiceContext()
@ -61,7 +68,7 @@ public class ConsumerContextFilter implements ClusterFilter, ClusterFilter.Liste
((RpcInvocation) invocation).setInvoker(invoker);
}
ExtensionLoader<PenetrateAttachmentSelector> selectorExtensionLoader = ExtensionLoader.getExtensionLoader(PenetrateAttachmentSelector.class);
ExtensionLoader<PenetrateAttachmentSelector> selectorExtensionLoader = applicationModel.getExtensionLoader(PenetrateAttachmentSelector.class);
Set<String> supportedSelectors = selectorExtensionLoader.getSupportedExtensions();
if (CollectionUtils.isNotEmpty(supportedSelectors)) {
for (String supportedSelector : supportedSelectors) {

View File

@ -27,6 +27,7 @@ import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.ZoneDetector;
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_ZONE;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_ZONE_FORCE;
@ -39,12 +40,18 @@ import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_ZONE_
@Activate(group = CommonConstants.CONSUMER, value = "cluster:zone-aware")
public class ZoneAwareFilter implements ClusterFilter {
private ApplicationModel applicationModel;
public ZoneAwareFilter(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
RpcContext rpcContext = RpcContext.getClientAttachment();
String zone = (String) rpcContext.getAttachment(REGISTRY_ZONE);
String force = (String) rpcContext.getAttachment(REGISTRY_ZONE_FORCE);
ExtensionLoader<ZoneDetector> loader = ExtensionLoader.getExtensionLoader(ZoneDetector.class);
ExtensionLoader<ZoneDetector> loader = applicationModel.getExtensionLoader(ZoneDetector.class);
if (StringUtils.isEmpty(zone) && loader.hasExtension("default")) {
ZoneDetector detector = loader.getExtension("default");
zone = detector.getZoneOfCurrentRequest(invocation);

View File

@ -17,18 +17,24 @@
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.rpc.cluster.Merger;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class MergerFactory {
public class MergerFactory implements ScopeModelAware {
private static final ConcurrentMap<Class<?>, Merger<?>> MERGER_CACHE =
new ConcurrentHashMap<Class<?>, Merger<?>>();
private ConcurrentMap<Class<?>, Merger<?>> MERGER_CACHE = new ConcurrentHashMap<Class<?>, Merger<?>>();
private ScopeModel scopeModel;
@Override
public void setScopeModel(ScopeModel scopeModel) {
this.scopeModel = scopeModel;
}
/**
* Find the merger according to the returnType class, the merger will
@ -38,7 +44,7 @@ public class MergerFactory {
* @return the merger which merges an array of returnType into one, return null if not exist
* @throws IllegalArgumentException if returnType is null
*/
public static <T> Merger<T> getMerger(Class<T> returnType) {
public <T> Merger<T> getMerger(Class<T> returnType) {
if (returnType == null) {
throw new IllegalArgumentException("returnType is null");
}
@ -64,11 +70,11 @@ public class MergerFactory {
return result;
}
static void loadMergers() {
Set<String> names = ExtensionLoader.getExtensionLoader(Merger.class)
private void loadMergers() {
Set<String> names = scopeModel.getExtensionLoader(Merger.class)
.getSupportedExtensions();
for (String name : names) {
Merger m = ExtensionLoader.getExtensionLoader(Merger.class).getExtension(name);
Merger m = scopeModel.getExtensionLoader(Merger.class).getExtension(name);
MERGER_CACHE.putIfAbsent(ReflectUtils.getGenericClass(m.getClass()), m);
}
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.rpc.cluster.router;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.cluster.Router;
import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
@ -29,7 +28,7 @@ public abstract class AbstractRouter implements Router {
private GovernanceRuleRepository ruleRepository;
public AbstractRouter(URL url) {
this.ruleRepository = ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
this.ruleRepository = url.getOrDefaultApplicationModel().getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
this.url = url;
}

View File

@ -16,18 +16,17 @@
*/
package org.apache.dubbo.rpc.cluster.router.state;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.RouterChain;
import org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/***
* The abstract class of StateRoute.
* @since 3.0
@ -42,7 +41,7 @@ public abstract class AbstractStateRouter implements StateRouter {
protected GovernanceRuleRepository ruleRepository;
public AbstractStateRouter(URL url, RouterChain chain) {
this.ruleRepository = ExtensionLoader.getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
this.ruleRepository = url.getOrDefaultApplicationModel().getExtensionLoader(GovernanceRuleRepository.class).getDefaultExtension();
this.chain = chain;
this.url = url;
}

View File

@ -18,7 +18,6 @@ package org.apache.dubbo.rpc.cluster.support;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
@ -32,6 +31,8 @@ import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import org.apache.dubbo.rpc.support.RpcUtils;
import java.util.ArrayList;
@ -338,14 +339,15 @@ public abstract class AbstractClusterInvoker<T> implements ClusterInvoker<T> {
* @return LoadBalance instance. if not need init, return null.
*/
protected LoadBalance initLoadBalance(List<Invoker<T>> invokers, Invocation invocation) {
ApplicationModel applicationModel = ScopeModelUtil.getApplicationModel(invocation.getModuleModel());
if (CollectionUtils.isNotEmpty(invokers)) {
return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(
return applicationModel.getExtensionLoader(LoadBalance.class).getExtension(
invokers.get(0).getUrl().getMethodParameter(
RpcUtils.getMethodName(invocation), LOADBALANCE_KEY, DEFAULT_LOADBALANCE
)
);
} else {
return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(DEFAULT_LOADBALANCE);
return applicationModel.getExtensionLoader(LoadBalance.class).getExtension(DEFAULT_LOADBALANCE);
}
}

View File

@ -17,9 +17,10 @@
package org.apache.dubbo.rpc.cluster.support;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.cluster.ProviderURLMergeProcessor;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
import java.util.Map;
@ -29,33 +30,37 @@ import static org.apache.dubbo.common.constants.CommonConstants.URL_MERGE_PROCES
/**
* ClusterUtils
*/
public class ClusterUtils {
public class ClusterUtils implements ScopeModelAware {
private ClusterUtils() {
private ApplicationModel applicationModel;
@Override
public void setApplicationModel(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
}
public static URL mergeUrl(URL remoteUrl, Map<String, String> localMap) {
public URL mergeUrl(URL remoteUrl, Map<String, String> localMap) {
String ump = localMap.get(URL_MERGE_PROCESSOR_KEY);
ProviderURLMergeProcessor providerURLMergeProcessor;
if (StringUtils.isNotEmpty(ump)) {
providerURLMergeProcessor = ExtensionLoader.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension(ump);
providerURLMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension(ump);
} else {
providerURLMergeProcessor = ExtensionLoader.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension("default");
providerURLMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension("default");
}
return providerURLMergeProcessor.mergeUrl(remoteUrl, localMap);
}
public static Map<String, String> mergeLocalParams(Map<String, String> localMap) {
public Map<String, String> mergeLocalParams(Map<String, String> localMap) {
String ump = localMap.get(URL_MERGE_PROCESSOR_KEY);
ProviderURLMergeProcessor providerURLMergeProcessor;
if (StringUtils.isNotEmpty(ump)) {
providerURLMergeProcessor = ExtensionLoader.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension(ump);
providerURLMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension(ump);
} else {
providerURLMergeProcessor = ExtensionLoader.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension("default");
providerURLMergeProcessor = applicationModel.getExtensionLoader(ProviderURLMergeProcessor.class).getExtension("default");
}
return providerURLMergeProcessor.mergeLocalParams(localMap);

View File

@ -16,7 +16,6 @@
*/
package org.apache.dubbo.rpc.cluster.support;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ConfigUtils;
@ -30,6 +29,8 @@ import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.Merger;
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
@ -150,10 +151,12 @@ public class MergeableClusterInvoker<T> extends AbstractClusterInvoker<T> {
}
} else {
Merger resultMerger;
ApplicationModel applicationModel = ScopeModelUtil.getApplicationModel(invocation.getModuleModel().getApplicationModel());
if (ConfigUtils.isDefault(merger)) {
resultMerger = MergerFactory.getMerger(returnType);
resultMerger = applicationModel.getBeanFactory().getBean(MergerFactory.class).getMerger(returnType);
} else {
resultMerger = ExtensionLoader.getExtensionLoader(Merger.class).getExtension(merger);
resultMerger = applicationModel.getExtensionLoader(Merger.class).getExtension(merger);
}
if (resultMerger != null) {
List<Object> rets = new ArrayList<Object>(resultList.size());

View File

@ -19,7 +19,6 @@ package org.apache.dubbo.rpc.cluster.support.wrapper;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
@ -34,6 +33,7 @@ import org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder;
import org.apache.dubbo.rpc.cluster.filter.InvocationInterceptorBuilder;
import org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.List;
@ -62,7 +62,7 @@ public abstract class AbstractCluster implements Cluster {
}
private <T> AbstractClusterInvoker<T> buildInterceptorInvoker(AbstractClusterInvoker<T> invoker) {
List<InvocationInterceptorBuilder> builders = ExtensionLoader.getExtensionLoader(InvocationInterceptorBuilder.class).getActivateExtensions();
List<InvocationInterceptorBuilder> builders = ScopeModelUtil.getApplicationModel(invoker.getUrl().getScopeModel()).getExtensionLoader(InvocationInterceptorBuilder.class).getActivateExtensions();
if (CollectionUtils.isEmpty(builders)) {
return invoker;
}
@ -75,7 +75,7 @@ public abstract class AbstractCluster implements Cluster {
private ClusterInvoker<T> filterInvoker;
public ClusterFilterInvoker(AbstractClusterInvoker<T> invoker) {
List<FilterChainBuilder> builders = ExtensionLoader.getExtensionLoader(FilterChainBuilder.class).getActivateExtensions();
List<FilterChainBuilder> builders = ScopeModelUtil.getApplicationModel(invoker.getUrl().getScopeModel()).getExtensionLoader(FilterChainBuilder.class).getActivateExtensions();
if (CollectionUtils.isEmpty(builders)) {
filterInvoker = invoker;
} else {
@ -176,7 +176,7 @@ public abstract class AbstractCluster implements Cluster {
@Deprecated
private <T> ClusterInvoker<T> build27xCompatibleClusterInterceptors(AbstractClusterInvoker<T> clusterInvoker, AbstractClusterInvoker<T> last) {
List<ClusterInterceptor> interceptors = ExtensionLoader.getExtensionLoader(ClusterInterceptor.class).getActivateExtensions();
List<ClusterInterceptor> interceptors = ScopeModelUtil.getApplicationModel(clusterInvoker.getUrl().getScopeModel()).getExtensionLoader(ClusterInterceptor.class).getActivateExtensions();
if (!interceptors.isEmpty()) {
for (int i = interceptors.size() - 1; i >= 0; i--) {

View File

@ -0,0 +1 @@
dubbo-cluster=org.apache.dubbo.rpc.cluster.ClusterScopeModelInitializer

View File

@ -16,7 +16,10 @@
*/
package org.apache.dubbo.rpc.cluster.merger;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Array;
@ -28,6 +31,13 @@ import java.util.Map;
import java.util.Set;
public class ResultMergerTest {
private MergerFactory mergerFactory;
@BeforeEach
public void setup() {
mergerFactory = new MergerFactory();
mergerFactory.setScopeModel(ApplicationModel.defaultModel());
}
/**
* MergerFactory test
@ -35,7 +45,7 @@ public class ResultMergerTest {
@Test
public void testMergerFactoryIllegalArgumentException() {
try {
MergerFactory.getMerger(null);
mergerFactory.getMerger(null);
Assertions.fail("expected IllegalArgumentException for null argument");
} catch (IllegalArgumentException exception) {
Assertions.assertEquals("returnType is null", exception.getMessage());
@ -78,7 +88,7 @@ public class ResultMergerTest {
Integer[] intArray2 = {4, 5, 6};
Integer[] intArray3 = {7};
// trigger ArrayMerger
result = MergerFactory.getMerger(Integer[].class).merge(intArray1, intArray2, intArray3, null);
result = mergerFactory.getMerger(Integer[].class).merge(intArray1, intArray2, intArray3, null);
Assertions.assertTrue(result.getClass().isArray());
Assertions.assertEquals(7, Array.getLength(result));
Assertions.assertSame(Integer.class, result.getClass().getComponentType());
@ -103,17 +113,17 @@ public class ResultMergerTest {
public void testBooleanArrayMerger() {
boolean[] arrayOne = {true, false};
boolean[] arrayTwo = {false};
boolean[] result = MergerFactory.getMerger(boolean[].class).merge(arrayOne, arrayTwo, null);
boolean[] result = mergerFactory.getMerger(boolean[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(3, result.length);
boolean[] mergedResult = {true, false, false};
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i]);
}
result = MergerFactory.getMerger(boolean[].class).merge(null);
result = mergerFactory.getMerger(boolean[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(boolean[].class).merge(null, null);
result = mergerFactory.getMerger(boolean[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
@ -124,17 +134,17 @@ public class ResultMergerTest {
public void testByteArrayMerger() {
byte[] arrayOne = {1, 2};
byte[] arrayTwo = {1, 32};
byte[] result = MergerFactory.getMerger(byte[].class).merge(arrayOne, arrayTwo, null);
byte[] result = mergerFactory.getMerger(byte[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(4, result.length);
byte[] mergedResult = {1, 2, 1, 32};
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i]);
}
result = MergerFactory.getMerger(byte[].class).merge(null);
result = mergerFactory.getMerger(byte[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(byte[].class).merge(null, null);
result = mergerFactory.getMerger(byte[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
@ -145,17 +155,17 @@ public class ResultMergerTest {
public void testCharArrayMerger() {
char[] arrayOne = "hello".toCharArray();
char[] arrayTwo = "world".toCharArray();
char[] result = MergerFactory.getMerger(char[].class).merge(arrayOne, arrayTwo, null);
char[] result = mergerFactory.getMerger(char[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(10, result.length);
char[] mergedResult = "helloworld".toCharArray();
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i]);
}
result = MergerFactory.getMerger(char[].class).merge(null);
result = mergerFactory.getMerger(char[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(char[].class).merge(null, null);
result = mergerFactory.getMerger(char[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
@ -166,17 +176,17 @@ public class ResultMergerTest {
public void testDoubleArrayMerger() {
double[] arrayOne = {1.2d, 3.5d};
double[] arrayTwo = {2d, 34d};
double[] result = MergerFactory.getMerger(double[].class).merge(arrayOne, arrayTwo, null);
double[] result = mergerFactory.getMerger(double[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(4, result.length);
double[] mergedResult = {1.2d, 3.5d, 2d, 34d};
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i], 0.0);
}
result = MergerFactory.getMerger(double[].class).merge(null);
result = mergerFactory.getMerger(double[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(double[].class).merge(null, null);
result = mergerFactory.getMerger(double[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
@ -187,17 +197,17 @@ public class ResultMergerTest {
public void testFloatArrayMerger() {
float[] arrayOne = {1.2f, 3.5f};
float[] arrayTwo = {2f, 34f};
float[] result = MergerFactory.getMerger(float[].class).merge(arrayOne, arrayTwo, null);
float[] result = mergerFactory.getMerger(float[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(4, result.length);
double[] mergedResult = {1.2f, 3.5f, 2f, 34f};
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i], 0.0);
}
result = MergerFactory.getMerger(float[].class).merge(null);
result = mergerFactory.getMerger(float[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(float[].class).merge(null, null);
result = mergerFactory.getMerger(float[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
@ -208,17 +218,17 @@ public class ResultMergerTest {
public void testIntArrayMerger() {
int[] arrayOne = {1, 2};
int[] arrayTwo = {2, 34};
int[] result = MergerFactory.getMerger(int[].class).merge(arrayOne, arrayTwo, null);
int[] result = mergerFactory.getMerger(int[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(4, result.length);
double[] mergedResult = {1, 2, 2, 34};
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i], 0.0);
}
result = MergerFactory.getMerger(int[].class).merge(null);
result = mergerFactory.getMerger(int[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(int[].class).merge(null, null);
result = mergerFactory.getMerger(int[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
@ -237,7 +247,7 @@ public class ResultMergerTest {
add("4");
}};
List result = MergerFactory.getMerger(List.class).merge(list1, list2, null);
List result = mergerFactory.getMerger(List.class).merge(list1, list2, null);
Assertions.assertEquals(5, result.size());
ArrayList<String> expected = new ArrayList<String>() {{
add(null);
@ -248,10 +258,10 @@ public class ResultMergerTest {
}};
Assertions.assertEquals(expected, result);
result = MergerFactory.getMerger(List.class).merge(null);
result = mergerFactory.getMerger(List.class).merge(null);
Assertions.assertEquals(0, result.size());
result = MergerFactory.getMerger(List.class).merge(null, null);
result = mergerFactory.getMerger(List.class).merge(null, null);
Assertions.assertEquals(0, result.size());
}
@ -268,7 +278,7 @@ public class ResultMergerTest {
put("3333", 3232);
put("444", 2323);
}};
Map<Object, Object> result = MergerFactory.getMerger(Map.class).merge(mapOne, mapTwo, null);
Map<Object, Object> result = mergerFactory.getMerger(Map.class).merge(mapOne, mapTwo, null);
Assertions.assertEquals(4, result.size());
Map<String, Integer> mergedResult = new HashMap<String, Integer>() {{
put("11", 222);
@ -278,10 +288,10 @@ public class ResultMergerTest {
}};
Assertions.assertEquals(mergedResult, result);
result = MergerFactory.getMerger(Map.class).merge(null);
result = mergerFactory.getMerger(Map.class).merge(null);
Assertions.assertEquals(0, result.size());
result = MergerFactory.getMerger(Map.class).merge(null, null);
result = mergerFactory.getMerger(Map.class).merge(null, null);
Assertions.assertEquals(0, result.size());
}
@ -292,17 +302,17 @@ public class ResultMergerTest {
public void testLongArrayMerger() {
long[] arrayOne = {1L, 2L};
long[] arrayTwo = {2L, 34L};
long[] result = MergerFactory.getMerger(long[].class).merge(arrayOne, arrayTwo, null);
long[] result = mergerFactory.getMerger(long[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(4, result.length);
double[] mergedResult = {1L, 2L, 2L, 34L};
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i], 0.0);
}
result = MergerFactory.getMerger(long[].class).merge(null);
result = mergerFactory.getMerger(long[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(long[].class).merge(null, null);
result = mergerFactory.getMerger(long[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
@ -322,7 +332,7 @@ public class ResultMergerTest {
add("3");
}};
Set result = MergerFactory.getMerger(Set.class).merge(set1, set2, null);
Set result = mergerFactory.getMerger(Set.class).merge(set1, set2, null);
Assertions.assertEquals(4, result.size());
Assertions.assertEquals(new HashSet<String>() {
@ -334,10 +344,10 @@ public class ResultMergerTest {
}
}, result);
result = MergerFactory.getMerger(Set.class).merge(null);
result = mergerFactory.getMerger(Set.class).merge(null);
Assertions.assertEquals(0, result.size());
result = MergerFactory.getMerger(Set.class).merge(null, null);
result = mergerFactory.getMerger(Set.class).merge(null, null);
Assertions.assertEquals(0, result.size());
}
@ -348,17 +358,17 @@ public class ResultMergerTest {
public void testShortArrayMerger() {
short[] arrayOne = {1, 2};
short[] arrayTwo = {2, 34};
short[] result = MergerFactory.getMerger(short[].class).merge(arrayOne, arrayTwo, null);
short[] result = mergerFactory.getMerger(short[].class).merge(arrayOne, arrayTwo, null);
Assertions.assertEquals(4, result.length);
double[] mergedResult = {1, 2, 2, 34};
for (int i = 0; i < mergedResult.length; i++) {
Assertions.assertEquals(mergedResult[i], result[i], 0.0);
}
result = MergerFactory.getMerger(short[].class).merge(null);
result = mergerFactory.getMerger(short[].class).merge(null);
Assertions.assertEquals(0, result.length);
result = MergerFactory.getMerger(short[].class).merge(null, null);
result = mergerFactory.getMerger(short[].class).merge(null, null);
Assertions.assertEquals(0, result.length);
}
}

View File

@ -18,8 +18,10 @@ package org.apache.dubbo.rpc.cluster.support;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.apache.dubbo.common.constants.CommonConstants.ALIVE_KEY;
@ -46,6 +48,14 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
public class ClusterUtilsTest {
private ClusterUtils clusterUtils;
@BeforeEach
public void setup() {
clusterUtils = new ClusterUtils();
clusterUtils.setApplicationModel(ApplicationModel.defaultModel());
}
@Test
public void testMergeUrl() throws Exception {
URL providerURL = URL.valueOf("dubbo://localhost:55555");
@ -82,7 +92,7 @@ public class ClusterUtilsTest {
.addParameter(TAG_KEY,"UUU")
.build();
URL url = ClusterUtils.mergeUrl(providerURL, consumerURL.getParameters());
URL url = clusterUtils.mergeUrl(providerURL, consumerURL.getParameters());
Assertions.assertFalse(url.hasParameter(THREADS_KEY));
Assertions.assertFalse(url.hasParameter(DEFAULT_KEY_PREFIX + THREADS_KEY));
@ -120,7 +130,7 @@ public class ClusterUtilsTest {
"&methods=local&tag=local&timestamp=local");
URL remoteURL = URL.valueOf("dubbo://localhost:20880/DemoService?version=remote&group=remote&dubbo=remote&release=remote" +
"&methods=remote&tag=remote&timestamp=remote");
URL mergedUrl = ClusterUtils.mergeUrl(remoteURL, localURL.getParameters());
URL mergedUrl = clusterUtils.mergeUrl(remoteURL, localURL.getParameters());
Assertions.assertEquals(remoteURL.getVersion(), mergedUrl.getVersion());
Assertions.assertEquals(remoteURL.getGroup(), mergedUrl.getGroup());
@ -134,7 +144,7 @@ public class ClusterUtilsTest {
localURL = URL.valueOf("dubbo://localhost:20880/DemoService?version=local&group=local&dubbo=local&release=local" +
"&methods=local&tag=local&timestamp=local");
remoteURL = URL.valueOf("dubbo://localhost:20880/DemoService");
mergedUrl = ClusterUtils.mergeUrl(remoteURL, localURL.getParameters());
mergedUrl = clusterUtils.mergeUrl(remoteURL, localURL.getParameters());
Assertions.assertEquals(mergedUrl.getVersion(),localURL.getVersion());
Assertions.assertEquals(mergedUrl.getGroup(),localURL.getGroup());
@ -148,7 +158,7 @@ public class ClusterUtilsTest {
localURL = URL.valueOf("dubbo://localhost:20880/DemoService?version=local&group=local&dubbo=local&release=local" +
"&methods=local&tag=local&timestamp=local");
remoteURL = URL.valueOf("dubbo://localhost:20880/DemoService?key=value");
mergedUrl = ClusterUtils.mergeUrl(remoteURL, localURL.getParameters());
mergedUrl = clusterUtils.mergeUrl(remoteURL, localURL.getParameters());
Assertions.assertEquals(mergedUrl.getVersion(),localURL.getVersion());
Assertions.assertEquals(mergedUrl.getGroup(),localURL.getGroup());
@ -161,7 +171,7 @@ public class ClusterUtilsTest {
// present in both local and remote, uses local url params
localURL = URL.valueOf("dubbo://localhost:20880/DemoService?loadbalance=local&timeout=1000&cluster=local");
remoteURL = URL.valueOf("dubbo://localhost:20880/DemoService?loadbalance=remote&timeout=2000&cluster=remote");
mergedUrl = ClusterUtils.mergeUrl(remoteURL, localURL.getParameters());
mergedUrl = clusterUtils.mergeUrl(remoteURL, localURL.getParameters());
Assertions.assertEquals(localURL.getParameter(CLUSTER_KEY), mergedUrl.getParameter(CLUSTER_KEY));
Assertions.assertEquals(localURL.getParameter(TIMEOUT_KEY), mergedUrl.getParameter(TIMEOUT_KEY));

View File

@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
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 CommonScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
}
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(FrameworkStatusReportService.class);
}
@Override
public void initializeModuleModel(ModuleModel moduleModel) {
}
}

View File

@ -30,7 +30,11 @@ import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.LRUCache;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
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.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.io.Serializable;
@ -556,6 +560,18 @@ class URL implements Serializable {
return (ScopeModel) getAttribute(CommonConstants.SCOPE_MODEL);
}
public FrameworkModel getOrDefaultFrameworkModel() {
return ScopeModelUtil.getFrameworkModel(getScopeModel());
}
public ApplicationModel getOrDefaultApplicationModel() {
return ScopeModelUtil.getApplicationModel(getScopeModel());
}
public ModuleModel getOrDefaultModuleModel() {
return ScopeModelUtil.getModuleModel(getScopeModel());
}
public URL setServiceModel(ServiceModel serviceModel) {
return putAttribute(CommonConstants.SERVICE_MODEL, serviceModel);
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.common.bytecode;
import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
@ -60,6 +59,7 @@ public final class ClassGenerator {
private List<String> mFields;
private List<String> mConstructors;
private List<String> mMethods;
private ClassLoader mClassLoader;
private Map<String, Method> mCopyMethods; // <method desc,method instance>
private Map<String, Constructor<?>> mCopyConstructors; // <constructor desc,constructor instance>
private boolean mDefaultConstructor = false;
@ -67,16 +67,17 @@ public final class ClassGenerator {
private ClassGenerator() {
}
private ClassGenerator(ClassPool pool) {
private ClassGenerator(ClassLoader classLoader, ClassPool pool) {
mClassLoader = classLoader;
mPool = pool;
}
public static ClassGenerator newInstance() {
return new ClassGenerator(getClassPool(Thread.currentThread().getContextClassLoader()));
return new ClassGenerator(Thread.currentThread().getContextClassLoader(), getClassPool(Thread.currentThread().getContextClassLoader()));
}
public static ClassGenerator newInstance(ClassLoader loader) {
return new ClassGenerator(getClassPool(loader));
return new ClassGenerator(loader, getClassPool(loader));
}
public static boolean isDynamicClass(Class<?> cl) {
@ -282,7 +283,7 @@ public final class ClassGenerator {
}
public Class<?> toClass() {
return toClass(ClassUtils.getClassLoader(ClassGenerator.class),
return toClass(mClassLoader,
getClass().getProtectionDomain());
}

View File

@ -19,12 +19,20 @@ package org.apache.dubbo.common.compiler.support;
import org.apache.dubbo.common.compiler.Compiler;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
/**
* AdaptiveCompiler. (SPI, Singleton, ThreadSafe)
*/
@Adaptive
public class AdaptiveCompiler implements Compiler {
public class AdaptiveCompiler implements Compiler, ScopeModelAware {
private FrameworkModel frameworkModel;
@Override
public void setFrameworkModel(FrameworkModel frameworkModel) {
this.frameworkModel = frameworkModel;
}
private static volatile String DEFAULT_COMPILER;
@ -35,7 +43,7 @@ public class AdaptiveCompiler implements Compiler {
@Override
public Class<?> compile(String code, ClassLoader classLoader) {
Compiler compiler;
ExtensionLoader<Compiler> loader = ExtensionLoader.getExtensionLoader(Compiler.class);
ExtensionLoader<Compiler> loader = frameworkModel.getExtensionLoader(Compiler.class);
String name = DEFAULT_COMPILER; // copy reference
if (name != null && name.length() > 0) {
compiler = loader.getExtension(name);

View File

@ -129,6 +129,7 @@ public class ExtensionLoader<T> {
private List<ExtensionPostProcessor> extensionPostProcessors;
private InstantiationStrategy instantiationStrategy;
private Environment environment;
private ActivateComparator activateComparator;
public static void setLoadingStrategies(LoadingStrategy... strategies) {
if (ArrayUtils.isNotEmpty(strategies)) {
@ -167,6 +168,7 @@ public class ExtensionLoader<T> {
initInstantiationStrategy();
this.injector = (type == ExtensionInjector.class ? null : extensionDirector.getExtensionLoader(ExtensionInjector.class)
.getAdaptiveExtension());
this.activateComparator = new ActivateComparator(extensionDirector);
}
private void initInstantiationStrategy() {
@ -285,7 +287,7 @@ public class ExtensionLoader<T> {
*/
public List<T> getActivateExtension(URL url, String[] values, String group) {
// solve the bug of using @SPI's wrapper method to report a null pointer exception.
Map<Class<?>, T> activateExtensionsMap = new TreeMap<>(ActivateComparator.COMPARATOR);
Map<Class<?>, T> activateExtensionsMap = new TreeMap<>(activateComparator);
List<String> names = values == null ? new ArrayList<>(0) : asList(values);
if (!names.contains(REMOVE_VALUE_PREFIX + DEFAULT_KEY)) {
if (cachedActivateGroups.size() == 0) {
@ -364,7 +366,7 @@ public class ExtensionLoader<T> {
public List<T> getActivateExtensions() {
List<T> activateExtensions = new ArrayList<>();
TreeMap<Class<?>, T> activateExtensionsMap = new TreeMap<>(ActivateComparator.COMPARATOR);
TreeMap<Class<?>, T> activateExtensionsMap = new TreeMap<>(activateComparator);
getExtensionClasses();
for (Map.Entry<String, Object> entry : cachedActivates.entrySet()) {
String name = entry.getKey();

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.common.extension.support;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.ExtensionDirector;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.utils.ArrayUtils;
@ -29,7 +30,11 @@ import java.util.Comparator;
*/
public class ActivateComparator implements Comparator<Class<?>> {
public static final Comparator<Class<?>> COMPARATOR = new ActivateComparator();
private ExtensionDirector extensionDirector;
public ActivateComparator(ExtensionDirector extensionDirector) {
this.extensionDirector = extensionDirector;
}
@Override
public int compare(Class o1, Class o2) {
@ -52,7 +57,7 @@ public class ActivateComparator implements Comparator<Class<?>> {
ActivateInfo a2 = parseActivate(o2);
if ((a1.applicableToCompare() || a2.applicableToCompare()) && inf != null) {
ExtensionLoader<?> extensionLoader = ExtensionLoader.getExtensionLoader(inf);
ExtensionLoader<?> extensionLoader = extensionDirector.getExtensionLoader(inf);
if (a1.applicableToCompare()) {
String n2 = extensionLoader.getExtensionName(o2);
if (a1.isLess(n2)) {

View File

@ -16,13 +16,13 @@
*/
package org.apache.dubbo.common.logger;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.jcl.JclLoggerAdapter;
import org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter;
import org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter;
import org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter;
import org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter;
import org.apache.dubbo.common.logger.support.FailsafeLogger;
import org.apache.dubbo.rpc.model.FrameworkModel;
import java.io.File;
import java.util.Arrays;
@ -79,9 +79,9 @@ public class LoggerFactory {
private LoggerFactory() {
}
public static void setLoggerAdapter(String loggerAdapter) {
public static void setLoggerAdapter(FrameworkModel frameworkModel, String loggerAdapter) {
if (loggerAdapter != null && loggerAdapter.length() > 0) {
setLoggerAdapter(ExtensionLoader.getExtensionLoader(LoggerAdapter.class).getExtension(loggerAdapter));
setLoggerAdapter(frameworkModel.getExtensionLoader(LoggerAdapter.class).getExtension(loggerAdapter));
}
}

View File

@ -64,20 +64,20 @@ public class ClassUtils {
* @since 2.7.6
*/
public static final Set<Class<?>> SIMPLE_TYPES = ofSet(
Void.class,
Boolean.class,
Character.class,
Byte.class,
Short.class,
Integer.class,
Long.class,
Float.class,
Double.class,
String.class,
BigDecimal.class,
BigInteger.class,
Date.class,
Object.class
Void.class,
Boolean.class,
Character.class,
Byte.class,
Short.class,
Integer.class,
Long.class,
Float.class,
Double.class,
String.class,
BigDecimal.class,
BigInteger.class,
Date.class,
Object.class
);
/**
* Prefix for internal array class names: "[L"
@ -108,20 +108,20 @@ public class ClassUtils {
Set<Class<?>> primitiveTypeNames = new HashSet<>(32);
primitiveTypeNames.addAll(PRIMITIVE_WRAPPER_TYPE_MAP.values());
primitiveTypeNames.addAll(Arrays
.asList(boolean[].class, byte[].class, char[].class, double[].class,
float[].class, int[].class, long[].class, short[].class));
.asList(boolean[].class, byte[].class, char[].class, double[].class,
float[].class, int[].class, long[].class, short[].class));
for (Class<?> primitiveTypeName : primitiveTypeNames) {
PRIMITIVE_TYPE_NAME_MAP.put(primitiveTypeName.getName(), primitiveTypeName);
}
}
public static Class<?> forNameWithThreadContextClassLoader(String name)
throws ClassNotFoundException {
throws ClassNotFoundException {
return forName(name, Thread.currentThread().getContextClassLoader());
}
public static Class<?> forNameWithCallerClassLoader(String name, Class<?> caller)
throws ClassNotFoundException {
throws ClassNotFoundException {
return forName(name, caller.getClassLoader());
}
@ -137,20 +137,25 @@ public class ClassUtils {
*/
public static ClassLoader getClassLoader(Class<?> clazz) {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back to system class loader...
if (!clazz.getName().startsWith("org.apache.dubbo")) {
cl = clazz.getClassLoader();
}
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = clazz.getClassLoader();
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back to system class loader...
}
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
} catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
// No thread context class loader -> use class loader of this class.
cl = clazz.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
} catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
}
@ -198,7 +203,7 @@ public class ClassUtils {
* @see Class#forName(String, boolean, ClassLoader)
*/
public static Class<?> forName(String name, ClassLoader classLoader)
throws ClassNotFoundException, LinkageError {
throws ClassNotFoundException, LinkageError {
Class<?> clazz = resolvePrimitiveClassName(name);
if (clazz != null) {
@ -218,7 +223,7 @@ public class ClassUtils {
String elementClassName = null;
if (internalArrayMarker == 0) {
elementClassName = name
.substring(INTERNAL_ARRAY_PREFIX.length(), name.length() - 1);
.substring(INTERNAL_ARRAY_PREFIX.length(), name.length() - 1);
} else if (name.startsWith("[")) {
elementClassName = name.substring(1);
}
@ -338,7 +343,7 @@ public class ClassUtils {
*/
public static boolean isTypeMatch(Class<?> type, String value) {
if ((type == boolean.class || type == Boolean.class)
&& !("true".equals(value) || "false".equals(value))) {
&& !("true".equals(value) || "false".equals(value))) {
return false;
}
return true;
@ -392,18 +397,18 @@ public class ClassUtils {
if (isNotEmpty(interfaces)) {
// add current interfaces
Arrays.stream(interfaces)
.filter(resolved::add)
.forEach(cls -> {
allInterfaces.add(cls);
waitResolve.add(cls);
});
.filter(resolved::add)
.forEach(cls -> {
allInterfaces.add(cls);
waitResolve.add(cls);
});
}
// add all super classes to waitResolve
getAllSuperClasses(clazz)
.stream()
.filter(resolved::add)
.forEach(waitResolve::add);
.stream()
.filter(resolved::add)
.forEach(waitResolve::add);
clazz = waitResolve.poll();
}

View File

@ -331,7 +331,7 @@ public class ApplicationConfig extends AbstractConfig {
public void setLogger(String logger) {
this.logger = logger;
LoggerFactory.setLoggerAdapter(logger);
LoggerFactory.setLoggerAdapter(getApplicationModel().getFrameworkModel(), logger);
}
@Parameter(key = DUMP_DIRECTORY)

View File

@ -233,7 +233,9 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
}
setInterface(interfaceClass == null ? null : interfaceClass.getName());
setInterfaceClassLoader(interfaceClass == null ? null : interfaceClass.getClassLoader());
if (getInterfaceClassLoader() == null) {
setInterfaceClassLoader(interfaceClass == null ? null : interfaceClass.getClassLoader());
}
}
public String getClient() {

View File

@ -319,7 +319,9 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
}
this.interfaceClass = interfaceClass;
setInterface(interfaceClass == null ? null : interfaceClass.getName());
setInterfaceClassLoader(interfaceClass == null ? null : interfaceClass.getClassLoader());
if (getInterfaceClassLoader() == null) {
setInterfaceClassLoader(interfaceClass == null ? null : interfaceClass.getClassLoader());
}
}
public T getRef() {

View File

@ -169,6 +169,12 @@ public class ApplicationModel extends ScopeModel {
initFrameworkExts();
ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
for (ScopeModelInitializer initializer : initializers) {
initializer.initializeApplicationModel(this);
}
postProcessAfterCreated();
}

View File

@ -16,6 +16,7 @@
*/
package org.apache.dubbo.rpc.model;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -23,6 +24,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Model of dubbo framework, it can be shared with multiple applications.
@ -51,6 +53,13 @@ public class FrameworkModel extends ScopeModel {
serviceRepository = new FrameworkServiceRepository(this);
allInstances.add(this);
ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
for (ScopeModelInitializer initializer : initializers) {
initializer.initializeFrameworkModel(this);
}
postProcessAfterCreated();
}

View File

@ -16,11 +16,13 @@
*/
package org.apache.dubbo.rpc.model;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import java.util.List;
import java.util.Set;
/**
* Model of a service module
@ -43,6 +45,13 @@ public class ModuleModel extends ScopeModel {
protected void initialize() {
super.initialize();
this.serviceRepository = new ModuleServiceRepository(this);
ExtensionLoader<ScopeModelInitializer> initializerExtensionLoader = this.getExtensionLoader(ScopeModelInitializer.class);
Set<ScopeModelInitializer> initializers = initializerExtensionLoader.getSupportedExtensionInstances();
for (ScopeModelInitializer initializer : initializers) {
initializer.initializeModuleModel(this);
}
postProcessAfterCreated();
}

View File

@ -0,0 +1,30 @@
/*
* 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.model;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
@SPI(scope = ExtensionScope.SELF)
public interface ScopeModelInitializer {
void initializeFrameworkModel(FrameworkModel frameworkModel);
void initializeApplicationModel(ApplicationModel applicationModel);
void initializeModuleModel(ModuleModel moduleModel);
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.rpc.model;
import org.apache.dubbo.common.BaseServiceMetadata;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.config.AbstractInterfaceConfig;
import org.apache.dubbo.config.ReferenceConfigBase;
import org.apache.dubbo.config.ServiceConfigBase;
@ -30,6 +29,7 @@ public class ServiceModel {
private String serviceKey;
private Object proxyObject;
private Callable<Void> destroyCaller;
private ClassLoader classLoader;
private final ModuleModel moduleModel;
private final ServiceDescriptor serviceModel;
private final AbstractInterfaceConfig config;
@ -51,6 +51,12 @@ public class ServiceModel {
this.moduleModel = moduleModel;
this.config = config;
this.serviceMetadata = serviceMetadata;
if (config != null) {
this.classLoader = config.getInterfaceClassLoader();
}
if (this.classLoader == null) {
this.classLoader = Thread.currentThread().getContextClassLoader();
}
}
public String getServiceKey() {
@ -69,9 +75,12 @@ public class ServiceModel {
return serviceModel;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public ClassLoader getClassLoader() {
Class<?> serviceType = serviceMetadata.getServiceType();
return serviceType != null ? serviceType.getClassLoader() : ClassUtils.getClassLoader();
return classLoader;
}
/**

View File

@ -0,0 +1 @@
dubbo-common=org.apache.dubbo.common.CommonScopeModelInitializer

View File

@ -16,6 +16,8 @@
*/
package org.apache.dubbo.common.compiler.support;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -25,6 +27,7 @@ public class AdaptiveCompilerTest extends JavaCodeTest {
public void testAvailableCompiler() throws Exception {
AdaptiveCompiler.setDefaultCompiler("jdk");
AdaptiveCompiler compiler = new AdaptiveCompiler();
compiler.setFrameworkModel(FrameworkModel.defaultModel());
Class<?> clazz = compiler.compile(getSimpleCode(), AdaptiveCompiler.class.getClassLoader());
HelloService helloService = (HelloService) clazz.newInstance();
Assertions.assertEquals("Hello world!", helloService.sayHello());

View File

@ -16,7 +16,10 @@
*/
package org.apache.dubbo.common.extension.support;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
@ -25,6 +28,13 @@ import java.util.List;
public class ActivateComparatorTest {
private ActivateComparator activateComparator;
@BeforeEach
public void setup() {
activateComparator = new ActivateComparator(ApplicationModel.defaultModel().getExtensionDirector());
}
@Test
public void testActivateComparator(){
Filter1 f1 = new Filter1();
@ -39,7 +49,7 @@ public class ActivateComparatorTest {
filters.add(f4.getClass());
filters.add(f5.getClass());
Collections.sort(filters, ActivateComparator.COMPARATOR);
Collections.sort(filters, activateComparator);
Assertions.assertEquals(f4.getClass(), filters.get(0));
Assertions.assertEquals(f5.getClass(), filters.get(1));
@ -59,7 +69,7 @@ public class ActivateComparatorTest {
filters = new ArrayList<>();
filters.add(order0Filter1.getClass());
filters.add(order0Filter2.getClass());
filters.sort(ActivateComparator.COMPARATOR);
filters.sort(activateComparator);
Assertions.assertEquals(order0Filter1.getClass(), filters.get(0));
Assertions.assertEquals(order0Filter2.getClass(), filters.get(1));
}
@ -68,7 +78,7 @@ public class ActivateComparatorTest {
filters = new ArrayList<>();
filters.add(order0Filter2.getClass());
filters.add(order0Filter1.getClass());
filters.sort(ActivateComparator.COMPARATOR);
filters.sort(activateComparator);
Assertions.assertEquals(order0Filter1.getClass(), filters.get(0));
Assertions.assertEquals(order0Filter2.getClass(), filters.get(1));
}

View File

@ -16,6 +16,8 @@
*/
package org.apache.dubbo.common.logger;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.Test;
import java.io.File;
@ -35,7 +37,7 @@ public class LoggerFactoryTest {
@Test
public void testGetLogFile() {
LoggerFactory.setLoggerAdapter("slf4j");
LoggerFactory.setLoggerAdapter(FrameworkModel.defaultModel(), "slf4j");
File file = LoggerFactory.getFile();
assertThat(file, is(nullValue()));

View File

@ -43,6 +43,7 @@ import org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster;
import org.apache.dubbo.rpc.model.AsyncMethodInfo;
import org.apache.dubbo.rpc.model.ConsumerModel;
import org.apache.dubbo.rpc.model.ModuleServiceRepository;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ServiceDescriptor;
import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import org.apache.dubbo.rpc.service.GenericService;
@ -430,7 +431,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
if (UrlUtils.isRegistry(url)) {
urls.add(url.putAttribute(REFER_KEY, referenceParameters));
} else {
URL peerUrl = ClusterUtils.mergeUrl(url, referenceParameters);
URL peerUrl = getScopeModel().getApplicationModel().getBeanFactory().getBean(ClusterUtils.class).mergeUrl(url, referenceParameters);
peerUrl = peerUrl.putAttribute(PEER_KEY, true);
urls.add(peerUrl);
}
@ -490,15 +491,17 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
// for multi-subscription scenario, use 'zone-aware' policy by default
String cluster = registryUrl.getParameter(CLUSTER_KEY, ZoneAwareCluster.NAME);
// The invoker wrap sequence would be: ZoneAwareClusterInvoker(StaticDirectory) -> FailoverClusterInvoker(RegistryDirectory, routing happens here) -> Invoker
invoker = Cluster.getCluster(cluster, false).join(new StaticDirectory(registryUrl, invokers));
invoker = Cluster.getCluster(registryUrl.getScopeModel(), cluster, false).join(new StaticDirectory(registryUrl, invokers));
} else {
// not a registry url, must be direct invoke.
String cluster = CollectionUtils.isNotEmpty(invokers)
?
String cluster = CollectionUtils.isNotEmpty(invokers) ?
(invokers.get(0).getUrl() != null ? invokers.get(0).getUrl().getParameter(CLUSTER_KEY, ZoneAwareCluster.NAME) :
Cluster.DEFAULT)
: Cluster.DEFAULT;
invoker = Cluster.getCluster(cluster).join(new StaticDirectory(invokers));
ScopeModel scopeModel = CollectionUtils.isNotEmpty(invokers) ?
(invokers.get(0).getUrl() != null ? invokers.get(0).getUrl().getScopeModel() : null)
: null;
invoker = Cluster.getCluster(scopeModel, cluster).join(new StaticDirectory(invokers));
}
}
}

View File

@ -303,8 +303,11 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
}
} else {
try {
interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
.getContextClassLoader());
if (getInterfaceClassLoader() != null) {
interfaceClass = Class.forName(interfaceName, true, getInterfaceClassLoader());
} else {
interfaceClass = Class.forName(interfaceName, true, Thread.currentThread().getContextClassLoader());
}
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.config.bootstrap;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.config.Environment;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
@ -29,7 +28,6 @@ import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
@ -282,19 +280,6 @@ public final class DubboBootstrap {
DubboShutdownHook.getDubboShutdownHook().register();
ShutdownHookCallbacks.INSTANCE.addCallback(DubboBootstrap.this::destroy);
cache = ReferenceConfigCache.newCache();
initInternalBeans();
}
/**
* TODO init beans module-self
*/
private void initInternalBeans() {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(this);
beanFactory.registerBean(MetadataReportInstance.class);
beanFactory.registerBean(RemoteMetadataServiceImpl.class);
beanFactory.registerBean(FrameworkStatusReportService.class);
}
public ApplicationModel getApplicationModel() {

View File

@ -19,7 +19,6 @@ package org.apache.dubbo.config.utils;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.serialize.Serialization;
@ -63,6 +62,7 @@ import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.support.MockInvoker;
import java.net.InetAddress;
@ -108,7 +108,6 @@ import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTO
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.apache.dubbo.config.Constants.ARCHITECTURE;
import static org.apache.dubbo.config.Constants.CONTEXTPATH_KEY;
import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
@ -325,7 +324,7 @@ public class ConfigValidationUtils {
.build();
} else if (ConfigUtils.isNotEmpty(address) || ConfigUtils.isNotEmpty(protocol)) {
if (!map.containsKey(PROTOCOL_KEY)) {
if (getExtensionLoader(MonitorFactory.class).hasExtension(LOGSTAT_PROTOCOL)) {
if (interfaceConfig.getScopeModel().getExtensionLoader(MonitorFactory.class).hasExtension(LOGSTAT_PROTOCOL)) {
map.put(PROTOCOL_KEY, LOGSTAT_PROTOCOL);
} else if (ConfigUtils.isNotEmpty(protocol)) {
map.put(PROTOCOL_KEY, protocol);
@ -377,7 +376,7 @@ public class ConfigValidationUtils {
}
} else {
//Check whether the mock class is a implementation of the interfaceClass, and if it has a default constructor
MockInvoker.getMockObject(normalizedMock, interfaceClass);
MockInvoker.getMockObject(config.getScopeModel().getExtensionDirector(), normalizedMock, interfaceClass);
}
}
@ -386,9 +385,9 @@ public class ConfigValidationUtils {
checkName("stub", config.getStub());
checkMultiName("owner", config.getOwner());
checkExtension(ProxyFactory.class, PROXY_KEY, config.getProxy());
checkExtension(Cluster.class, CLUSTER_KEY, config.getCluster());
checkMultiExtension(Arrays.asList(Filter.class, ClusterFilter.class), FILTER_KEY, config.getFilter());
checkExtension(config.getScopeModel(), ProxyFactory.class, PROXY_KEY, config.getProxy());
checkExtension(config.getScopeModel(), Cluster.class, CLUSTER_KEY, config.getCluster());
checkMultiExtension(config.getScopeModel(), Arrays.asList(Filter.class, ClusterFilter.class), FILTER_KEY, config.getFilter());
checkNameHasSymbol(LAYER_KEY, config.getLayer());
List<MethodConfig> methods = config.getMethods();
@ -403,7 +402,7 @@ public class ConfigValidationUtils {
checkName(TOKEN_KEY, config.getToken());
checkPathName(PATH_KEY, config.getPath());
checkMultiExtension(ExporterListener.class, "listener", config.getListener());
checkMultiExtension(config.getScopeModel(), ExporterListener.class, "listener", config.getListener());
validateAbstractInterfaceConfig(config);
@ -428,7 +427,7 @@ public class ConfigValidationUtils {
}
public static void validateReferenceConfig(ReferenceConfig config) {
checkMultiExtension(InvokerListener.class, "listener", config.getListener());
checkMultiExtension(config.getScopeModel(), InvokerListener.class, "listener", config.getListener());
checkKey(VERSION_KEY, config.getVersion());
checkKey(GROUP_KEY, config.getGroup());
checkName(CLIENT_KEY, config.getClient());
@ -529,29 +528,29 @@ public class ConfigValidationUtils {
if (DUBBO_PROTOCOL.equals(name)) {
checkMultiExtension(Codec2.class, CODEC_KEY, config.getCodec());
checkMultiExtension(Serialization.class, SERIALIZATION_KEY, config.getSerialization());
checkMultiExtension(Transporter.class, SERVER_KEY, config.getServer());
checkMultiExtension(Transporter.class, CLIENT_KEY, config.getClient());
checkMultiExtension(config.getScopeModel(), Codec2.class, CODEC_KEY, config.getCodec());
checkMultiExtension(config.getScopeModel(), Serialization.class, SERIALIZATION_KEY, config.getSerialization());
checkMultiExtension(config.getScopeModel(), Transporter.class, SERVER_KEY, config.getServer());
checkMultiExtension(config.getScopeModel(), Transporter.class, CLIENT_KEY, config.getClient());
}
checkMultiExtension(TelnetHandler.class, TELNET, config.getTelnet());
checkMultiExtension(StatusChecker.class, "status", config.getStatus());
checkExtension(Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(Exchanger.class, EXCHANGER_KEY, config.getExchanger());
checkExtension(Dispatcher.class, DISPATCHER_KEY, config.getDispatcher());
checkExtension(Dispatcher.class, "dispather", config.getDispather());
checkExtension(ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
checkMultiExtension(config.getScopeModel(), TelnetHandler.class, TELNET, config.getTelnet());
checkMultiExtension(config.getScopeModel(), StatusChecker.class, "status", config.getStatus());
checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
checkExtension(config.getScopeModel(), Dispatcher.class, DISPATCHER_KEY, config.getDispatcher());
checkExtension(config.getScopeModel(), Dispatcher.class, "dispather", config.getDispather());
checkExtension(config.getScopeModel(), ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
}
}
public static void validateProviderConfig(ProviderConfig config) {
checkPathName(CONTEXTPATH_KEY, config.getContextpath());
checkExtension(ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
checkMultiExtension(TelnetHandler.class, TELNET, config.getTelnet());
checkMultiExtension(StatusChecker.class, STATUS_KEY, config.getStatus());
checkExtension(Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(Exchanger.class, EXCHANGER_KEY, config.getExchanger());
checkExtension(config.getScopeModel(), ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
checkMultiExtension(config.getScopeModel(), TelnetHandler.class, TELNET, config.getTelnet());
checkMultiExtension(config.getScopeModel(), StatusChecker.class, STATUS_KEY, config.getStatus());
checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
}
public static void validateConsumerConfig(ConsumerConfig config) {
@ -572,7 +571,7 @@ public class ConfigValidationUtils {
}
public static void validateMethodConfig(MethodConfig config) {
checkExtension(LoadBalance.class, LOADBALANCE_KEY, config.getLoadbalance());
checkExtension(config.getScopeModel(), LoadBalance.class, LOADBALANCE_KEY, config.getLoadbalance());
checkParameterName(config.getParameters());
checkMethodName("name", config.getName());
@ -597,10 +596,10 @@ public class ConfigValidationUtils {
return StringUtils.isNotEmpty(registryProtocol) ? registryProtocol : REGISTRY_PROTOCOL;
}
public static void checkExtension(Class<?> type, String property, String value) {
public static void checkExtension(ScopeModel scopeModel, Class<?> type, String property, String value) {
checkName(property, value);
if (StringUtils.isNotEmpty(value)
&& !ExtensionLoader.getExtensionLoader(type).hasExtension(value)) {
&& !scopeModel.getExtensionLoader(type).hasExtension(value)) {
throw new IllegalStateException("No such extension " + value + " for " + property + "/" + type.getName());
}
}
@ -613,11 +612,11 @@ public class ConfigValidationUtils {
* @param property The extension key
* @param value The Extension name
*/
public static void checkMultiExtension(Class<?> type, String property, String value) {
checkMultiExtension(Collections.singletonList(type), property, value);
public static void checkMultiExtension(ScopeModel scopeModel, Class<?> type, String property, String value) {
checkMultiExtension(scopeModel,Collections.singletonList(type), property, value);
}
public static void checkMultiExtension(List<Class<?>> types, String property, String value) {
public static void checkMultiExtension(ScopeModel scopeModel, List<Class<?>> types, String property, String value) {
checkMultiName(property, value);
if (StringUtils.isNotEmpty(value)) {
String[] values = value.split("\\s*[,]+\\s*");
@ -630,7 +629,7 @@ public class ConfigValidationUtils {
}
boolean match = false;
for (Class<?> type : types) {
if (ExtensionLoader.getExtensionLoader(type).hasExtension(v)) {
if (scopeModel.getExtensionLoader(type).hasExtension(v)) {
match = true;
}
}

View File

@ -0,0 +1,22 @@
/*
* 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 demo;
public interface MultiClassLoaderService {
Object call(MultiClassLoaderServiceRequest innerRequest);
}

View File

@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package demo;
import java.util.concurrent.atomic.AtomicReference;
public class MultiClassLoaderServiceImpl implements MultiClassLoaderService {
private AtomicReference<MultiClassLoaderServiceRequest> innerRequestReference;
private AtomicReference<MultiClassLoaderServiceResult> innerResultReference;
public MultiClassLoaderServiceImpl(AtomicReference<MultiClassLoaderServiceRequest> innerRequestReference, AtomicReference<MultiClassLoaderServiceResult> innerResultReference) {
this.innerRequestReference = innerRequestReference;
this.innerResultReference = innerResultReference;
}
@Override
public MultiClassLoaderServiceResult call(MultiClassLoaderServiceRequest innerRequest) {
innerRequestReference.set(innerRequest);
return innerResultReference.get();
}
}

View File

@ -0,0 +1,22 @@
/*
* 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 demo;
import java.io.Serializable;
public class MultiClassLoaderServiceRequest implements Serializable {
}

View File

@ -0,0 +1,22 @@
/*
* 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 demo;
import java.io.Serializable;
public class MultiClassLoaderServiceResult implements Serializable {
}

View File

@ -192,19 +192,19 @@ public class AbstractConfigTest {
@Test
public void checkExtension() throws Exception {
Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkExtension(Greeting.class, "hello", "world"));
Assertions.assertThrows(IllegalStateException.class, () -> ConfigValidationUtils.checkExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "world"));
}
@Test
public void checkMultiExtension1() throws Exception {
Assertions.assertThrows(IllegalStateException.class,
() -> ConfigValidationUtils.checkMultiExtension(Greeting.class, "hello", "default,world"));
() -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,world"));
}
@Test
public void checkMultiExtension2() throws Exception {
Assertions.assertThrows(IllegalStateException.class,
() -> ConfigValidationUtils.checkMultiExtension(Greeting.class, "hello", "default,-world"));
() -> ConfigValidationUtils.checkMultiExtension(ApplicationModel.defaultModel(), Greeting.class, "hello", "default,-world"));
}
@Test

View File

@ -18,6 +18,8 @@ package org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.compiler.support.CtClassBuilder;
import org.apache.dubbo.common.compiler.support.JavassistCompiler;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
@ -41,6 +43,13 @@ import org.apache.dubbo.rpc.model.ServiceMetadata;
import org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker;
import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import demo.MultiClassLoaderService;
import demo.MultiClassLoaderServiceImpl;
import demo.MultiClassLoaderServiceRequest;
import demo.MultiClassLoaderServiceResult;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.NotFoundException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@ -51,15 +60,18 @@ import org.mockito.Mockito;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
@ -865,6 +877,80 @@ public class ReferenceConfigTest {
applicationModel.destroy();
}
@Test
public void testDifferentClassLoaderRequest() throws Exception {
String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
TestClassLoader1 classLoader1 = new TestClassLoader1(basePath);
TestClassLoader1 classLoader2 = new TestClassLoader1(basePath);
TestClassLoader2 classLoader3 = new TestClassLoader2(classLoader2, basePath);
ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
ModuleModel moduleModel = new ModuleModel(applicationModel);
Class<?> clazz1 = classLoader1.loadClass(MultiClassLoaderService.class.getName(), false);
Class<?> clazz1impl = classLoader1.loadClass(MultiClassLoaderServiceImpl.class.getName(), false);
Class<?> requestClazzCustom1 = compileCustomRequest(classLoader1);
Class<?> resultClazzCustom1 = compileCustomResult(classLoader1);
classLoader1.loadedClass.put(requestClazzCustom1.getName(), requestClazzCustom1);
classLoader1.loadedClass.put(resultClazzCustom1.getName(), resultClazzCustom1);
AtomicReference innerRequestReference = new AtomicReference();
AtomicReference innerResultReference = new AtomicReference();
innerResultReference.set(resultClazzCustom1.newInstance());
Constructor<?> declaredConstructor = clazz1impl.getDeclaredConstructor(AtomicReference.class, AtomicReference.class);
ServiceConfig serviceConfig = new ServiceConfig<>();
serviceConfig.setInterfaceClassLoader(classLoader1);
serviceConfig.setInterface(clazz1);
serviceConfig.setRegistry(new RegistryConfig(zkUrl));
serviceConfig.setScopeModel(moduleModel);
serviceConfig.setRef(declaredConstructor.newInstance(innerRequestReference, innerResultReference));
serviceConfig.export();
Class<?> clazz2 = classLoader2.loadClass(MultiClassLoaderService.class.getName(), false);
Class<?> requestClazzOrigin = classLoader2.loadClass(MultiClassLoaderServiceRequest.class.getName(), false);
Class<?> requestClazzCustom2 = compileCustomRequest(classLoader2);
Class<?> resultClazzCustom3 = compileCustomResult(classLoader3);
classLoader2.loadedClass.put(requestClazzCustom2.getName(), requestClazzCustom2);
classLoader3.loadedClass.put(resultClazzCustom3.getName(), resultClazzCustom3);
ReferenceConfig<DemoService> referenceConfig1 = new ReferenceConfig<>();
referenceConfig1.setInterface(clazz2);
referenceConfig1.setInterfaceClassLoader(classLoader3);
referenceConfig1.setRegistry(new RegistryConfig(zkUrl));
referenceConfig1.setScopeModel(moduleModel);
referenceConfig1.setScope("remote");
Object object1 = referenceConfig1.get();
java.lang.reflect.Method callBean1 = object1.getClass().getDeclaredMethod("call", requestClazzOrigin);
callBean1.setAccessible(true);
Object result1 = callBean1.invoke(object1, requestClazzCustom2.newInstance());
Assertions.assertEquals(resultClazzCustom3, result1.getClass());
Assertions.assertNotEquals(classLoader2, result1.getClass().getClassLoader());
Assertions.assertEquals(classLoader1, innerRequestReference.get().getClass().getClassLoader());
applicationModel.destroy();
}
private Class<?> compileCustomRequest(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
CtClassBuilder builder = new CtClassBuilder();
builder.setClassName(MultiClassLoaderServiceRequest.class.getName() + "A");
builder.setSuperClassName(MultiClassLoaderServiceRequest.class.getName());
CtClass cls = builder.build(classLoader);
return cls.toClass(classLoader, JavassistCompiler.class.getProtectionDomain());
}
private Class<?> compileCustomResult(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
CtClassBuilder builder = new CtClassBuilder();
builder.setClassName(MultiClassLoaderServiceResult.class.getName() + "A");
builder.setSuperClassName(MultiClassLoaderServiceResult.class.getName());
CtClass cls = builder.build(classLoader);
return cls.toClass(classLoader, JavassistCompiler.class.getProtectionDomain());
}
@Reference(methods = {@Method(name = "sayHello", timeout = 1300, retries = 4, loadbalance = "random", async = true,
actives = 3, executes = 5, deprecated = true, sticky = true, oninvoke = "instance.i", onthrow = "instance.t", onreturn = "instance.r", cache = "c", validation = "v",
arguments = {@Argument(index = 24, callback = true, type = "sss")})})
@ -873,7 +959,6 @@ public class ReferenceConfigTest {
private class InnerTest {
}
private static class TestClassLoader extends ClassLoader {
private String basePath;
@ -914,6 +999,115 @@ public class ReferenceConfigTest {
}
public byte[] loadClassData(String className) throws IOException {
className = className.replaceAll("\\.", "/");
String path = basePath + File.separator + className + ".class";
FileInputStream fileInputStream;
byte[] classBytes;
fileInputStream = new FileInputStream(path);
int length = fileInputStream.available();
classBytes = new byte[length];
fileInputStream.read(classBytes);
fileInputStream.close();
return classBytes;
}
}
private static class TestClassLoader1 extends ClassLoader {
private String basePath;
public TestClassLoader1(String basePath) {
this.basePath = basePath;
}
Map<String, Class<?>> loadedClass = new ConcurrentHashMap<>();
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] bytes = loadClassData(name);
return defineClass(name, bytes, 0, bytes.length);
} catch (Exception e) {
throw new ClassNotFoundException();
}
}
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (loadedClass.containsKey(name)) {
return loadedClass.get(name);
}
if (name.startsWith("demo")) {
Class<?> aClass = this.findClass(name);
this.loadedClass.put(name, aClass);
if (resolve) {
this.resolveClass(aClass);
}
return aClass;
} else {
Class<?> loadedClass = this.findLoadedClass(name);
if (loadedClass != null) {
return loadedClass;
} else {
return super.loadClass(name, resolve);
}
}
}
public byte[] loadClassData(String className) throws IOException {
className = className.replaceAll("\\.", "/");
String path = basePath + File.separator + className + ".class";
FileInputStream fileInputStream;
byte[] classBytes;
fileInputStream = new FileInputStream(path);
int length = fileInputStream.available();
classBytes = new byte[length];
fileInputStream.read(classBytes);
fileInputStream.close();
return classBytes;
}
}
private static class TestClassLoader2 extends ClassLoader {
private String basePath;
private TestClassLoader1 testClassLoader;
Map<String, Class<?>> loadedClass = new ConcurrentHashMap<>();
public TestClassLoader2(TestClassLoader1 testClassLoader, String basePath) {
this.testClassLoader = testClassLoader;
this.basePath = basePath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] bytes = loadClassData(name);
return defineClass(name, bytes, 0, bytes.length);
} catch (Exception e) {
throw new ClassNotFoundException();
}
}
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (loadedClass.containsKey(name)) {
return loadedClass.get(name);
}
if (name.startsWith("demo.MultiClassLoaderServiceRe")) {
Class<?> aClass = this.findClass(name);
this.loadedClass.put(name, aClass);
if (resolve) {
this.resolveClass(aClass);
}
return aClass;
} else {
return testClassLoader.loadClass(name, resolve);
}
}
public byte[] loadClassData(String className) throws IOException {
className = className.replaceAll("\\.", "/");
String path = basePath + File.separator + className + ".class";

View File

@ -789,6 +789,12 @@
META-INF/dubbo/internal/org.apache.dubbo.registry.ProviderFirstParams
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.rpc.model.ScopeModelInitializer
</resource>
</transformer>
</transformers>
<filters>
<filter>

View File

@ -228,7 +228,6 @@ public class MetadataInfo implements Serializable {
}
public static class ServiceInfo implements Serializable {
private static ExtensionLoader<MetadataParamsFilter> loader = ExtensionLoader.getExtensionLoader(MetadataParamsFilter.class);
private String name;
private String group;
private String version;
@ -250,6 +249,7 @@ public class MetadataInfo implements Serializable {
private transient String matchKey;
private transient URL url;
private transient ExtensionLoader<MetadataParamsFilter> loader;
private final static String[] KEYS_TO_REMOVE = {MONITOR_KEY, BIND_IP_KEY, BIND_PORT_KEY, QOS_ENABLE,
QOS_HOST, QOS_PORT, ACCEPT_FOREIGN_IP, VALIDATION_KEY, INTERFACES, PID_KEY, TIMESTAMP_KEY};
@ -258,7 +258,7 @@ public class MetadataInfo implements Serializable {
public ServiceInfo(URL url) {
this(url.getServiceInterface(), url.getGroup(), url.getVersion(), url.getProtocol(), url.getPath(), null);
this.loader = url.getOrDefaultApplicationModel().getExtensionLoader(MetadataParamsFilter.class);
this.url = url;
Map<String, String> params = new HashMap<>();
List<MetadataParamsFilter> filters = loader.getActivateExtension(url, "params-filter");

View File

@ -19,11 +19,11 @@ package org.apache.dubbo.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.lang.Prioritized;
import org.apache.dubbo.rpc.model.ScopeModel;
import java.util.List;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
/**
@ -84,8 +84,8 @@ public interface MetadataServiceExporter extends Prioritized {
* @return non-null
* @since 2.7.8
*/
static MetadataServiceExporter getExtension(String metadataType) {
return getExtensionLoader(MetadataServiceExporter.class).getOrDefaultExtension(metadataType);
static MetadataServiceExporter getExtension(ScopeModel scopeModel, String metadataType) {
return scopeModel.getExtensionLoader(MetadataServiceExporter.class).getOrDefaultExtension(metadataType);
}
/**
@ -94,8 +94,8 @@ public interface MetadataServiceExporter extends Prioritized {
* @return non-null
* @since 2.7.8
*/
static MetadataServiceExporter getDefaultExtension() {
return getExtension(DEFAULT_METADATA_STORAGE_TYPE);
static MetadataServiceExporter getDefaultExtension(ScopeModel scopeModel) {
return getExtension(scopeModel, DEFAULT_METADATA_STORAGE_TYPE);
}
}

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.Arrays;
import java.util.HashSet;
@ -27,7 +28,6 @@ import java.util.Set;
import static java.util.Collections.emptySet;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
import static org.apache.dubbo.common.utils.StringUtils.SLASH;
@ -51,16 +51,8 @@ public interface ServiceNameMapping {
*
* @return non-null {@link ServiceNameMapping}
*/
static ServiceNameMapping getDefaultExtension() {
return getExtensionLoader(ServiceNameMapping.class).getDefaultExtension();
}
static ServiceNameMapping getDefaultExtension(ScopeModel scopeModel) {
if (scopeModel != null) {
return scopeModel.getDefaultExtension(ServiceNameMapping.class);
} else {
return getExtensionLoader(ServiceNameMapping.class).getDefaultExtension();
}
return ScopeModelUtil.getApplicationModel(scopeModel).getDefaultExtension(ServiceNameMapping.class);
}
static String buildMappingKey(URL url) {

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.metadata.report;
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 MetadataScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
}
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(MetadataReportInstance.class);
}
@Override
public void initializeModuleModel(ModuleModel moduleModel) {
}
}

View File

@ -0,0 +1 @@
dubbo-metadata-api=org.apache.dubbo.metadata.report.MetadataScopeModelInitializer

View File

@ -24,11 +24,17 @@ import org.apache.dubbo.auth.spi.Authenticator;
import org.apache.dubbo.auth.utils.SignatureUtils;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.model.ApplicationModel;
public class AccessKeyAuthenticator implements Authenticator {
private ApplicationModel applicationModel;
public AccessKeyAuthenticator(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
}
@Override
public void sign(Invocation invocation, URL url) {
String currentTime = String.valueOf(System.currentTimeMillis());
@ -66,7 +72,7 @@ public class AccessKeyAuthenticator implements Authenticator {
}
AccessKeyPair getAccessKeyPair(Invocation invocation, URL url) {
AccessKeyStorage accessKeyStorage = ExtensionLoader.getExtensionLoader(AccessKeyStorage.class)
AccessKeyStorage accessKeyStorage = applicationModel.getExtensionLoader(AccessKeyStorage.class)
.getExtension(url.getParameter(Constants.ACCESS_KEY_STORAGE_KEY, Constants.DEFAULT_ACCESS_KEY_STORAGE));
AccessKeyPair accessKeyPair = null;

View File

@ -21,12 +21,12 @@ import org.apache.dubbo.auth.spi.Authenticator;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ApplicationModel;
/**
* The ConsumerSignFilter
@ -35,13 +35,18 @@ import org.apache.dubbo.rpc.RpcException;
*/
@Activate(group = CommonConstants.CONSUMER, value = Constants.SERVICE_AUTH, order = -10000)
public class ConsumerSignFilter implements Filter {
private ApplicationModel applicationModel;
public ConsumerSignFilter(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
URL url = invoker.getUrl();
boolean shouldAuth = url.getParameter(Constants.SERVICE_AUTH, false);
if (shouldAuth) {
Authenticator authenticator = ExtensionLoader.getExtensionLoader(Authenticator.class)
Authenticator authenticator = applicationModel.getExtensionLoader(Authenticator.class)
.getExtension(url.getParameter(Constants.AUTHENTICATOR, Constants.DEFAULT_AUTHENTICATOR));
authenticator.sign(invocation, url);
}

View File

@ -21,23 +21,28 @@ import org.apache.dubbo.auth.spi.Authenticator;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.AsyncRpcResult;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ApplicationModel;
@Activate(group = CommonConstants.PROVIDER, order = -10000)
public class ProviderAuthFilter implements Filter {
private ApplicationModel applicationModel;
public ProviderAuthFilter(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
URL url = invoker.getUrl();
boolean shouldAuth = url.getParameter(Constants.SERVICE_AUTH, false);
if (shouldAuth) {
Authenticator authenticator = ExtensionLoader.getExtensionLoader(Authenticator.class)
Authenticator authenticator = applicationModel.getExtensionLoader(Authenticator.class)
.getExtension(url.getParameter(Constants.AUTHENTICATOR, Constants.DEFAULT_AUTHENTICATOR));
try {
authenticator.authenticate(invocation, url);

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Test;
@ -93,7 +94,7 @@ class AccessKeyAuthenticatorTest {
.addParameter(CommonConstants.APPLICATION_KEY, "test")
.addParameter(Constants.SECRET_ACCESS_KEY_KEY, "sk");
Invocation invocation = new RpcInvocation();
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
AccessKeyAuthenticator helper = new AccessKeyAuthenticator(ApplicationModel.defaultModel());
assertThrows(RpcAuthenticationException.class, () -> helper.authenticate(invocation, url));
}
@ -101,7 +102,7 @@ class AccessKeyAuthenticatorTest {
void testGetAccessKeyPairFailed() {
URL url = URL.valueOf("dubbo://10.10.10.10:2181")
.addParameter(Constants.ACCESS_KEY_ID_KEY, "ak");
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
AccessKeyAuthenticator helper = new AccessKeyAuthenticator(ApplicationModel.defaultModel());
Invocation invocation = mock(Invocation.class);
assertThrows(RuntimeException.class, () -> helper.getAccessKeyPair(invocation, url));
}
@ -111,7 +112,7 @@ class AccessKeyAuthenticatorTest {
URL url = mock(URL.class);
Invocation invocation = mock(Invocation.class);
String secretKey = "123456";
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
AccessKeyAuthenticator helper = new AccessKeyAuthenticator(ApplicationModel.defaultModel());
String signature = helper.getSignature(url, invocation, secretKey, String.valueOf(System.currentTimeMillis()));
assertNotNull(signature);
}
@ -124,7 +125,7 @@ class AccessKeyAuthenticatorTest {
String secretKey = "123456";
Object[] params = {"dubbo", new ArrayList()};
when(invocation.getArguments()).thenReturn(params);
AccessKeyAuthenticator helper = new AccessKeyAuthenticator();
AccessKeyAuthenticator helper = new AccessKeyAuthenticator(ApplicationModel.defaultModel());
String signature = helper.getSignature(url, invocation, secretKey, String.valueOf(System.currentTimeMillis()));
assertNotNull(signature);

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Test;
@ -41,7 +42,7 @@ class ConsumerSignFilterTest {
Invoker invoker = mock(Invoker.class);
Invocation invocation = mock(Invocation.class);
when(invoker.getUrl()).thenReturn(url);
ConsumerSignFilter consumerSignFilter = new ConsumerSignFilter();
ConsumerSignFilter consumerSignFilter = new ConsumerSignFilter(ApplicationModel.defaultModel());
consumerSignFilter.invoke(invoker, invocation);
verify(invocation, never()).setAttachment(eq(Constants.REQUEST_SIGNATURE_KEY), anyString());
}
@ -56,7 +57,7 @@ class ConsumerSignFilterTest {
Invoker invoker = mock(Invoker.class);
Invocation invocation = mock(Invocation.class);
when(invoker.getUrl()).thenReturn(url);
ConsumerSignFilter consumerSignFilter = new ConsumerSignFilter();
ConsumerSignFilter consumerSignFilter = new ConsumerSignFilter(ApplicationModel.defaultModel());
consumerSignFilter.invoke(invoker, invocation);
verify(invocation, times(1)).setAttachment(eq(Constants.REQUEST_SIGNATURE_KEY), anyString());
}

View File

@ -24,6 +24,7 @@ import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Test;
@ -45,7 +46,7 @@ class ProviderAuthFilterTest {
Invoker invoker = mock(Invoker.class);
Invocation invocation = mock(Invocation.class);
when(invoker.getUrl()).thenReturn(url);
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter(ApplicationModel.defaultModel());
providerAuthFilter.invoke(invoker, invocation);
verify(url, never()).getParameter(eq(Constants.AUTHENTICATOR), eq(Constants.DEFAULT_AUTHENTICATOR));
}
@ -60,7 +61,7 @@ class ProviderAuthFilterTest {
Invoker invoker = mock(Invoker.class);
Invocation invocation = mock(Invocation.class);
when(invoker.getUrl()).thenReturn(url);
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter(ApplicationModel.defaultModel());
providerAuthFilter.invoke(invoker, invocation);
verify(invocation, atLeastOnce()).getAttachment(anyString());
}
@ -78,7 +79,7 @@ class ProviderAuthFilterTest {
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(null);
when(invoker.getUrl()).thenReturn(url);
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter(ApplicationModel.defaultModel());
Result result = providerAuthFilter.invoke(invoker, invocation);
assertTrue(result.hasException());
@ -96,7 +97,7 @@ class ProviderAuthFilterTest {
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(null);
when(invoker.getUrl()).thenReturn(url);
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter(ApplicationModel.defaultModel());
Result result = providerAuthFilter.invoke(invoker, invocation);
assertTrue(result.hasException());
}
@ -114,7 +115,7 @@ class ProviderAuthFilterTest {
when(invocation.getObjectAttachment(Constants.REQUEST_TIMESTAMP_KEY)).thenReturn(System.currentTimeMillis());
when(invoker.getUrl()).thenReturn(url);
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter(ApplicationModel.defaultModel());
Result result = providerAuthFilter.invoke(invoker, invocation);
assertTrue(result.hasException());
assertTrue(result.getException() instanceof RpcAuthenticationException);
@ -150,7 +151,7 @@ class ProviderAuthFilterTest {
String sign = SignatureUtils.sign(originalParams, requestString, "sk");
when(invocation.getObjectAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(sign);
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter(ApplicationModel.defaultModel());
Result result = providerAuthFilter.invoke(invoker, invocation);
assertTrue(result.hasException());
assertTrue(result.getException() instanceof RpcAuthenticationException);
@ -181,7 +182,7 @@ class ProviderAuthFilterTest {
String sign = SignatureUtils.sign(requestString, "sk");
when(invocation.getAttachment(Constants.REQUEST_SIGNATURE_KEY)).thenReturn(sign);
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter();
ProviderAuthFilter providerAuthFilter = new ProviderAuthFilter(ApplicationModel.defaultModel());
Result result = providerAuthFilter.invoke(invoker, invocation);
assertNull(result);
}

View File

@ -18,7 +18,6 @@
package org.apache.dubbo.registry;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import java.util.Collections;
@ -32,7 +31,7 @@ public class RegistryFactoryWrapper implements RegistryFactory {
@Override
public Registry getRegistry(URL url) {
return new ListenerRegistryWrapper(registryFactory.getRegistry(url),
Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(RegistryServiceListener.class)
Collections.unmodifiableList(url.getOrDefaultApplicationModel().getExtensionLoader(RegistryServiceListener.class)
.getActivateExtension(url, "registry.listeners")));
}
}

View File

@ -16,7 +16,7 @@
*/
package org.apache.dubbo.registry;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
@ -42,14 +42,14 @@ public abstract class RegistryNotifier {
private ScheduledExecutorService scheduler;
public RegistryNotifier(long delayTime) {
this(delayTime, null);
public RegistryNotifier(URL registryUrl, long delayTime) {
this(registryUrl, delayTime, null);
}
public RegistryNotifier(long delayTime, ScheduledExecutorService scheduler) {
public RegistryNotifier(URL registryUrl, long delayTime, ScheduledExecutorService scheduler) {
this.delayTime = delayTime;
if (scheduler == null) {
this.scheduler = ExtensionLoader.getExtensionLoader(ExecutorRepository.class)
this.scheduler = registryUrl.getOrDefaultApplicationModel().getExtensionLoader(ExecutorRepository.class)
.getDefaultExtension().getRegistryNotificationExecutor();
} else {
this.scheduler = scheduler;

View File

@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.registry;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
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 RegistryScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
}
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(RemoteMetadataServiceImpl.class);
}
@Override
public void initializeModuleModel(ModuleModel moduleModel) {
}
}

View File

@ -20,8 +20,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.SPI;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
/**
* The default {@link SPI} implementation of {@link ServiceDiscoveryFactory} to {@link #getServiceDiscovery(URL) get the
* instance of ServiceDiscovery} via the {@link URL#getProtocol() protocol} from the {@link URL} that will connect
@ -42,7 +40,7 @@ public class DefaultServiceDiscoveryFactory extends AbstractServiceDiscoveryFact
@Override
protected ServiceDiscovery createDiscovery(URL registryURL) {
String protocol = registryURL.getProtocol();
ExtensionLoader<ServiceDiscovery> loader = getExtensionLoader(ServiceDiscovery.class);
ExtensionLoader<ServiceDiscovery> loader = registryURL.getOrDefaultApplicationModel().getExtensionLoader(ServiceDiscovery.class);
return loader.getExtension(protocol);
}
}

View File

@ -212,6 +212,7 @@ public class DefaultServiceInstance implements ServiceInstance {
}
@Override
@Transient
public Map<String, Object> getAttributes() {
return attributes;
}

View File

@ -20,8 +20,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.SPI;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
/**
* The factory to create {@link ServiceDiscovery}
*
@ -47,7 +45,7 @@ public interface ServiceDiscoveryFactory {
*/
static ServiceDiscoveryFactory getExtension(URL registryURL) {
String protocol = registryURL.getProtocol();
ExtensionLoader<ServiceDiscoveryFactory> loader = getExtensionLoader(ServiceDiscoveryFactory.class);
ExtensionLoader<ServiceDiscoveryFactory> loader = registryURL.getOrDefaultApplicationModel().getExtensionLoader(ServiceDiscoveryFactory.class);
return loader.getOrDefaultExtension(protocol);
}
}

View File

@ -115,7 +115,7 @@ public class ServiceDiscoveryRegistry implements Registry {
}
private List<SubscribedURLsSynthesizer> initSubscribedURLsSynthesizers() {
ExtensionLoader<SubscribedURLsSynthesizer> loader = ExtensionLoader.getExtensionLoader(SubscribedURLsSynthesizer.class);
ExtensionLoader<SubscribedURLsSynthesizer> loader = getUrl().getOrDefaultApplicationModel().getExtensionLoader(SubscribedURLsSynthesizer.class);
return Collections.unmodifiableList(new ArrayList<>(loader.getSupportedExtensionInstances()));
}

View File

@ -36,7 +36,6 @@ import org.apache.dubbo.rpc.RpcServiceContext;
import org.apache.dubbo.rpc.cluster.Configurator;
import org.apache.dubbo.rpc.cluster.RouterChain;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.ArrayList;
import java.util.Collections;
@ -75,7 +74,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
applicationModel = getApplicationModel(url.getScopeModel());
consumerConfigurationListener = new ConsumerConfigurationListener(applicationModel);
Set<ProviderFirstParams> providerFirstParams = ScopeModelUtil.getApplicationModel(url.getScopeModel()).getExtensionLoader(ProviderFirstParams.class).getSupportedExtensionInstances();
Set<ProviderFirstParams> providerFirstParams = url.getOrDefaultApplicationModel().getExtensionLoader(ProviderFirstParams.class).getSupportedExtensionInstances();
if (CollectionUtils.isEmpty(providerFirstParams)) {
this.providerFirstParams = null;
} else {
@ -147,7 +146,7 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
RpcServiceContext.setRpcContext(getConsumerUrl());
// 3.x added for extend URL address
ExtensionLoader<AddressListener> addressListenerExtensionLoader = ExtensionLoader.getExtensionLoader(AddressListener.class);
ExtensionLoader<AddressListener> addressListenerExtensionLoader = getUrl().getOrDefaultApplicationModel().getExtensionLoader(AddressListener.class);
List<AddressListener> supportedListeners = addressListenerExtensionLoader.getActivateExtension(getUrl(), (String[]) null);
if (supportedListeners != null && !supportedListeners.isEmpty()) {
for (AddressListener addressListener : supportedListeners) {
@ -294,11 +293,11 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
if (EMPTY_PROTOCOL.equals(instanceAddressURL.getProtocol())) {
continue;
}
if (!ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(instanceAddressURL.getProtocol())) {
if (!getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).hasExtension(instanceAddressURL.getProtocol())) {
logger.error(new IllegalStateException("Unsupported protocol " + instanceAddressURL.getProtocol() +
" in notified url: " + instanceAddressURL + " from registry " + getUrl().getAddress() +
" to consumer " + NetUtils.getLocalHost() + ", supported protocol: " +
ExtensionLoader.getExtensionLoader(Protocol.class).getSupportedExtensions()));
getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).getSupportedExtensions()));
continue;
}

View File

@ -17,7 +17,9 @@
package org.apache.dubbo.registry.client;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.beans.Transient;
import java.io.Serializable;
import java.util.Map;
import java.util.SortedMap;
@ -96,6 +98,11 @@ public interface ServiceInstance extends Serializable {
ApplicationModel getApplicationModel();
@Transient
default ApplicationModel getOrDefaultApplicationModel() {
return ScopeModelUtil.getApplicationModel(getApplicationModel());
}
/**
* Get the value of metadata by the specified name
*

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.registry.client.event.listener;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
@ -35,6 +34,7 @@ import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
import org.apache.dubbo.registry.client.metadata.MetadataUtils;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.ArrayList;
import java.util.Collections;
@ -80,7 +80,7 @@ public class ServiceInstancesChangedListener {
private volatile long lastRefreshTime;
private Semaphore retryPermission;
private volatile ScheduledFuture<?> retryFuture;
private static ScheduledExecutorService scheduler = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension().getMetadataRetryExecutor();
private ScheduledExecutorService scheduler;
public ServiceInstancesChangedListener(Set<String> serviceNames, ServiceDiscovery serviceDiscovery) {
this.serviceNames = serviceNames;
@ -90,6 +90,8 @@ public class ServiceInstancesChangedListener {
this.serviceUrls = new HashMap<>();
this.revisionToMetadata = new HashMap<>();
retryPermission = new Semaphore(1);
this.scheduler = ScopeModelUtil.getApplicationModel(serviceDiscovery == null || serviceDiscovery.getUrl() == null ? null : serviceDiscovery.getUrl().getScopeModel())
.getExtensionLoader(ExecutorRepository.class).getDefaultExtension().getMetadataRetryExecutor();
}
/**

View File

@ -29,7 +29,6 @@ import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.registry.client.RegistryClusterIdentifier;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
import java.util.Collections;
import java.util.List;
@ -38,7 +37,7 @@ import java.util.Set;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
public class MetadataServiceNameMapping extends AbstractServiceNameMapping implements ScopeModelAware {
public class MetadataServiceNameMapping extends AbstractServiceNameMapping {
private final Logger logger = LoggerFactory.getLogger(getClass());
@ -47,8 +46,8 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping imple
private static final int CAS_RETRY_TIMES = 6;
protected MetadataReportInstance metadataReportInstance;
public MetadataServiceNameMapping() {
metadataReportInstance = ApplicationModel.defaultModel().getBeanFactory().getBean(MetadataReportInstance.class);
public MetadataServiceNameMapping(ApplicationModel applicationModel) {
metadataReportInstance = applicationModel.getBeanFactory().getBean(MetadataReportInstance.class);
}
@Override
@ -109,12 +108,6 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping imple
return metadataReport.getServiceAppMapping(serviceInterface, mappingListener, url);
}
@Override
public void setApplicationModel(ApplicationModel applicationModel) {
super.setApplicationModel(applicationModel);
metadataReportInstance = applicationModel.getBeanFactory().getBean(MetadataReportInstance.class);
}
protected String getRegistryCluster(URL url) {
String registryCluster = RegistryClusterIdentifier.getExtension(url).providerKey(url);
if (registryCluster == null) {

View File

@ -55,7 +55,7 @@ public class MetadataUtils {
WritableMetadataService.getDefaultExtension(url.getScopeModel()).publishServiceDefinition(url);
// send to remote
if (REMOTE_METADATA_STORAGE_TYPE.equalsIgnoreCase(url.getParameter(METADATA_KEY))) {
getRemoteMetadataService(ScopeModelUtil.getApplicationModel(url.getScopeModel())).publishServiceDefinition(url);
getRemoteMetadataService(url.getOrDefaultApplicationModel()).publishServiceDefinition(url);
}
}
@ -79,8 +79,8 @@ public class MetadataUtils {
private static MetadataService referProxy(String key, ServiceInstance instance) {
MetadataServiceURLBuilder builder = null;
ExtensionLoader<MetadataServiceURLBuilder> loader
= ExtensionLoader.getExtensionLoader(MetadataServiceURLBuilder.class);
ExtensionLoader<MetadataServiceURLBuilder> loader = instance.getOrDefaultApplicationModel()
.getExtensionLoader(MetadataServiceURLBuilder.class);
Map<String, String> metadata = instance.getMetadata();
// METADATA_SERVICE_URLS_PROPERTY_NAME is a unique key exists only on instances of spring-cloud-alibaba.

View File

@ -284,7 +284,7 @@ public class ServiceInstanceMetadataUtils {
public static void customizeInstance(ServiceInstance instance) {
ExtensionLoader<ServiceInstanceCustomizer> loader =
ExtensionLoader.getExtensionLoader(ServiceInstanceCustomizer.class);
instance.getOrDefaultApplicationModel().getExtensionLoader(ServiceInstanceCustomizer.class);
// FIXME, sort customizer before apply
loader.getSupportedExtensionInstances().forEach(customizer -> {
// customizes

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.registry.client.migration;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
@ -34,6 +33,7 @@ import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.model.ConsumerModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.Map;
import java.util.Set;
@ -178,7 +178,8 @@ public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
return true;
}
Set<MigrationAddressComparator> detectors = ExtensionLoader.getExtensionLoader(MigrationAddressComparator.class).getSupportedExtensionInstances();
Set<MigrationAddressComparator> detectors = ScopeModelUtil.getApplicationModel(consumerUrl == null ? null : consumerUrl.getScopeModel())
.getExtensionLoader(MigrationAddressComparator.class).getSupportedExtensionInstances();
if (CollectionUtils.isNotEmpty(detectors)) {
if (detectors.stream().allMatch(comparator -> comparator.shouldMigrate(invoker, serviceDiscoveryInvoker, newRule))) {
this.currentAvailableInvoker = invoker;
@ -215,7 +216,8 @@ public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
return true;
}
Set<MigrationAddressComparator> detectors = ExtensionLoader.getExtensionLoader(MigrationAddressComparator.class).getSupportedExtensionInstances();
Set<MigrationAddressComparator> detectors = ScopeModelUtil.getApplicationModel(consumerUrl == null ? null : consumerUrl.getScopeModel())
.getExtensionLoader(MigrationAddressComparator.class).getSupportedExtensionInstances();
if (CollectionUtils.isNotEmpty(detectors)) {
if (detectors.stream().allMatch(comparator -> comparator.shouldMigrate(serviceDiscoveryInvoker, invoker, newRule))) {
this.currentAvailableInvoker = serviceDiscoveryInvoker;
@ -461,7 +463,8 @@ public class MigrationInvoker<T> implements MigrationClusterInvoker<T> {
if (serviceDiscoveryInvoker == null || invoker == null) {
return;
}
Set<MigrationAddressComparator> detectors = ExtensionLoader.getExtensionLoader(MigrationAddressComparator.class).getSupportedExtensionInstances();
Set<MigrationAddressComparator> detectors = ScopeModelUtil.getApplicationModel(consumerUrl == null ? null : consumerUrl.getScopeModel())
.getExtensionLoader(MigrationAddressComparator.class).getSupportedExtensionInstances();
if (CollectionUtils.isNotEmpty(detectors)) {
// pick preferred invoker
// the real invoker choice in invocation will be affected by promotion

View File

@ -106,7 +106,10 @@ public abstract class AbstractConfiguratorListener implements ConfigurationListe
try {
// parseConfigurators will recognize app/service config automatically.
List<URL> urls = ConfigParser.parseConfigurators(rawConfig);
List<URL> safeUrls = urls.stream().map(url -> url.removeParameters(securityKey)).collect(Collectors.toList());
List<URL> safeUrls = urls.stream()
.map(url -> url.removeParameters(securityKey))
.map(url -> url.setScopeModel(applicationModel))
.collect(Collectors.toList());
configurators = Configurator.toConfigurators(safeUrls).orElse(configurators);
} catch (Exception e) {
logger.error("Failed to parse raw dynamic config and it will not take effect, the raw config is: " +

View File

@ -56,10 +56,9 @@ public abstract class DynamicDirectory<T> extends AbstractDirectory<T> implement
private static final Logger logger = LoggerFactory.getLogger(DynamicDirectory.class);
protected static final Cluster CLUSTER = ExtensionLoader.getExtensionLoader(Cluster.class).getAdaptiveExtension();
protected final Cluster cluster;
protected static final RouterFactory ROUTER_FACTORY = ExtensionLoader.getExtensionLoader(RouterFactory.class)
.getAdaptiveExtension();
protected final RouterFactory routerFactory;
/**
* Initialization at construction time, assertion not null
@ -113,6 +112,9 @@ public abstract class DynamicDirectory<T> extends AbstractDirectory<T> implement
public DynamicDirectory(Class<T> serviceType, URL url) {
super(url, true);
this.cluster = url.getOrDefaultApplicationModel().getExtensionLoader(Cluster.class).getAdaptiveExtension();
this.routerFactory = url.getOrDefaultApplicationModel().getExtensionLoader(RouterFactory.class).getAdaptiveExtension();
if (serviceType == null) {
throw new IllegalArgumentException("service type is null.");
}
@ -280,7 +282,7 @@ public abstract class DynamicDirectory<T> extends AbstractDirectory<T> implement
logger.warn("unexpected error when unsubscribe service " + serviceKey + " from registry: " + registry.getUrl(), t);
}
ExtensionLoader<AddressListener> addressListenerExtensionLoader = ExtensionLoader.getExtensionLoader(AddressListener.class);
ExtensionLoader<AddressListener> addressListenerExtensionLoader = getUrl().getOrDefaultApplicationModel().getExtensionLoader(AddressListener.class);
List<AddressListener> supportedListeners = addressListenerExtensionLoader.getActivateExtension(getUrl(), (String[]) null);
if (supportedListeners != null && !supportedListeners.isEmpty()) {
for (AddressListener addressListener : supportedListeners) {

View File

@ -146,7 +146,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
List<URL> providerURLs = categoryUrls.getOrDefault(PROVIDERS_CATEGORY, Collections.emptyList());
// 3.x added for extend URL address
ExtensionLoader<AddressListener> addressListenerExtensionLoader = ExtensionLoader.getExtensionLoader(AddressListener.class);
ExtensionLoader<AddressListener> addressListenerExtensionLoader = getUrl().getOrDefaultApplicationModel().getExtensionLoader(AddressListener.class);
List<AddressListener> supportedListeners = addressListenerExtensionLoader.getActivateExtension(getUrl(), (String[]) null);
if (supportedListeners != null && !supportedListeners.isEmpty()) {
for (AddressListener addressListener : supportedListeners) {
@ -265,7 +265,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
for (List<Invoker<T>> groupList : groupMap.values()) {
StaticDirectory<T> staticDirectory = new StaticDirectory<>(groupList);
staticDirectory.buildRouterChain();
mergedInvokers.add(CLUSTER.join(staticDirectory));
mergedInvokers.add(cluster.join(staticDirectory));
}
} else {
mergedInvokers = invokers;
@ -293,7 +293,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
url = url.setProtocol(routerType);
}
try {
Router router = ROUTER_FACTORY.getRouter(url);
Router router = routerFactory.getRouter(url);
if (!routers.contains(router)) {
routers.add(router);
}
@ -335,11 +335,11 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
if (EMPTY_PROTOCOL.equals(providerUrl.getProtocol())) {
continue;
}
if (!ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) {
if (!getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).hasExtension(providerUrl.getProtocol())) {
logger.error(new IllegalStateException("Unsupported protocol " + providerUrl.getProtocol() +
" in notified url: " + providerUrl + " from registry " + getUrl().getAddress() +
" to consumer " + NetUtils.getLocalHost() + ", supported protocol: " +
ExtensionLoader.getExtensionLoader(Protocol.class).getSupportedExtensions()));
getUrl().getOrDefaultFrameworkModel().getExtensionLoader(Protocol.class).getSupportedExtensions()));
continue;
}
URL url = mergeUrl(providerUrl);
@ -381,7 +381,7 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
if (providerUrl instanceof ServiceAddressURL) {
providerUrl = overrideWithConfigurator(providerUrl);
} else {
providerUrl = ClusterUtils.mergeUrl(providerUrl, queryMap); // Merge the consumer side parameters
providerUrl = applicationModel.getBeanFactory().getBean(ClusterUtils.class).mergeUrl(providerUrl, queryMap); // Merge the consumer side parameters
providerUrl = overrideWithConfigurator(providerUrl);
providerUrl = providerUrl.addParameter(Constants.CHECK_KEY, String.valueOf(false)); // Do not check whether the connection is successful or not, always create Invoker!
}

View File

@ -472,11 +472,11 @@ public class RegistryProtocol implements Protocol, ScopeModelAware {
String group = qs.get(GROUP_KEY);
if (group != null && group.length() > 0) {
if ((COMMA_SPLIT_PATTERN.split(group)).length > 1 || "*".equals(group)) {
return doRefer(Cluster.getCluster(MergeableCluster.NAME), registry, type, url, qs);
return doRefer(Cluster.getCluster(url.getScopeModel(), MergeableCluster.NAME), registry, type, url, qs);
}
}
Cluster cluster = Cluster.getCluster(qs.get(CLUSTER_KEY));
Cluster cluster = Cluster.getCluster(url.getScopeModel(), qs.get(CLUSTER_KEY));
return doRefer(cluster, registry, type, url, qs);
}

View File

@ -20,7 +20,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.URLStrParser;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
@ -34,7 +33,6 @@ import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.ProviderFirstParams;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.ArrayList;
import java.util.Collection;
@ -85,7 +83,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
extraParameters = new HashMap<>(8);
extraParameters.put(CHECK_KEY, String.valueOf(false));
cacheRemovalScheduler = ScopeModelUtil.getApplicationModel(url.getScopeModel()).getExtensionLoader(ExecutorRepository.class).getDefaultExtension().nextScheduledExecutor();
cacheRemovalScheduler = url.getOrDefaultApplicationModel().getExtensionLoader(ExecutorRepository.class).getDefaultExtension().nextScheduledExecutor();
cacheRemovalTaskIntervalInMillis = getIntConfig(url.getScopeModel(), CACHE_CLEAR_TASK_INTERVAL, 2 * 60 * 1000);
cacheClearWaitingThresholdInMillis = getIntConfig(url.getScopeModel(), CACHE_CLEAR_WAITING_THRESHOLD, 5 * 60 * 1000);
}
@ -232,7 +230,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
}
protected URL removeParamsFromConsumer(URL consumer) {
Set<ProviderFirstParams> providerFirstParams = ExtensionLoader.getExtensionLoader(ProviderFirstParams.class).getSupportedExtensionInstances();
Set<ProviderFirstParams> providerFirstParams = consumer.getOrDefaultApplicationModel().getExtensionLoader(ProviderFirstParams.class).getSupportedExtensionInstances();
if (CollectionUtils.isEmpty(providerFirstParams)) {
return consumer;
}

View File

@ -0,0 +1 @@
dubbo-registry-api=org.apache.dubbo.registry.RegistryScopeModelInitializer

View File

@ -28,8 +28,6 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Collections;
@ -50,7 +48,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@ -59,7 +56,6 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
public class ServiceDiscoveryRegistryTest {
public static final String APP_NAME1 = "app1";
@ -97,6 +93,9 @@ public class ServiceDiscoveryRegistryTest {
doNothing().when(instanceListener).onEvent(any());
when(serviceDiscovery.createListener(any())).thenReturn(instanceListener);
when(serviceDiscovery.getInstances(any())).thenReturn(Collections.emptyList());
ApplicationModel applicationModel = spy(ApplicationModel.defaultModel());
when(applicationModel.getDefaultExtension(ServiceNameMapping.class)).thenReturn(mapping);
registryURL = registryURL.setScopeModel(applicationModel);
spiedMetadataService = spy(WritableMetadataService.getDefaultExtension(ApplicationModel.defaultModel()));
serviceDiscoveryRegistry = new ServiceDiscoveryRegistry(registryURL, serviceDiscovery, spiedMetadataService);
@ -160,59 +159,56 @@ public class ServiceDiscoveryRegistryTest {
*/
@Test
public void testSubscribeURLs() {
try (MockedStatic<ServiceNameMapping> mockStaticMapping = Mockito.mockStatic(ServiceNameMapping.class, withSettings().defaultAnswer(CALLS_REAL_METHODS))) {
mockStaticMapping.when(ServiceNameMapping::getDefaultExtension).thenReturn(mapping);
// interface to single app mapping
Set<String> singleApp = new TreeSet<>();
singleApp.add(APP_NAME1);
serviceDiscoveryRegistry.subscribeURLs(url, testServiceListener, singleApp);
// interface to single app mapping
Set<String> singleApp = new TreeSet<>();
singleApp.add(APP_NAME1);
serviceDiscoveryRegistry.subscribeURLs(url, testServiceListener, singleApp);
assertEquals(1, serviceDiscoveryRegistry.getServiceListeners().size());
verify(testServiceListener, times(1)).addServiceListener(instanceListener);
verify(instanceListener, never()).onEvent(any());
verify(serviceDiscovery, times(1)).addServiceInstancesChangedListener(instanceListener);
assertEquals(1, serviceDiscoveryRegistry.getServiceListeners().size());
verify(testServiceListener, times(1)).addServiceListener(instanceListener);
verify(instanceListener, never()).onEvent(any());
verify(serviceDiscovery, times(1)).addServiceInstancesChangedListener(instanceListener);
// interface to multiple apps mapping
Set<String> multiApps = new TreeSet<>();
multiApps.add(APP_NAME1);
multiApps.add(APP_NAME2);
MockServiceInstancesChangedListener multiAppsInstanceListener = spy(new MockServiceInstancesChangedListener(multiApps, serviceDiscovery));
doNothing().when(multiAppsInstanceListener).onEvent(any());
List<URL> urls = new ArrayList<>();
urls.add(URL.valueOf("dubbo://127.0.0.1:20880/TestService"));
doReturn(urls).when(multiAppsInstanceListener).getAddresses(any(), any());
when(serviceDiscovery.createListener(multiApps)).thenReturn(multiAppsInstanceListener);
when(serviceDiscovery.getInstances(APP_NAME1)).thenReturn(instanceList1);
when(serviceDiscovery.getInstances(APP_NAME2)).thenReturn(instanceList2);
serviceDiscoveryRegistry.subscribeURLs(url, testServiceListener, multiApps);
// interface to multiple apps mapping
Set<String> multiApps = new TreeSet<>();
multiApps.add(APP_NAME1);
multiApps.add(APP_NAME2);
MockServiceInstancesChangedListener multiAppsInstanceListener = spy(new MockServiceInstancesChangedListener(multiApps, serviceDiscovery));
doNothing().when(multiAppsInstanceListener).onEvent(any());
List<URL> urls = new ArrayList<>();
urls.add(URL.valueOf("dubbo://127.0.0.1:20880/TestService"));
doReturn(urls).when(multiAppsInstanceListener).getAddresses(any(), any());
when(serviceDiscovery.createListener(multiApps)).thenReturn(multiAppsInstanceListener);
when(serviceDiscovery.getInstances(APP_NAME1)).thenReturn(instanceList1);
when(serviceDiscovery.getInstances(APP_NAME2)).thenReturn(instanceList2);
serviceDiscoveryRegistry.subscribeURLs(url, testServiceListener, multiApps);
assertEquals(2, serviceDiscoveryRegistry.getServiceListeners().size());
assertEquals(instanceListener, serviceDiscoveryRegistry.getServiceListeners().get(toStringKeys(singleApp)));
assertEquals(multiAppsInstanceListener, serviceDiscoveryRegistry.getServiceListeners().get(toStringKeys(multiApps)));
verify(testServiceListener, times(1)).addServiceListener(multiAppsInstanceListener);
verify(multiAppsInstanceListener, times(2)).onEvent(any());
verify(multiAppsInstanceListener, times(1)).addListenerAndNotify(any(), eq(testServiceListener));
verify(serviceDiscovery, times(1)).addServiceInstancesChangedListener(multiAppsInstanceListener);
ArgumentCaptor<List<URL>> captor = ArgumentCaptor.forClass(List.class);
verify(testServiceListener).notify(captor.capture());
assertEquals(urls, captor.getValue());
assertEquals(2, serviceDiscoveryRegistry.getServiceListeners().size());
assertEquals(instanceListener, serviceDiscoveryRegistry.getServiceListeners().get(toStringKeys(singleApp)));
assertEquals(multiAppsInstanceListener, serviceDiscoveryRegistry.getServiceListeners().get(toStringKeys(multiApps)));
verify(testServiceListener, times(1)).addServiceListener(multiAppsInstanceListener);
verify(multiAppsInstanceListener, times(2)).onEvent(any());
verify(multiAppsInstanceListener, times(1)).addListenerAndNotify(any(), eq(testServiceListener));
verify(serviceDiscovery, times(1)).addServiceInstancesChangedListener(multiAppsInstanceListener);
ArgumentCaptor<List<URL>> captor = ArgumentCaptor.forClass(List.class);
verify(testServiceListener).notify(captor.capture());
assertEquals(urls, captor.getValue());
// different interface mapping to the same apps
NotifyListener testServiceListener2 = mock(NotifyListener.class);
URL url2 = URL.valueOf("consumer://127.0.0.1/TestService2?interface=TestService1&check=false&protocol=tri");
serviceDiscoveryRegistry.subscribeURLs(url2, testServiceListener2, multiApps);
// check instance listeners not changed, methods not called
assertEquals(2, serviceDiscoveryRegistry.getServiceListeners().size());
assertEquals(multiAppsInstanceListener, serviceDiscoveryRegistry.getServiceListeners().get(toStringKeys(multiApps)));
verify(multiAppsInstanceListener, times(1)).addListenerAndNotify(any(), eq(testServiceListener));
// still called once, not executed this time
verify(serviceDiscovery, times(1)).addServiceInstancesChangedListener(multiAppsInstanceListener);
// check different protocol
Map<String, NotifyListener> serviceListeners = multiAppsInstanceListener.getServiceListeners();
assertEquals(2, serviceListeners.size());
String protocolServiceKey = url2.getServiceKey() + GROUP_CHAR_SEPARATOR + url2.getParameter(PROTOCOL_KEY, DUBBO);
assertEquals(testServiceListener2, serviceListeners.get(protocolServiceKey));
}
// different interface mapping to the same apps
NotifyListener testServiceListener2 = mock(NotifyListener.class);
URL url2 = URL.valueOf("consumer://127.0.0.1/TestService2?interface=TestService1&check=false&protocol=tri");
serviceDiscoveryRegistry.subscribeURLs(url2, testServiceListener2, multiApps);
// check instance listeners not changed, methods not called
assertEquals(2, serviceDiscoveryRegistry.getServiceListeners().size());
assertEquals(multiAppsInstanceListener, serviceDiscoveryRegistry.getServiceListeners().get(toStringKeys(multiApps)));
verify(multiAppsInstanceListener, times(1)).addListenerAndNotify(any(), eq(testServiceListener));
// still called once, not executed this time
verify(serviceDiscovery, times(1)).addServiceInstancesChangedListener(multiAppsInstanceListener);
// check different protocol
Map<String, NotifyListener> serviceListeners = multiAppsInstanceListener.getServiceListeners();
assertEquals(2, serviceListeners.size());
String protocolServiceKey = url2.getServiceKey() + GROUP_CHAR_SEPARATOR + url2.getParameter(PROTOCOL_KEY, DUBBO);
assertEquals(testServiceListener2, serviceListeners.get(protocolServiceKey));
}
/**

View File

@ -60,7 +60,7 @@ public class MetadataServiceNameMappingTest {
applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
configManager = mock(ConfigManager.class);
metadataReport = mock(MetadataReport.class);
mapping = new MetadataServiceNameMapping();
mapping = new MetadataServiceNameMapping(ApplicationModel.defaultModel());
mapping.setApplicationModel(applicationModel);
url = URL.valueOf("dubbo://127.0.0.1:20880/TestService?version=1.0.0");
}

View File

@ -20,7 +20,6 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.ServiceNameMapping;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
@ -76,7 +75,7 @@ public class MigrationRuleTest {
assertEquals(false, migrationRule.getForce());
URL url = Mockito.mock(URL.class);
ModuleModel defaultModule = Mockito.spy(ApplicationModel.defaultModel().getDefaultModule());
ApplicationModel defaultModule = Mockito.spy(ApplicationModel.defaultModel());
Mockito.when(defaultModule.getDefaultExtension(ServiceNameMapping.class)).thenReturn(mapping);
Mockito.when(url.getScopeModel()).thenReturn(defaultModule);

View File

@ -154,8 +154,8 @@ public class DNSServiceDiscoveryTest {
serviceInstances = dnsServiceDiscovery.getInstances("Test.Service.");
assertEquals("c", serviceInstances.get(0).getMetadata("a"));
dnsServiceDiscovery.addServiceInstancesChangedListener(changedListener);
ArgumentCaptor<ServiceInstancesChangedEvent> argument = ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class);
dnsServiceDiscovery.addServiceInstancesChangedListener(changedListener);
Thread.sleep(1000);
Mockito.verify(changedListener, Mockito.timeout(1000)).onEvent(argument.capture());
assertEquals("c", argument.getValue().getServiceInstances().get(0).getMetadata("a"));

View File

@ -19,7 +19,6 @@ package org.apache.dubbo.registry.multiple;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
@ -44,7 +43,7 @@ public class MultipleRegistry extends AbstractRegistry {
public static final String REGISTRY_FOR_SERVICE = "service-registry";
public static final String REGISTRY_FOR_REFERENCE = "reference-registry";
protected RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
protected RegistryFactory registryFactory;
private final Map<String, Registry> serviceRegistries = new ConcurrentHashMap<>(4);
private final Map<String, Registry> referenceRegistries = new ConcurrentHashMap<String, Registry>(4);
private final Map<NotifyListener, MultipleNotifyListenerWrapper> multipleNotifyListenerMap = new ConcurrentHashMap<NotifyListener, MultipleNotifyListenerWrapper>(32);
@ -57,6 +56,7 @@ public class MultipleRegistry extends AbstractRegistry {
public MultipleRegistry(URL url) {
this(url, true, true);
this.registryFactory = url.getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
boolean defaultRegistry = url.getParameter(CommonConstants.DEFAULT_KEY, true);
if (defaultRegistry && effectServiceRegistryURLs.isEmpty() && effectReferenceRegistryURLs.isEmpty()) {
@ -69,6 +69,8 @@ public class MultipleRegistry extends AbstractRegistry {
super(url);
this.registryUrl = url;
this.applicationName = url.getApplication();
this.registryFactory = url.getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
init();
checkApplicationName(this.applicationName);
// This urls contain parameter and it donot inherit from the parameter of url in MultipleRegistry

View File

@ -609,7 +609,7 @@ public class NacosRegistry extends FailbackRegistry {
private RegistryNotifier notifier;
public RegistryChildListenerImpl(String serviceName, URL consumerUrl, NotifyListener listener) {
notifier = new RegistryNotifier(NacosRegistry.this.getDelay()) {
notifier = new RegistryNotifier(getUrl(), NacosRegistry.this.getDelay()) {
@Override
protected void doNotify(Object rawAddresses) {
List<Instance> instances = (List<Instance>) rawAddresses;

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.registry.xds.util;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.registry.xds.XdsCertificateSigner;
@ -45,7 +44,7 @@ public class XdsChannel {
protected XdsChannel(URL url) {
ManagedChannel channel1 = null;
try {
XdsCertificateSigner signer = ExtensionLoader.getExtensionLoader(XdsCertificateSigner.class).getExtension(url.getParameter("Signer","istio"));
XdsCertificateSigner signer = url.getOrDefaultApplicationModel().getExtensionLoader(XdsCertificateSigner.class).getExtension(url.getParameter("Signer","istio"));
XdsCertificateSigner.CertPair certPair = signer.request(url);
SslContext context = GrpcSslContexts.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)

View File

@ -301,7 +301,7 @@ public class ZookeeperRegistry extends CacheableFailbackRegistry {
public RegistryChildListenerImpl(URL consumerUrl, String path, NotifyListener listener, CountDownLatch latch) {
this.latch = latch;
notifier = new RegistryNotifier(ZookeeperRegistry.this.getDelay()) {
notifier = new RegistryNotifier(getUrl(), ZookeeperRegistry.this.getDelay()) {
@Override
public void notify(Object rawAddresses) {
long delayTime = getDelayTime();

View File

@ -65,7 +65,7 @@ public class ZookeeperServiceDiscoveryChangeWatcher implements CuratorWatcher {
this.serviceName = serviceName;
this.path = path;
this.latch = latch;
this.notifier = new RegistryNotifier(zookeeperServiceDiscovery.getDelay(),
this.notifier = new RegistryNotifier(zookeeperServiceDiscovery.getUrl(), zookeeperServiceDiscovery.getDelay(),
ScopeModelUtil.getApplicationModel(zookeeperServiceDiscovery.getUrl().getScopeModel()).getApplicationExecutorRepository().getServiceDiscoveryAddressNotificationExecutor()) {
@Override
protected void doNotify(Object rawAddresses) {

View File

@ -18,7 +18,6 @@ package org.apache.dubbo.remoting;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.remoting.transport.ChannelHandlerAdapter;
import org.apache.dubbo.remoting.transport.ChannelHandlerDispatcher;
@ -53,7 +52,7 @@ public class Transporters {
} else {
handler = new ChannelHandlerDispatcher(handlers);
}
return getTransporter().bind(url, handler);
return getTransporter(url).bind(url, handler);
}
public static Client connect(String url, ChannelHandler... handler) throws RemotingException {
@ -72,11 +71,11 @@ public class Transporters {
} else {
handler = new ChannelHandlerDispatcher(handlers);
}
return getTransporter().connect(url, handler);
return getTransporter(url).connect(url, handler);
}
public static Transporter getTransporter() {
return ExtensionLoader.getExtensionLoader(Transporter.class).getAdaptiveExtension();
public static Transporter getTransporter(URL url) {
return url.getOrDefaultFrameworkModel().getExtensionLoader(Transporter.class).getAdaptiveExtension();
}
}

View File

@ -17,8 +17,8 @@
package org.apache.dubbo.remoting.api;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.rpc.model.FrameworkModel;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -27,6 +27,12 @@ import java.util.function.Consumer;
public class MultiplexProtocolConnectionManager implements ConnectionManager {
private final ConcurrentMap<String, ConnectionManager> protocols = new ConcurrentHashMap<>();
private FrameworkModel frameworkModel;
public MultiplexProtocolConnectionManager(FrameworkModel frameworkModel) {
this.frameworkModel = frameworkModel;
}
@Override
public Connection connect(URL url) throws RemotingException {
final ConnectionManager manager = protocols.computeIfAbsent(url.getProtocol(), this::createSingleProtocolConnectionManager);
@ -39,6 +45,6 @@ public class MultiplexProtocolConnectionManager implements ConnectionManager {
}
private ConnectionManager createSingleProtocolConnectionManager(String protocol) {
return ExtensionLoader.getExtensionLoader(ConnectionManager.class).getExtension("single");
return frameworkModel.getExtensionLoader(ConnectionManager.class).getExtension("single");
}
}

View File

@ -21,7 +21,6 @@ import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.OpenSsl;
@ -39,7 +38,7 @@ public class SslContexts {
private static final Logger logger = LoggerFactory.getLogger(SslContexts.class);
public static SslContext buildServerSslContext(URL url) {
ConfigManager globalConfigManager = ScopeModelUtil.getApplicationModel(url.getScopeModel()).getApplicationConfigManager();
ConfigManager globalConfigManager = url.getOrDefaultApplicationModel().getApplicationConfigManager();
SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!"));
SslContextBuilder sslClientContextBuilder;
@ -68,7 +67,7 @@ public class SslContexts {
}
public static SslContext buildClientSslContext(URL url) {
ConfigManager globalConfigManager = ScopeModelUtil.getApplicationModel(url.getScopeModel()).getApplicationConfigManager();
ConfigManager globalConfigManager = url.getOrDefaultApplicationModel().getApplicationConfigManager();
SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!"));
SslContextBuilder builder = SslContextBuilder.forClient();

View File

@ -18,7 +18,6 @@ package org.apache.dubbo.remoting.exchange;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.RemotingException;
@ -111,11 +110,7 @@ public class Exchangers {
public static Exchanger getExchanger(URL url) {
String type = url.getParameter(Constants.EXCHANGER_KEY, Constants.DEFAULT_EXCHANGER);
return getExchanger(type);
}
public static Exchanger getExchanger(String type) {
return ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension(type);
return url.getOrDefaultFrameworkModel().getExtensionLoader(Exchanger.class).getExtension(type);
}
}

View File

@ -18,7 +18,6 @@ package org.apache.dubbo.remoting.transport;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
@ -49,10 +48,11 @@ public abstract class AbstractClient extends AbstractEndpoint implements Client
private final Lock connectLock = new ReentrantLock();
private final boolean needReconnect;
protected volatile ExecutorService executor;
private ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
private ExecutorRepository executorRepository;
public AbstractClient(URL url, ChannelHandler handler) throws RemotingException {
super(url, handler);
executorRepository = url.getOrDefaultApplicationModel().getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
// set default needReconnect true when channel is not connected
needReconnect = url.getParameter(Constants.SEND_RECONNECT_KEY, true);

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.remoting.transport;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
@ -50,10 +49,11 @@ public abstract class AbstractServer extends AbstractEndpoint implements Remotin
private InetSocketAddress bindAddress;
private int accepts;
private ExecutorRepository executorRepository = ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
private ExecutorRepository executorRepository;
public AbstractServer(URL url, ChannelHandler handler) throws RemotingException {
super(url, handler);
executorRepository = url.getOrDefaultApplicationModel().getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
localAddress = getUrl().toInetSocketAddress();
String bindIp = getUrl().getParameter(Constants.BIND_IP_KEY, getUrl().getHost());

View File

@ -79,7 +79,7 @@ public class CodecSupport {
}
public static Serialization getSerialization(URL url) {
return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(
return url.getOrDefaultFrameworkModel().getExtensionLoader(Serialization.class).getExtension(
url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION));
}

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.remoting.transport.dispatcher;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.Dispatcher;
import org.apache.dubbo.remoting.exchange.support.header.HeartbeatHandler;
@ -43,7 +42,7 @@ public class ChannelHandlers {
}
protected ChannelHandler wrapInternal(ChannelHandler handler, URL url) {
return new MultiMessageHandler(new HeartbeatHandler(ExtensionLoader.getExtensionLoader(Dispatcher.class)
return new MultiMessageHandler(new HeartbeatHandler(url.getOrDefaultFrameworkModel().getExtensionLoader(Dispatcher.class)
.getAdaptiveExtension().dispatch(handler, url)));
}
}

View File

@ -17,6 +17,8 @@
package org.apache.dubbo.rpc;
import org.apache.dubbo.common.Experimental;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.util.Map;
@ -46,6 +48,7 @@ public interface Invocation {
/**
* get the interface name
*
* @return
*/
String getServiceName();
@ -65,8 +68,8 @@ public interface Invocation {
*/
default String[] getCompatibleParamSignatures() {
return Stream.of(getParameterTypes())
.map(Class::getName)
.toArray(String[]::new);
.map(Class::getName)
.toArray(String[]::new);
}
/**
@ -143,6 +146,10 @@ public interface Invocation {
ServiceModel getServiceModel();
default ModuleModel getModuleModel() {
return ScopeModelUtil.getModuleModel(getServiceModel() == null ? null : getServiceModel().getModuleModel());
}
Object put(Object key, Object value);
Object get(Object key);

View File

@ -22,7 +22,6 @@ import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.io.UnsafeByteArrayInputStream;
import org.apache.dubbo.common.io.UnsafeByteArrayOutputStream;
import org.apache.dubbo.common.logger.Logger;
@ -131,7 +130,7 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
for (int i = 0; i < args.length; i++) {
if (byte[].class == args[i].getClass()) {
try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
args[i] = ExtensionLoader.getExtensionLoader(Serialization.class)
args[i] = applicationModel.getExtensionLoader(Serialization.class)
.getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA)
.deserialize(null, is).readObject();
} catch (Exception e) {
@ -166,7 +165,7 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
if (args.length == 1 && args[0] instanceof String) {
try (UnsafeByteArrayInputStream is =
new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) {
args[0] = ExtensionLoader.getExtensionLoader(Serialization.class)
args[0] = applicationModel.getExtensionLoader(Serialization.class)
.getExtension(GENERIC_SERIALIZATION_PROTOBUF)
.deserialize(null, is).readObject(method.getParameterTypes()[0]);
} catch (Exception e) {
@ -236,7 +235,7 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
if (ProtocolUtils.isJavaGenericSerialization(generic)) {
try {
UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA)
applicationModel.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA)
.serialize(null, os).writeObject(appResponse.getValue());
appResponse.setValue(os.toByteArray());
} catch (IOException e) {
@ -250,7 +249,7 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
} else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
try {
UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
ExtensionLoader.getExtensionLoader(Serialization.class)
applicationModel.getExtensionLoader(Serialization.class)
.getExtension(GENERIC_SERIALIZATION_PROTOBUF)
.serialize(null, os).writeObject(appResponse.getValue());
appResponse.setValue(os.toString());

View File

@ -211,7 +211,7 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
}
// server context attachment
ExtensionLoader<PenetrateAttachmentSelector> selectorExtensionLoader = ExtensionLoader.getExtensionLoader(PenetrateAttachmentSelector.class);
ExtensionLoader<PenetrateAttachmentSelector> selectorExtensionLoader = invocation.getModuleModel().getExtensionLoader(PenetrateAttachmentSelector.class);
Set<String> supportedSelectors = selectorExtensionLoader.getSupportedExtensions();
if (CollectionUtils.isNotEmpty(supportedSelectors)) {
// custom context attachment
@ -293,7 +293,7 @@ public abstract class AbstractInvoker<T> implements Invoker<T> {
// -- Protected api
protected ExecutorService getCallbackExecutor(URL url, Invocation inv) {
ExecutorService sharedExecutor = ExtensionLoader.getExtensionLoader(ExecutorRepository.class)
ExecutorService sharedExecutor = url.getOrDefaultApplicationModel().getExtensionLoader(ExecutorRepository.class)
.getDefaultExtension()
.getExecutor(url);
if (InvokeMode.SYNC == RpcUtils.getInvokeMode(getUrl(), inv)) {

View File

@ -17,8 +17,8 @@
package org.apache.dubbo.rpc.support;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionDirector;
import org.apache.dubbo.common.extension.ExtensionInjector;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.PojoUtils;
@ -48,7 +48,7 @@ import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
final public class MockInvoker<T> implements Invoker<T> {
private final static ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
private final ProxyFactory proxyFactory;
private final static Map<String, Invoker<?>> MOCK_MAP = new ConcurrentHashMap<String, Invoker<?>>();
private final static Map<String, Throwable> THROWABLE_MAP = new ConcurrentHashMap<String, Throwable>();
@ -58,6 +58,7 @@ final public class MockInvoker<T> implements Invoker<T> {
public MockInvoker(URL url, Class<T> type) {
this.url = url;
this.type = type;
this.proxyFactory = url.getOrDefaultFrameworkModel().getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
}
public static Object parseMockValue(String mock) throws Exception {
@ -169,8 +170,8 @@ final public class MockInvoker<T> implements Invoker<T> {
return invoker;
}
T mockObject = (T) getMockObject(mock, serviceType);
invoker = PROXY_FACTORY.getInvoker(mockObject, serviceType, url);
T mockObject = (T) getMockObject(url.getOrDefaultApplicationModel().getExtensionDirector(), mock, serviceType);
invoker = proxyFactory.getInvoker(mockObject, serviceType, url);
if (MOCK_MAP.size() < 10000) {
MOCK_MAP.put(mockService, invoker);
}
@ -178,7 +179,7 @@ final public class MockInvoker<T> implements Invoker<T> {
}
@SuppressWarnings("unchecked")
public static Object getMockObject(String mockService, Class serviceType) {
public static Object getMockObject(ExtensionDirector extensionDirector, String mockService, Class serviceType) {
boolean isDefault = ConfigUtils.isDefault(mockService);
if (isDefault) {
mockService = serviceType.getName() + "Mock";
@ -190,7 +191,7 @@ final public class MockInvoker<T> implements Invoker<T> {
} catch (Exception e) {
if (!isDefault) {// does not check Spring bean if it is default config.
ExtensionInjector extensionFactory =
ExtensionLoader.getExtensionLoader(ExtensionInjector.class).getAdaptiveExtension();
extensionDirector.getExtensionLoader(ExtensionInjector.class).getAdaptiveExtension();
Object obj = extensionFactory.getInstance(serviceType, mockService);
if (obj != null) {
return obj;

Some files were not shown because too many files have changed in this diff Show More