Add 3.0 Multi Instance Support (#8662)
* Add ExtensionDirector and Models
* Fix access static getter method of ApplicationModel
* Replace ExtensionFactory with ExtensionInjector
* specify scope of some SPIs
* Support scoped injection for extension
* improve create extension loader logic
* Add ScopeModel and ScopeBeanFactory, fix extension initialization of XxxConfig
* polish doc of scope model
* Extract FrameworkStatusReportService from FrameworkStatusReporter
* Fix application model of default bootstrap instance
* Pass scope model through URL
* Fix scope model of registry, metadata, cluster and so on
* exact ServiceModel from ProviderModel and ConsumerModel
* Add ASF license header for ScopeBeanFactoryInitializer
* Remove unused import
* Remove unused import
* Fix ut in ConfigManagerTest
* Change default Scope Behave
* Resolve recursive creation of Scope Model
* Fix inject default model when scope is parent
* Fix inject default model when scope is parent
* Compact with url without ScopeModel
* Change HttpBinder Scope
* Change some SPIs' scope
* Fix setApplicationModel override issue of MetadataServiceNameMapping
* Default inject ScopeModel in ConfigManager
* Add default Scope for AbstractConfig when init
* Fix field override & Fix ut env
* Fix zk not startup in DubboBootstrapMultiInstanceTest
* Fix ExtensionAccessor not inject in UT of MetricsFilterTest
* Compact old style getName
* Fix UT in DNSServiceDiscoveryTest
* Compact old style ApplicationModel
* Fix UT in DNSServiceDiscoveryTest
* Fix repository changed after ApplicationModel destroyed
* Fix SpringExtensionInjector pollution in UT
* Pass ApplicationModel in ServiceInstance
* reintroduce metadata delay key
* Add Transient on ApplicationModel getter of DefaultServiceInstance
* Fix Configurator Listener in Singleton mode override issue
* Fix Configurator Listener in Singleton mode override issue
* Compact old style getApplication
* Invocation pass ServiceModel
* Compact old style registerConsumer
* Fix NPE in RpcInvocation
* Add ServiceModel pass when init
* Fix ServiceModel cast error
* Add ServiceModel pass when invoke
* Fix NPE when simplify registry url
* Revert "Resolve recursive creation of Scope Model"
This reverts commit 37a99957
* Improve scope model aware
* polish scope model
* Cleanup ApplicationModel.defaultModel usage
* Fix ut
* Compatible with 2.6 Registry
* Fix ut
* Add Callback Service build ProviderModel
* improve scope model of config bean
* Fix scope model of reference/service model
* Revert CallbackServiceCodec for dev
* Fix scope model NPE
* Fix consumer url NPE
* Add Callback Service build ProviderModel
* Fix NPE when destroy
* Fix ut
* add failback logic for ut
* Fix ut
* Add Scope Model check
* Fix uts
* Fix ut in DubboBootstrapTest
* Fix ut in DubboBootstrapTest
* Fix uts
* Reset ApplicationModel Before Test
Co-authored-by: gongdewei <kylixs@qq.com>
This commit is contained in:
parent
b8de0a7fd5
commit
ff39bf36c3
|
|
@ -16,11 +16,12 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.cluster.filter;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
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.Invoker;
|
||||
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -33,7 +34,8 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
|
|||
@Override
|
||||
public <T> Invoker<T> buildInvokerChain(final Invoker<T> originalInvoker, String key, String group) {
|
||||
Invoker<T> last = originalInvoker;
|
||||
List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(originalInvoker.getUrl(), key, group);
|
||||
URL url = originalInvoker.getUrl();
|
||||
List<Filter> filters = ScopeModelUtil.getExtensionLoader(Filter.class, url.getScopeModel()).getActivateExtension(url, key, group);
|
||||
|
||||
if (!filters.isEmpty()) {
|
||||
for (int i = filters.size() - 1; i >= 0; i--) {
|
||||
|
|
@ -52,7 +54,8 @@ public class DefaultFilterChainBuilder implements FilterChainBuilder {
|
|||
@Override
|
||||
public <T> ClusterInvoker<T> buildClusterInvokerChain(final ClusterInvoker<T> originalInvoker, String key, String group) {
|
||||
ClusterInvoker<T> last = originalInvoker;
|
||||
List<ClusterFilter> filters = ExtensionLoader.getExtensionLoader(ClusterFilter.class).getActivateExtension(originalInvoker.getUrl(), key, group);
|
||||
URL url = originalInvoker.getUrl();
|
||||
List<ClusterFilter> filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, url.getScopeModel()).getActivateExtension(url, key, group);
|
||||
|
||||
if (!filters.isEmpty()) {
|
||||
for (int i = filters.size() - 1; i >= 0; i--) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ import org.apache.dubbo.rpc.RpcException;
|
|||
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.Directory;
|
||||
|
||||
@SPI("default")
|
||||
import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
|
||||
|
||||
@SPI(value = "default", scope = APPLICATION)
|
||||
public interface FilterChainBuilder {
|
||||
/**
|
||||
* build consumer/provider filter chain
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ package org.apache.dubbo.rpc.cluster.filter;
|
|||
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.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.rpc.Exporter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.ProtocolServer;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -39,8 +39,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.SERVICE_FILTER_K
|
|||
public class ProtocolFilterWrapper implements Protocol {
|
||||
|
||||
private final Protocol protocol;
|
||||
private static final FilterChainBuilder builder
|
||||
= ExtensionLoader.getExtensionLoader(FilterChainBuilder.class).getDefaultExtension();
|
||||
|
||||
public ProtocolFilterWrapper(Protocol protocol) {
|
||||
if (protocol == null) {
|
||||
|
|
@ -59,14 +57,20 @@ public class ProtocolFilterWrapper implements Protocol {
|
|||
if (UrlUtils.isRegistry(invoker.getUrl())) {
|
||||
return protocol.export(invoker);
|
||||
}
|
||||
FilterChainBuilder builder = getFilterChainBuilder(invoker.getUrl());
|
||||
return protocol.export(builder.buildInvokerChain(invoker, SERVICE_FILTER_KEY, CommonConstants.PROVIDER));
|
||||
}
|
||||
|
||||
private <T> FilterChainBuilder getFilterChainBuilder(URL url) {
|
||||
return ScopeModelUtil.getExtensionLoader(FilterChainBuilder.class, url.getScopeModel()).getDefaultExtension();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
|
||||
if (UrlUtils.isRegistry(url)) {
|
||||
return protocol.refer(type, url);
|
||||
}
|
||||
FilterChainBuilder builder = getFilterChainBuilder(url);
|
||||
return builder.buildInvokerChain(protocol.refer(type, url), REFERENCE_FILTER_KEY, CommonConstants.CONSUMER);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,11 @@ package org.apache.dubbo.rpc.cluster.governance;
|
|||
import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
|
||||
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleRepository {
|
||||
public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleRepository, ScopeModelAware {
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
|
||||
@Override
|
||||
public void addListener(String key, String group, ConfigurationListener listener) {
|
||||
|
|
@ -47,8 +50,13 @@ public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleReposi
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
}
|
||||
|
||||
private DynamicConfiguration getDynamicConfiguration() {
|
||||
return ApplicationModel.getEnvironment().getDynamicConfiguration().orElse(null);
|
||||
return ApplicationModel.ofNullable(applicationModel).getApplicationEnvironment().getDynamicConfiguration().orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ package org.apache.dubbo.rpc.cluster.governance;
|
|||
import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI("default")
|
||||
import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
|
||||
|
||||
@SPI(value = "default", scope = APPLICATION)
|
||||
public interface GovernanceRuleRepository {
|
||||
|
||||
String DEFAULT_GROUP = "dubbo";
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.dubbo.rpc.Invoker;
|
|||
import org.apache.dubbo.rpc.RpcStatus;
|
||||
import org.apache.dubbo.rpc.cluster.Constants;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -41,11 +42,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
* if there are multiple invokers and the weights are not the same, then random according to the total weight;
|
||||
* if there are multiple invokers and the same weight, then randomly called.
|
||||
*/
|
||||
public class ShortestResponseLoadBalance extends AbstractLoadBalance {
|
||||
public class ShortestResponseLoadBalance extends AbstractLoadBalance implements ScopeModelAware {
|
||||
|
||||
public static final String NAME = "shortestresponse";
|
||||
|
||||
private static final int SLIDE_PERIOD = ApplicationModel.getEnvironment().getConfiguration().getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
|
||||
private int SLIDE_PERIOD = 30_000;
|
||||
|
||||
private ConcurrentMap<RpcStatus, SlideWindowData> methodMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
|
@ -53,6 +54,11 @@ public class ShortestResponseLoadBalance extends AbstractLoadBalance {
|
|||
|
||||
private volatile long lastUpdateTime = System.currentTimeMillis();
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
SLIDE_PERIOD = applicationModel.getApplicationEnvironment().getConfiguration().getInt(Constants.SHORTEST_RESPONSE_SLIDE_PERIOD, 30_000);
|
||||
}
|
||||
|
||||
protected static class SlideWindowData {
|
||||
private final static ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor((new NamedThreadFactory("Dubbo-slidePeriod-reset")));
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public final class MeshRuleManager {
|
|||
|
||||
MeshAppRuleListener meshAppRuleListener = new MeshAppRuleListener(app);
|
||||
String appRuleDataId = app + MESH_RULE_DATA_ID_SUFFIX;
|
||||
DynamicConfiguration configuration = ApplicationModel.getEnvironment().getDynamicConfiguration()
|
||||
DynamicConfiguration configuration = ApplicationModel.defaultModel().getApplicationEnvironment().getDynamicConfiguration()
|
||||
.orElse(null);
|
||||
|
||||
Set<MeshEnvListenerFactory> envListenerFactories = ExtensionLoader.getExtensionLoader(MeshEnvListenerFactory.class).getSupportedExtensionInstances();
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public abstract class AbstractCluster implements Cluster {
|
|||
// AbstractClusterInvoker<T> last = clusterInvoker;
|
||||
AbstractClusterInvoker<T> last = buildInterceptorInvoker(new ClusterFilterInvoker<>(clusterInvoker));
|
||||
|
||||
if (Boolean.parseBoolean(ConfigurationUtils.getProperty(CLUSTER_INTERCEPTOR_COMPATIBLE_KEY, "false"))) {
|
||||
if (Boolean.parseBoolean(ConfigurationUtils.getProperty(clusterInvoker.getDirectory().getConsumerUrl().getScopeModel(), CLUSTER_INTERCEPTOR_COMPATIBLE_KEY, "false"))) {
|
||||
return build27xCompatibleClusterInterceptors(clusterInvoker, last);
|
||||
}
|
||||
return last;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.apache.dubbo.rpc.cluster;
|
|||
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
|
|
@ -72,7 +71,6 @@ public class StickyTest {
|
|||
|
||||
clusterinvoker = new StickyClusterInvoker<StickyTest>(dic);
|
||||
|
||||
ExtensionLoader.resetExtensionLoader(LoadBalance.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.rpc.cluster.directory;
|
|||
import org.apache.dubbo.rpc.AttachmentsAdapter;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -129,6 +130,16 @@ public class MockDirInvocation implements Invocation {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceModel(ServiceModel serviceModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceModel getServiceModel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Object, Object> getAttributes() {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ package org.apache.dubbo.rpc.cluster.loadbalance;
|
|||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcStatus;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Order;
|
||||
|
|
@ -42,6 +44,7 @@ public class ShortestResponseLoadBalanceTest extends LoadBalanceBaseTest {
|
|||
int loop = 10000;
|
||||
|
||||
ShortestResponseLoadBalance lb = new ShortestResponseLoadBalance();
|
||||
lb.setApplicationModel(ApplicationModel.defaultModel());
|
||||
for (int i = 0; i < loop; i++) {
|
||||
Invoker selected = lb.select(weightInvokersSR, null, weightTestInvocation);
|
||||
|
||||
|
|
@ -74,6 +77,7 @@ public class ShortestResponseLoadBalanceTest extends LoadBalanceBaseTest {
|
|||
//active -> 0
|
||||
RpcStatus.endCount(weightInvoker5.getUrl(), weightTestInvocation.getMethodName(), 5000L, true);
|
||||
ShortestResponseLoadBalance lb = new ShortestResponseLoadBalance();
|
||||
lb.setApplicationModel(ApplicationModel.defaultModel());
|
||||
|
||||
//reset slideWindow
|
||||
Field lastUpdateTimeField = ReflectUtils.forName(ShortestResponseLoadBalance.class.getName()).getDeclaredField("lastUpdateTime");
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.dubbo.rpc.cluster.router.mesh.route;
|
|||
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.rule.VsDestinationGroup;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
|
@ -38,11 +39,11 @@ public class MeshRuleManagerTest {
|
|||
|
||||
@Test
|
||||
public void subscribeAppRule() {
|
||||
Optional<DynamicConfiguration> before = ApplicationModel.getEnvironment().getDynamicConfiguration();
|
||||
Optional<DynamicConfiguration> before = ApplicationModel.defaultModel().getApplicationEnvironment().getDynamicConfiguration();
|
||||
try {
|
||||
DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
||||
|
||||
ApplicationModel.getEnvironment().setDynamicConfiguration(dynamicConfiguration);
|
||||
ApplicationModel.defaultModel().getApplicationEnvironment().setDynamicConfiguration(dynamicConfiguration);
|
||||
|
||||
MeshRuleManager.subscribeAppRule("test");
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ public class MeshRuleManagerTest {
|
|||
|
||||
assertEquals("test.MESHAPPRULE", result);
|
||||
} finally {
|
||||
ApplicationModel.getEnvironment().setDynamicConfiguration(before.orElse(null));
|
||||
ApplicationModel.defaultModel().getApplicationEnvironment().setDynamicConfiguration(before.orElse(null));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -61,11 +62,11 @@ public class MeshRuleManagerTest {
|
|||
|
||||
@Test
|
||||
public void register() {
|
||||
Optional<DynamicConfiguration> before = ApplicationModel.getEnvironment().getDynamicConfiguration();
|
||||
Optional<DynamicConfiguration> before = ApplicationModel.defaultModel().getApplicationEnvironment().getDynamicConfiguration();
|
||||
try {
|
||||
DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
||||
|
||||
ApplicationModel.getEnvironment().setDynamicConfiguration(dynamicConfiguration);
|
||||
ApplicationModel.defaultModel().getApplicationEnvironment().setDynamicConfiguration(dynamicConfiguration);
|
||||
|
||||
when(dynamicConfiguration.getConfig(anyString(), anyString(), anyLong())).thenReturn("apiVersion: service.dubbo.apache.org/v1alpha1\n" +
|
||||
"kind: VirtualService\n" +
|
||||
|
|
@ -109,17 +110,17 @@ public class MeshRuleManagerTest {
|
|||
assertEquals(1, result.getVirtualServiceRuleList().size());
|
||||
assertEquals(0, result.getDestinationRuleList().size());
|
||||
} finally {
|
||||
ApplicationModel.getEnvironment().setDynamicConfiguration(before.orElse(null));
|
||||
ApplicationModel.defaultModel().getApplicationEnvironment().setDynamicConfiguration(before.orElse(null));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unregister() {
|
||||
Optional<DynamicConfiguration> before = ApplicationModel.getEnvironment().getDynamicConfiguration();
|
||||
Optional<DynamicConfiguration> before = ApplicationModel.defaultModel().getApplicationEnvironment().getDynamicConfiguration();
|
||||
try {
|
||||
DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
||||
|
||||
ApplicationModel.getEnvironment().setDynamicConfiguration(dynamicConfiguration);
|
||||
ApplicationModel.defaultModel().getApplicationEnvironment().setDynamicConfiguration(dynamicConfiguration);
|
||||
|
||||
when(dynamicConfiguration.getConfig(anyString(), anyString(), anyLong())).thenReturn("apiVersion: service.dubbo.apache.org/v1alpha1\n" +
|
||||
"kind: VirtualService\n" +
|
||||
|
|
@ -154,7 +155,7 @@ public class MeshRuleManagerTest {
|
|||
MeshRuleManager.unregister(meshRuleRouter);
|
||||
|
||||
} finally {
|
||||
ApplicationModel.getEnvironment().setDynamicConfiguration(before.orElse(null));
|
||||
ApplicationModel.defaultModel().getApplicationEnvironment().setDynamicConfiguration(before.orElse(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.common;
|
|||
|
||||
import org.apache.dubbo.common.config.Configuration;
|
||||
import org.apache.dubbo.common.config.InmemoryConfiguration;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.constants.RemotingConstants;
|
||||
import org.apache.dubbo.common.url.component.PathURLAddress;
|
||||
import org.apache.dubbo.common.url.component.ServiceConfigURL;
|
||||
|
|
@ -29,6 +30,8 @@ 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.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
|
@ -122,15 +125,22 @@ class URL implements Serializable {
|
|||
|
||||
private transient String serviceKey;
|
||||
private transient String protocolServiceKey;
|
||||
protected final Map<String, Object> attributes;
|
||||
|
||||
protected URL() {
|
||||
this.urlAddress = null;
|
||||
this.urlParam = null;
|
||||
this.attributes = new HashMap<>();
|
||||
}
|
||||
|
||||
public URL(URLAddress urlAddress, URLParam urlParam) {
|
||||
this(urlAddress, urlParam, null);
|
||||
}
|
||||
|
||||
public URL(URLAddress urlAddress, URLParam urlParam, Map<String, Object> attributes) {
|
||||
this.urlAddress = urlAddress;
|
||||
this.urlParam = urlParam;
|
||||
this.attributes = (attributes != null ? attributes : new HashMap<>());
|
||||
}
|
||||
|
||||
public URL(String protocol, String host, int port) {
|
||||
|
|
@ -179,6 +189,7 @@ class URL implements Serializable {
|
|||
|
||||
this.urlAddress = new PathURLAddress(protocol, username, password, path, host, port);
|
||||
this.urlParam = URLParam.parse(parameters);
|
||||
this.attributes = new HashMap<>();
|
||||
}
|
||||
|
||||
protected URL(String protocol,
|
||||
|
|
@ -196,6 +207,7 @@ class URL implements Serializable {
|
|||
|
||||
this.urlAddress = new PathURLAddress(protocol, username, password, path, host, port);
|
||||
this.urlParam = URLParam.parse(parameters);
|
||||
this.attributes = new HashMap<>();
|
||||
}
|
||||
|
||||
public static URL cacheableValueOf(String url) {
|
||||
|
|
@ -218,6 +230,10 @@ class URL implements Serializable {
|
|||
return valueOf(url, false);
|
||||
}
|
||||
|
||||
public static URL valueOf(String url, ScopeModel scopeModel) {
|
||||
return valueOf(url).setScopeModel(scopeModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse normal or encoded url string into strutted URL:
|
||||
* - dubbo://host:port/path?param=value
|
||||
|
|
@ -271,8 +287,8 @@ class URL implements Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
return newMap.isEmpty() ? new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), (Map<String, String>) null)
|
||||
: new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), newMap);
|
||||
return newMap.isEmpty() ? new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), (Map<String, String>) null, url.getAttributes())
|
||||
: new ServiceConfigURL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), newMap, url.getAttributes());
|
||||
}
|
||||
|
||||
public static String encode(String value) {
|
||||
|
|
@ -532,6 +548,22 @@ class URL implements Serializable {
|
|||
return result;
|
||||
}
|
||||
|
||||
public URL setScopeModel(ScopeModel scopeModel) {
|
||||
return putAttribute(CommonConstants.SCOPE_MODEL, scopeModel);
|
||||
}
|
||||
|
||||
public ScopeModel getScopeModel() {
|
||||
return (ScopeModel) getAttribute(CommonConstants.SCOPE_MODEL);
|
||||
}
|
||||
|
||||
public URL setServiceModel(ServiceModel serviceModel) {
|
||||
return putAttribute(CommonConstants.SERVICE_MODEL, serviceModel);
|
||||
}
|
||||
|
||||
public ServiceModel getServiceModel() {
|
||||
return (ServiceModel) getAttribute(CommonConstants.SERVICE_MODEL);
|
||||
}
|
||||
|
||||
protected Map<String, Number> getNumbers() {
|
||||
// concurrent initialization is tolerant
|
||||
if (numbers == null) {
|
||||
|
|
@ -1449,7 +1481,7 @@ class URL implements Serializable {
|
|||
}
|
||||
|
||||
protected <T extends URL> T newURL(URLAddress urlAddress, URLParam urlParam) {
|
||||
return (T) new ServiceConfigURL(urlAddress, urlParam, null);
|
||||
return (T) new ServiceConfigURL(urlAddress, urlParam, attributes);
|
||||
}
|
||||
|
||||
/* methods introduced for CompositeURL, CompositeURL must override to make the implementations meaningful */
|
||||
|
|
@ -1517,27 +1549,30 @@ class URL implements Serializable {
|
|||
|
||||
/* Service Config URL, START*/
|
||||
public Map<String, Object> getAttributes() {
|
||||
return new HashMap<>();
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public URL addAttributes(Map<String, Object> attributes) {
|
||||
attributes.putAll(attributes);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object getAttribute(String key) {
|
||||
return null;
|
||||
return attributes.get(key);
|
||||
}
|
||||
|
||||
public URL putAttribute(String key, Object obj) {
|
||||
attributes.put(key, obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
public URL removeAttribute(String key) {
|
||||
attributes.remove(key);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean hasAttribute(String key) {
|
||||
return true;
|
||||
return attributes.containsKey(key);
|
||||
}
|
||||
|
||||
/* Service Config URL, END*/
|
||||
|
|
|
|||
|
|
@ -19,12 +19,15 @@ package org.apache.dubbo.common;
|
|||
import org.apache.dubbo.common.url.component.ServiceConfigURL;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SCOPE_MODEL;
|
||||
|
||||
public final class URLBuilder extends ServiceConfigURL {
|
||||
private String protocol;
|
||||
|
||||
|
|
@ -206,6 +209,12 @@ public final class URLBuilder extends ServiceConfigURL {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URLBuilder setScopeModel(ScopeModel scopeModel) {
|
||||
this.attributes.put(SCOPE_MODEL, scopeModel);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URLBuilder addParameterAndEncoded(String key, String value) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.beans;
|
||||
|
||||
public class ScopeBeanException extends RuntimeException {
|
||||
|
||||
public ScopeBeanException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ScopeBeanException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.beans;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionInjector;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
/**
|
||||
* Inject scope bean to SPI extension instance
|
||||
*/
|
||||
public class ScopeBeanExtensionInjector implements ExtensionInjector, ScopeModelAware {
|
||||
private ScopeModel scopeModel;
|
||||
private ScopeBeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void setScopeModel(ScopeModel scopeModel) {
|
||||
this.scopeModel = scopeModel;
|
||||
this.beanFactory = scopeModel.getBeanFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInstance(Class<T> type, String name) {
|
||||
return beanFactory.getBean(name, type);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* 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.beans.factory;
|
||||
|
||||
import org.apache.dubbo.common.beans.ScopeBeanException;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessor;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessorAware;
|
||||
import org.apache.dubbo.common.extension.ExtensionPostProcessor;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* A bean factory for internal sharing.
|
||||
*/
|
||||
public class ScopeBeanFactory {
|
||||
|
||||
private final ScopeBeanFactory parent;
|
||||
private ExtensionAccessor extensionAccessor;
|
||||
private List<ExtensionPostProcessor> extensionPostProcessors;
|
||||
private Map<Class, AtomicInteger> beanNameIdCounterMap = new ConcurrentHashMap<>();
|
||||
private List<BeanInfo> registeredBeanInfos = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
public ScopeBeanFactory(ScopeBeanFactory parent, ExtensionAccessor extensionAccessor) {
|
||||
this.parent = parent;
|
||||
this.extensionAccessor = extensionAccessor;
|
||||
extensionPostProcessors = extensionAccessor.getExtensionDirector().getExtensionPostProcessors();
|
||||
}
|
||||
|
||||
public <T> T registerBean(Class<T> bean) throws ScopeBeanException {
|
||||
return this.registerBean(null, bean);
|
||||
}
|
||||
|
||||
public <T> T registerBean(String name, Class<T> clazz) throws ScopeBeanException {
|
||||
T instance = getBean(name, clazz);
|
||||
if (instance != null) {
|
||||
throw new ScopeBeanException("already exists bean with same name and type, name=" + name + ", type=" + clazz.getName());
|
||||
}
|
||||
try {
|
||||
instance = clazz.newInstance();
|
||||
} catch (Throwable e) {
|
||||
throw new ScopeBeanException("create bean instance failed, type=" + clazz.getName());
|
||||
}
|
||||
registerBean(name, instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void registerBean(Object bean) {
|
||||
this.registerBean(null, bean);
|
||||
}
|
||||
|
||||
public void registerBean(String name, Object bean) {
|
||||
// avoid duplicated register same bean
|
||||
if (containsBean(name, bean)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> beanClass = bean.getClass();
|
||||
if (name == null) {
|
||||
name = beanClass.getName() + "#" + getNextId(beanClass);
|
||||
}
|
||||
initializeBean(name, bean);
|
||||
|
||||
registeredBeanInfos.add(new BeanInfo(name, bean));
|
||||
}
|
||||
|
||||
public <T> T registerBeanIfAbsent(Class<T> type) {
|
||||
return registerBeanIfAbsent(null, type);
|
||||
}
|
||||
|
||||
public <T> T registerBeanIfAbsent(String name, Class<T> type) {
|
||||
T bean = getBean(name, type);
|
||||
if (bean == null) {
|
||||
bean = registerBean(name, type);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
public <T> T registerBeanIfAbsent(Class<T> type, Function<? super Class<T>, ? extends T> mappingFunction) {
|
||||
return registerBeanIfAbsent(null, type, mappingFunction);
|
||||
}
|
||||
|
||||
public <T> T registerBeanIfAbsent(String name, Class<T> type, Function<? super Class<T>, ? extends T> mappingFunction) {
|
||||
T bean = getBean(name, type);
|
||||
if (bean == null) {
|
||||
//TODO add lock
|
||||
bean = mappingFunction.apply(type);
|
||||
registerBean(name, bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
public <T> T initializeBean(T bean) {
|
||||
this.initializeBean(null, bean);
|
||||
return bean;
|
||||
}
|
||||
|
||||
private void initializeBean(String name, Object bean) {
|
||||
try {
|
||||
if (bean instanceof ExtensionAccessorAware) {
|
||||
((ExtensionAccessorAware) bean).setExtensionAccessor(extensionAccessor);
|
||||
}
|
||||
for (ExtensionPostProcessor processor : extensionPostProcessors) {
|
||||
processor.postProcessAfterInitialization(bean, name);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ScopeBeanException("register bean failed! name=" + name + ", type=" + bean.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsBean(String name, Object bean) {
|
||||
for (BeanInfo beanInfo : registeredBeanInfos) {
|
||||
if (beanInfo.instance == bean &&
|
||||
(name == null || StringUtils.isEquals(name, beanInfo.name))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getNextId(Class<?> beanClass) {
|
||||
return beanNameIdCounterMap.computeIfAbsent(beanClass, key -> new AtomicInteger()).incrementAndGet();
|
||||
}
|
||||
|
||||
public <T> T getBean(Class<T> type) {
|
||||
return this.getBean(null, type);
|
||||
}
|
||||
|
||||
public <T> T getBean(String name, Class<T> type) {
|
||||
T bean = getBeanInternal(name, type);
|
||||
if (bean == null && parent != null) {
|
||||
return parent.getBean(name, type);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
private <T> T getBeanInternal(String name, Class<T> type) {
|
||||
List<BeanInfo> candidates = null;
|
||||
for (BeanInfo beanInfo : registeredBeanInfos) {
|
||||
// if required bean type is same class/superclass/interface of the registered bean
|
||||
if (type.isAssignableFrom(beanInfo.instance.getClass())) {
|
||||
if (StringUtils.isEquals(beanInfo.name, name)) {
|
||||
return (T) beanInfo.instance;
|
||||
} else {
|
||||
if (candidates == null) {
|
||||
candidates = new ArrayList<>();
|
||||
}
|
||||
candidates.add(beanInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if bean name not matched and only single candidate
|
||||
if (candidates != null) {
|
||||
if (candidates.size() == 1) {
|
||||
return (T) candidates.get(0).instance;
|
||||
} else if (candidates.size() > 1) {
|
||||
List<String> candidateBeanNames = candidates.stream().map(beanInfo -> beanInfo.name).collect(Collectors.toList());
|
||||
throw new ScopeBeanException("expected single matching bean but found " + candidates.size() + " candidates for type [" + type.getName() + "]: " + candidateBeanNames);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static class BeanInfo {
|
||||
private String name;
|
||||
private Object instance;
|
||||
|
||||
public BeanInfo(String name, Object instance) {
|
||||
this.name = name;
|
||||
this.instance = instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.beans.factory;
|
||||
|
||||
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.ScopeModelPostProcessor;
|
||||
|
||||
/**
|
||||
* Initialize the bean factory for ScopeModel
|
||||
*/
|
||||
public abstract class ScopeBeanFactoryInitializer implements ScopeModelPostProcessor {
|
||||
|
||||
@Override
|
||||
public void postProcessScopeModel(ScopeModel scopeModel) {
|
||||
if (scopeModel instanceof ApplicationModel) {
|
||||
ApplicationModel applicationModel = (ApplicationModel) scopeModel;
|
||||
registerApplicationBeans(applicationModel, applicationModel.getBeanFactory());
|
||||
} else if (scopeModel instanceof FrameworkModel) {
|
||||
FrameworkModel frameworkModel = (FrameworkModel) scopeModel;
|
||||
registerFrameworkBeans(frameworkModel, frameworkModel.getBeanFactory());
|
||||
} else if (scopeModel instanceof ModuleModel) {
|
||||
ModuleModel moduleModel = (ModuleModel) scopeModel;
|
||||
registerModuleBeans(moduleModel, moduleModel.getBeanFactory());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize beans for framework
|
||||
*
|
||||
* @param frameworkModel
|
||||
* @param beanFactory
|
||||
*/
|
||||
protected void registerFrameworkBeans(FrameworkModel frameworkModel, ScopeBeanFactory beanFactory) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize beans for application
|
||||
*
|
||||
* @param applicationModel
|
||||
* @param beanFactory
|
||||
*/
|
||||
protected void registerApplicationBeans(ApplicationModel applicationModel, ScopeBeanFactory beanFactory) {
|
||||
// beanFactory.registerBean(MetadataReportInstance.class);
|
||||
// beanFactory.registerBean(RemoteMetadataServiceImpl.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize beans for module
|
||||
*
|
||||
* @param moduleModel
|
||||
* @param beanFactory
|
||||
*/
|
||||
protected void registerModuleBeans(ModuleModel moduleModel, ScopeBeanFactory beanFactory) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,12 +16,13 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.compiler;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
/**
|
||||
* Compiler. (SPI, Singleton, ThreadSafe)
|
||||
*/
|
||||
@SPI("javassist")
|
||||
@SPI(value = "javassist", scope = ExtensionScope.FRAMEWORK)
|
||||
public interface Compiler {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -16,10 +16,15 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.config;
|
||||
|
||||
import org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessor;
|
||||
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.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
|
@ -48,8 +53,8 @@ public class ConfigurationUtils {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public static Configuration getSystemConfiguration() {
|
||||
return ApplicationModel.getEnvironment().getSystemConfiguration();
|
||||
public static Configuration getSystemConfiguration(ScopeModel scopeModel) {
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel).getApplicationEnvironment().getSystemConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -57,8 +62,9 @@ public class ConfigurationUtils {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public static Configuration getEnvConfiguration() {
|
||||
return ApplicationModel.getEnvironment().getEnvironmentConfiguration();
|
||||
|
||||
public static Configuration getEnvConfiguration(ScopeModel scopeModel) {
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel).getApplicationEnvironment().getEnvironmentConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -68,19 +74,20 @@ public class ConfigurationUtils {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
public static Configuration getGlobalConfiguration() {
|
||||
return ApplicationModel.getEnvironment().getConfiguration();
|
||||
|
||||
public static Configuration getGlobalConfiguration(ScopeModel scopeModel) {
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel).getApplicationEnvironment().getConfiguration();
|
||||
}
|
||||
|
||||
public static Configuration getDynamicGlobalConfiguration() {
|
||||
return ApplicationModel.getEnvironment().getDynamicGlobalConfiguration();
|
||||
public static Configuration getDynamicGlobalConfiguration(ScopeModel scopeModel) {
|
||||
return ScopeModelUtil.getApplicationModel(scopeModel).getApplicationEnvironment().getDynamicGlobalConfiguration();
|
||||
}
|
||||
|
||||
// FIXME
|
||||
@SuppressWarnings("deprecation")
|
||||
public static int getServerShutdownTimeout() {
|
||||
public static int getServerShutdownTimeout(ScopeModel scopeModel) {
|
||||
int timeout = DEFAULT_SERVER_SHUTDOWN_TIMEOUT;
|
||||
Configuration configuration = getGlobalConfiguration();
|
||||
Configuration configuration = getGlobalConfiguration(scopeModel);
|
||||
String value = StringUtils.trim(configuration.getString(SHUTDOWN_WAIT_KEY));
|
||||
|
||||
if (value != null && value.length() > 0) {
|
||||
|
|
@ -102,29 +109,29 @@ public class ConfigurationUtils {
|
|||
return timeout;
|
||||
}
|
||||
|
||||
public static String getCachedDynamicProperty(String key, String defaultValue) {
|
||||
String value = CACHED_DYNAMIC_PROPERTIES.computeIfAbsent(key, _k -> ConfigurationUtils.getDynamicProperty(key, ""));
|
||||
public static String getCachedDynamicProperty(ScopeModel scopeModel, String key, String defaultValue) {
|
||||
String value = CACHED_DYNAMIC_PROPERTIES.computeIfAbsent(key, _k -> ConfigurationUtils.getDynamicProperty(scopeModel, key, ""));
|
||||
return StringUtils.isEmpty(value) ? defaultValue : value;
|
||||
}
|
||||
|
||||
public static String getDynamicProperty(String property) {
|
||||
return getDynamicProperty(property, null);
|
||||
public static String getDynamicProperty(ScopeModel scopeModel, String property) {
|
||||
return getDynamicProperty(scopeModel, property, null);
|
||||
}
|
||||
|
||||
public static String getDynamicProperty(String property, String defaultValue) {
|
||||
return StringUtils.trim(getDynamicGlobalConfiguration().getString(property, defaultValue));
|
||||
public static String getDynamicProperty(ScopeModel scopeModel, String property, String defaultValue) {
|
||||
return StringUtils.trim(getDynamicGlobalConfiguration(scopeModel).getString(property, defaultValue));
|
||||
}
|
||||
|
||||
public static String getProperty(String property) {
|
||||
return getProperty(property, null);
|
||||
public static String getProperty(ScopeModel scopeModel, String property) {
|
||||
return getProperty(scopeModel, property, null);
|
||||
}
|
||||
|
||||
public static String getProperty(String property, String defaultValue) {
|
||||
return StringUtils.trim(getGlobalConfiguration().getString(property, defaultValue));
|
||||
public static String getProperty(ScopeModel scopeModel, String property, String defaultValue) {
|
||||
return StringUtils.trim(getGlobalConfiguration(scopeModel).getString(property, defaultValue));
|
||||
}
|
||||
|
||||
public static int get(String property, int defaultValue) {
|
||||
return getGlobalConfiguration().getInt(property, defaultValue);
|
||||
public static int get(ScopeModel scopeModel, String property, int defaultValue) {
|
||||
return getGlobalConfiguration(scopeModel).getInt(property, defaultValue);
|
||||
}
|
||||
|
||||
public static Map<String, String> parseProperties(String content) throws IOException {
|
||||
|
|
@ -275,4 +282,70 @@ public class ConfigurationUtils {
|
|||
return ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of {@link DynamicConfigurationFactory} by the specified name. If not found, take the default
|
||||
* extension of {@link DynamicConfigurationFactory}
|
||||
*
|
||||
* @param name the name of extension of {@link DynamicConfigurationFactory}
|
||||
* @return non-null
|
||||
* @see 2.7.4
|
||||
*/
|
||||
public static DynamicConfigurationFactory getDynamicConfigurationFactory(ExtensionAccessor extensionAccessor, String name) {
|
||||
ExtensionLoader<DynamicConfigurationFactory> loader = extensionAccessor.getExtensionLoader(DynamicConfigurationFactory.class);
|
||||
return loader.getOrDefaultExtension(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* For compact single instance
|
||||
*/
|
||||
@Deprecated
|
||||
public static Configuration getSystemConfiguration() {
|
||||
return ApplicationModel.defaultModel().getApplicationEnvironment().getSystemConfiguration();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Configuration getEnvConfiguration() {
|
||||
return ApplicationModel.defaultModel().getApplicationEnvironment().getEnvironmentConfiguration();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Configuration getGlobalConfiguration() {
|
||||
return ApplicationModel.defaultModel().getApplicationEnvironment().getConfiguration();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Configuration getDynamicGlobalConfiguration() {
|
||||
return ApplicationModel.defaultModel().getApplicationEnvironment().getDynamicGlobalConfiguration();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getCachedDynamicProperty(String key, String defaultValue) {
|
||||
return getCachedDynamicProperty(ApplicationModel.defaultModel(), key, defaultValue);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getDynamicProperty(String property) {
|
||||
return getDynamicProperty(ApplicationModel.defaultModel(), property);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getDynamicProperty(String property, String defaultValue) {
|
||||
return getDynamicProperty(ApplicationModel.defaultModel(), property, defaultValue);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getProperty(String property) {
|
||||
return getProperty(ApplicationModel.defaultModel(), property);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getProperty(String property, String defaultValue) {
|
||||
return getProperty(ApplicationModel.defaultModel(), property, defaultValue);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int get(String property, int defaultValue) {
|
||||
return get(ApplicationModel.defaultModel(), property, defaultValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.dubbo.common.config;
|
||||
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.util.Properties;
|
||||
|
|
@ -26,7 +27,7 @@ import java.util.Properties;
|
|||
* The smaller value, the higher priority
|
||||
*
|
||||
*/
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface OrderedPropertiesProvider {
|
||||
/**
|
||||
* order
|
||||
|
|
|
|||
|
|
@ -17,30 +17,15 @@
|
|||
package org.apache.dubbo.common.config.configcenter;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
|
||||
/**
|
||||
* The factory interface to create the instance of {@link DynamicConfiguration}
|
||||
*/
|
||||
@SPI("nop") // 2.7.5 change the default SPI implementation
|
||||
@SPI(value = "nop", scope = ExtensionScope.APPLICATION) // 2.7.5 change the default SPI implementation
|
||||
public interface DynamicConfigurationFactory {
|
||||
|
||||
DynamicConfiguration getDynamicConfiguration(URL url);
|
||||
|
||||
/**
|
||||
* Get an instance of {@link DynamicConfigurationFactory} by the specified name. If not found, take the default
|
||||
* extension of {@link DynamicConfigurationFactory}
|
||||
*
|
||||
* @param name the name of extension of {@link DynamicConfigurationFactory}
|
||||
* @return non-null
|
||||
* @see 2.7.4
|
||||
*/
|
||||
static DynamicConfigurationFactory getDynamicConfigurationFactory(String name) {
|
||||
Class<DynamicConfigurationFactory> factoryClass = DynamicConfigurationFactory.class;
|
||||
ExtensionLoader<DynamicConfigurationFactory> loader = getExtensionLoader(factoryClass);
|
||||
return loader.getOrDefaultExtension(name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,6 +464,10 @@ public interface CommonConstants {
|
|||
|
||||
String SERVICE_NAME_MAPPING_KEY = "service-name-mapping";
|
||||
|
||||
String SCOPE_MODEL = "scopeModel";
|
||||
|
||||
String SERVICE_MODEL = "serviceModel";
|
||||
|
||||
/**
|
||||
* The property name for {@link NetworkInterface#getDisplayName() the name of network interface} that
|
||||
* the Dubbo application will be ignored
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.context;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface FrameworkExt extends Lifecycle {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.dubbo.common.convert;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
|
||||
|
|
@ -31,7 +32,7 @@ import static org.apache.dubbo.common.utils.TypeUtils.findActualTypeArgument;
|
|||
* @param <T> The target type
|
||||
* @since 2.7.6
|
||||
*/
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
@FunctionalInterface
|
||||
public interface Converter<S, T> extends Prioritized {
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.dubbo.common.convert.multiple;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ import static org.apache.dubbo.common.utils.TypeUtils.findActualTypeArgument;
|
|||
* @param <S> The source type
|
||||
* @since 2.7.6
|
||||
*/
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface MultiValueConverter<S> extends Prioritized {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.extension;
|
||||
|
||||
/**
|
||||
* Uniform accessor for extension
|
||||
*/
|
||||
public interface ExtensionAccessor {
|
||||
|
||||
ExtensionDirector getExtensionDirector();
|
||||
|
||||
default <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
|
||||
return this.getExtensionDirector().getExtensionLoader(type);
|
||||
}
|
||||
|
||||
default <T> T getExtension(Class<T> type, String name) {
|
||||
ExtensionLoader<T> extensionLoader = getExtensionLoader(type);
|
||||
return extensionLoader != null ? extensionLoader.getExtension(name) : null;
|
||||
}
|
||||
|
||||
default <T> T getAdaptiveExtension(Class<T> type) {
|
||||
ExtensionLoader<T> extensionLoader = getExtensionLoader(type);
|
||||
return extensionLoader != null ? extensionLoader.getAdaptiveExtension() : null;
|
||||
}
|
||||
|
||||
default <T> T getDefaultExtension(Class<T> type) {
|
||||
ExtensionLoader<T> extensionLoader = getExtensionLoader(type);
|
||||
return extensionLoader != null ? extensionLoader.getDefaultExtension() : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.extension;
|
||||
|
||||
/**
|
||||
* SPI extension can implement this aware interface to obtain appropriate {@link ExtensionAccessor} instance.
|
||||
*/
|
||||
public interface ExtensionAccessorAware {
|
||||
|
||||
void setExtensionAccessor(ExtensionAccessor extensionAccessor);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* 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.extension;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* ExtensionDirector is a scoped extension loader manager.
|
||||
*
|
||||
* <p></p>
|
||||
* <p>ExtensionDirector supports multiple levels, and the child can inherit the parent's extension instances. </p>
|
||||
* <p>The way to find and create an extension instance is similar to Java classloader.</p>
|
||||
*/
|
||||
public class ExtensionDirector implements ExtensionAccessor {
|
||||
|
||||
private final ConcurrentMap<Class<?>, ExtensionLoader<?>> extensionLoadersMap = new ConcurrentHashMap<>(64);
|
||||
private ExtensionDirector parent;
|
||||
private final ExtensionScope scope;
|
||||
private List<ExtensionPostProcessor> extensionPostProcessors = new ArrayList<>();
|
||||
|
||||
public ExtensionDirector(ExtensionDirector parent, ExtensionScope scope) {
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public void addExtensionPostProcessor(ExtensionPostProcessor processor) {
|
||||
if (!this.extensionPostProcessors.contains(processor)) {
|
||||
this.extensionPostProcessors.add(processor);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ExtensionPostProcessor> getExtensionPostProcessors() {
|
||||
return extensionPostProcessors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtensionDirector getExtensionDirector() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Extension type == null");
|
||||
}
|
||||
if (!type.isInterface()) {
|
||||
throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
|
||||
}
|
||||
if (!withExtensionAnnotation(type)) {
|
||||
throw new IllegalArgumentException("Extension type (" + type +
|
||||
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
|
||||
}
|
||||
|
||||
// 1. find in local cache
|
||||
ExtensionLoader<T> loader = (ExtensionLoader<T>) extensionLoadersMap.get(type);
|
||||
|
||||
final SPI annotation = type.getAnnotation(SPI.class);
|
||||
ExtensionScope scope = annotation.scope();
|
||||
|
||||
if (loader == null && scope == ExtensionScope.SELF) {
|
||||
// create an instance in self scope
|
||||
loader = createExtensionLoader0(type);
|
||||
}
|
||||
|
||||
// 2. find in parent
|
||||
if (loader == null) {
|
||||
if (this.parent != null) {
|
||||
loader = this.parent.getExtensionLoader(type);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. create it
|
||||
if (loader == null) {
|
||||
loader = createExtensionLoader(type);
|
||||
}
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
private <T> ExtensionLoader<T> createExtensionLoader(Class<T> type) {
|
||||
ExtensionLoader<T> loader = null;
|
||||
if (isScopeMatched(type)) {
|
||||
// if scope is matched, just create it
|
||||
loader = createExtensionLoader0(type);
|
||||
} else {
|
||||
// if scope is not matched, ignore it
|
||||
}
|
||||
return loader;
|
||||
}
|
||||
|
||||
private <T> ExtensionLoader<T> createExtensionLoader0(Class<T> type) {
|
||||
ExtensionLoader<T> loader;
|
||||
extensionLoadersMap.putIfAbsent(type, new ExtensionLoader<T>(type, this));
|
||||
loader = (ExtensionLoader<T>) extensionLoadersMap.get(type);
|
||||
return loader;
|
||||
}
|
||||
|
||||
private boolean isScopeMatched(Class<?> type) {
|
||||
final SPI defaultAnnotation = type.getAnnotation(SPI.class);
|
||||
return defaultAnnotation.scope().equals(scope);
|
||||
}
|
||||
|
||||
private static boolean withExtensionAnnotation(Class<?> type) {
|
||||
return type.isAnnotationPresent(SPI.class);
|
||||
}
|
||||
|
||||
public ExtensionDirector getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,9 +18,16 @@ package org.apache.dubbo.common.extension;
|
|||
|
||||
/**
|
||||
* ExtensionFactory
|
||||
* @deprecated use {@link ExtensionInjector} instead
|
||||
*/
|
||||
@SPI
|
||||
public interface ExtensionFactory {
|
||||
@Deprecated
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface ExtensionFactory extends ExtensionInjector {
|
||||
|
||||
@Override
|
||||
default <T> T getInstance(Class<T> type, String name) {
|
||||
return getExtension(type, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extension.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.extension;
|
||||
|
||||
/**
|
||||
* An injector to provide resources for SPI extension.
|
||||
*/
|
||||
@SPI(scope = ExtensionScope.SELF)
|
||||
public interface ExtensionInjector extends ExtensionAccessorAware {
|
||||
|
||||
/**
|
||||
* Get instance of specify type and name.
|
||||
*
|
||||
* @param type object type.
|
||||
* @param name object name.
|
||||
* @return object instance.
|
||||
*/
|
||||
<T> T getInstance(Class<T> type, String name);
|
||||
|
||||
@Override
|
||||
default void setExtensionAccessor(ExtensionAccessor extensionAccessor) {
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,8 @@
|
|||
package org.apache.dubbo.common.extension;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.config.Environment;
|
||||
import org.apache.dubbo.common.context.FrameworkExt;
|
||||
import org.apache.dubbo.common.context.Lifecycle;
|
||||
import org.apache.dubbo.common.extension.support.ActivateComparator;
|
||||
import org.apache.dubbo.common.extension.support.WrapperComparator;
|
||||
|
|
@ -32,6 +34,8 @@ import org.apache.dubbo.common.utils.Holder;
|
|||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
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 java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
|
@ -90,13 +94,11 @@ public class ExtensionLoader<T> {
|
|||
|
||||
private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
|
||||
|
||||
private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>(64);
|
||||
|
||||
private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>(64);
|
||||
private final ConcurrentMap<Class<?>, Object> extensionInstances = new ConcurrentHashMap<>(64);
|
||||
|
||||
private final Class<?> type;
|
||||
|
||||
private final ExtensionFactory objectFactory;
|
||||
private final ExtensionInjector injector;
|
||||
|
||||
private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();
|
||||
|
||||
|
|
@ -121,6 +123,9 @@ public class ExtensionLoader<T> {
|
|||
* Record all unacceptable exceptions when using SPI
|
||||
*/
|
||||
private Set<String> unacceptableExceptions = new ConcurrentHashSet<>();
|
||||
private ExtensionDirector extensionDirector;
|
||||
private List<ExtensionPostProcessor> extensionPostProcessors;
|
||||
private Environment environment;
|
||||
|
||||
public static void setLoadingStrategies(LoadingStrategy... strategies) {
|
||||
if (ArrayUtils.isNotEmpty(strategies)) {
|
||||
|
|
@ -152,52 +157,42 @@ public class ExtensionLoader<T> {
|
|||
return asList(strategies);
|
||||
}
|
||||
|
||||
private ExtensionLoader(Class<?> type) {
|
||||
ExtensionLoader(Class<?> type, ExtensionDirector extensionDirector) {
|
||||
this.extensionDirector = extensionDirector;
|
||||
this.extensionPostProcessors = extensionDirector.getExtensionPostProcessors();
|
||||
this.type = type;
|
||||
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
|
||||
this.injector = (type == ExtensionInjector.class ? null : extensionDirector.getExtensionLoader(ExtensionInjector.class)
|
||||
.getAdaptiveExtension());
|
||||
}
|
||||
|
||||
private static <T> boolean withExtensionAnnotation(Class<T> type) {
|
||||
return type.isAnnotationPresent(SPI.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
/**
|
||||
* @see ApplicationModel#getExtensionDirector()
|
||||
* @see FrameworkModel#getExtensionDirector()
|
||||
* @see ModuleModel#getExtensionDirector()
|
||||
* @see ExtensionDirector#getExtensionLoader(java.lang.Class)
|
||||
* @deprecated get extension loader from extension director of some module.
|
||||
*/
|
||||
@Deprecated
|
||||
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Extension type == null");
|
||||
}
|
||||
if (!type.isInterface()) {
|
||||
throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
|
||||
}
|
||||
if (!withExtensionAnnotation(type)) {
|
||||
throw new IllegalArgumentException("Extension type (" + type +
|
||||
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
|
||||
}
|
||||
|
||||
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
|
||||
if (loader == null) {
|
||||
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
|
||||
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
|
||||
}
|
||||
return loader;
|
||||
return ApplicationModel.defaultModel().getExtensionLoader(type);
|
||||
}
|
||||
|
||||
// For testing purposes only
|
||||
public static void resetExtensionLoader(Class type) {
|
||||
ExtensionLoader loader = EXTENSION_LOADERS.get(type);
|
||||
if (loader != null) {
|
||||
// Remove all instances associated with this loader as well
|
||||
Map<String, Class<?>> classes = loader.getExtensionClasses();
|
||||
for (Map.Entry<String, Class<?>> entry : classes.entrySet()) {
|
||||
EXTENSION_INSTANCES.remove(entry.getValue());
|
||||
}
|
||||
classes.clear();
|
||||
EXTENSION_LOADERS.remove(type);
|
||||
}
|
||||
// ExtensionLoader loader = EXTENSION_LOADERS.get(type);
|
||||
// if (loader != null) {
|
||||
// // Remove all instances associated with this loader as well
|
||||
// Map<String, Class<?>> classes = loader.getExtensionClasses();
|
||||
// for (Map.Entry<String, Class<?>> entry : classes.entrySet()) {
|
||||
// EXTENSION_INSTANCES.remove(entry.getValue());
|
||||
// }
|
||||
// classes.clear();
|
||||
// EXTENSION_LOADERS.remove(type);
|
||||
// }
|
||||
}
|
||||
|
||||
public static void destroyAll() {
|
||||
EXTENSION_INSTANCES.forEach((_type, instance) -> {
|
||||
public void destroy() {
|
||||
extensionInstances.forEach((_type, instance) -> {
|
||||
if (instance instanceof Lifecycle) {
|
||||
Lifecycle lifecycle = (Lifecycle) instance;
|
||||
try {
|
||||
|
|
@ -207,13 +202,9 @@ public class ExtensionLoader<T> {
|
|||
}
|
||||
}
|
||||
});
|
||||
extensionInstances.clear();
|
||||
|
||||
// TODO Improve extension loader, clear static refer extension instance.
|
||||
// Some extension instances may be referenced by static fields, if clear EXTENSION_INSTANCES may cause inconsistent.
|
||||
// e.g. org.apache.dubbo.registry.client.metadata.MetadataUtils.localMetadataService
|
||||
// EXTENSION_INSTANCES.clear();
|
||||
|
||||
EXTENSION_LOADERS.clear();
|
||||
// TODO destroy extension loader, release resources.
|
||||
}
|
||||
|
||||
private static ClassLoader findClassLoader() {
|
||||
|
|
@ -695,16 +686,16 @@ public class ExtensionLoader<T> {
|
|||
throw findException(name);
|
||||
}
|
||||
try {
|
||||
T instance = (T) EXTENSION_INSTANCES.get(clazz);
|
||||
T instance = (T) extensionInstances.get(clazz);
|
||||
if (instance == null) {
|
||||
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.getDeclaredConstructor().newInstance());
|
||||
instance = (T) EXTENSION_INSTANCES.get(clazz);
|
||||
extensionInstances.putIfAbsent(clazz, clazz.getDeclaredConstructor().newInstance());
|
||||
instance = (T) extensionInstances.get(clazz);
|
||||
}
|
||||
instance = postProcessBeforeInitialization(instance, name);
|
||||
injectExtension(instance);
|
||||
|
||||
instance = postProcessAfterInitialization(instance, name);
|
||||
|
||||
if (wrap) {
|
||||
|
||||
List<Class<?>> wrapperClassesList = new ArrayList<>();
|
||||
if (cachedWrapperClasses != null) {
|
||||
wrapperClassesList.addAll(cachedWrapperClasses);
|
||||
|
|
@ -718,6 +709,7 @@ public class ExtensionLoader<T> {
|
|||
if (wrapper == null
|
||||
|| (ArrayUtils.contains(wrapper.matches(), name) && !ArrayUtils.contains(wrapper.mismatches(), name))) {
|
||||
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
|
||||
instance = postProcessAfterInitialization(instance, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -732,13 +724,34 @@ public class ExtensionLoader<T> {
|
|||
}
|
||||
}
|
||||
|
||||
private T postProcessBeforeInitialization(T instance, String name) throws Exception {
|
||||
if (extensionPostProcessors != null) {
|
||||
for (ExtensionPostProcessor processor : extensionPostProcessors) {
|
||||
instance = (T) processor.postProcessBeforeInitialization(instance, name);
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private T postProcessAfterInitialization(T instance, String name) throws Exception {
|
||||
if (instance instanceof ExtensionAccessorAware) {
|
||||
((ExtensionAccessorAware) instance).setExtensionAccessor(extensionDirector);
|
||||
}
|
||||
if (extensionPostProcessors != null) {
|
||||
for (ExtensionPostProcessor processor : extensionPostProcessors) {
|
||||
instance = (T) processor.postProcessAfterInitialization(instance, name);
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private boolean containsExtension(String name) {
|
||||
return getExtensionClasses().containsKey(name);
|
||||
}
|
||||
|
||||
private T injectExtension(T instance) {
|
||||
|
||||
if (objectFactory == null) {
|
||||
if (injector == null) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
|
@ -760,7 +773,7 @@ public class ExtensionLoader<T> {
|
|||
|
||||
try {
|
||||
String property = getSetterProperty(method);
|
||||
Object object = objectFactory.getExtension(pt, property);
|
||||
Object object = injector.getInstance(pt, property);
|
||||
if (object != null) {
|
||||
method.invoke(instance, object);
|
||||
}
|
||||
|
|
@ -840,13 +853,25 @@ public class ExtensionLoader<T> {
|
|||
Map<String, Class<?>> extensionClasses = new HashMap<>();
|
||||
|
||||
for (LoadingStrategy strategy : strategies) {
|
||||
loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
|
||||
loadDirectory(extensionClasses, strategy.directory(), type.getName().replace("org.apache", "com.alibaba"), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
|
||||
loadDirectory(extensionClasses, strategy, type.getName());
|
||||
|
||||
// compatible with old ExtensionFactory
|
||||
if (this.type == ExtensionInjector.class) {
|
||||
loadDirectory(extensionClasses, strategy, ExtensionFactory.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return extensionClasses;
|
||||
}
|
||||
|
||||
private void loadDirectory(Map<String, Class<?>> extensionClasses, LoadingStrategy strategy, String type) {
|
||||
loadDirectory(extensionClasses, strategy.directory(), type, strategy.preferExtensionClassLoader(),
|
||||
strategy.overridden(), strategy.excludedPackages());
|
||||
String oldType = type.replace("org.apache", "com.alibaba");
|
||||
loadDirectory(extensionClasses, strategy.directory(), oldType, strategy.preferExtensionClassLoader(),
|
||||
strategy.overridden(), strategy.excludedPackages());
|
||||
}
|
||||
|
||||
/**
|
||||
* extract and cache default extension name if exists
|
||||
*/
|
||||
|
|
@ -934,7 +959,8 @@ public class ExtensionLoader<T> {
|
|||
loadClass(extensionClasses, resourceURL, Class.forName(clazz, true, classLoader), name, overridden);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
IllegalStateException e = new IllegalStateException("Failed to load extension class (interface: " + type + ", class line: " + line + ") in " + resourceURL + ", cause: " + t.getMessage(), t);
|
||||
IllegalStateException e = new IllegalStateException("Failed to load extension class (interface: " + type +
|
||||
", class line: " + line + ") in " + resourceURL + ", cause: " + t.getMessage(), t);
|
||||
exceptions.put(line, e);
|
||||
}
|
||||
}
|
||||
|
|
@ -1087,7 +1113,12 @@ public class ExtensionLoader<T> {
|
|||
@SuppressWarnings("unchecked")
|
||||
private T createAdaptiveExtension() {
|
||||
try {
|
||||
return injectExtension((T) getAdaptiveExtensionClass().newInstance());
|
||||
T instance = (T) getAdaptiveExtensionClass().newInstance();
|
||||
instance = postProcessBeforeInitialization(instance, null);
|
||||
instance = injectExtension(instance);
|
||||
instance = postProcessAfterInitialization(instance, null);
|
||||
initExtension(instance);
|
||||
return instance;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Can't create adaptive extension " + type + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
|
|
@ -1104,17 +1135,25 @@ public class ExtensionLoader<T> {
|
|||
private Class<?> createAdaptiveExtensionClass() {
|
||||
ClassLoader classLoader = findClassLoader();
|
||||
try {
|
||||
if (ApplicationModel.getEnvironment().getConfiguration().getBoolean(NATIVE, false)) {
|
||||
if (getEnvironment().getConfiguration().getBoolean(NATIVE, false)) {
|
||||
return classLoader.loadClass(type.getName() + "$Adaptive");
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
|
||||
}
|
||||
String code = new AdaptiveClassCodeGenerator(type, cachedDefaultName).generate();
|
||||
org.apache.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
|
||||
org.apache.dubbo.common.compiler.Compiler compiler = extensionDirector.getExtensionLoader(
|
||||
org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
|
||||
return compiler.compile(code, classLoader);
|
||||
}
|
||||
|
||||
private Environment getEnvironment() {
|
||||
if (environment == null) {
|
||||
environment = (Environment) extensionDirector.getExtensionLoader(FrameworkExt.class).getExtension(Environment.NAME);
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getName() + "[" + type.getName() + "]";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.extension;
|
||||
|
||||
/**
|
||||
* A Post-processor called before or after extension initialization.
|
||||
*/
|
||||
public interface ExtensionPostProcessor {
|
||||
|
||||
default Object postProcessBeforeInitialization(Object instance, String name) throws Exception {
|
||||
return instance;
|
||||
}
|
||||
|
||||
default Object postProcessAfterInitialization(Object instance, String name) throws Exception {
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.extension;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
/**
|
||||
* Extension SPI Scope
|
||||
* @see SPI
|
||||
* @see ExtensionDirector
|
||||
*/
|
||||
public enum ExtensionScope {
|
||||
|
||||
/**
|
||||
* The extension instance is used within framework, shared with all applications and modules.
|
||||
*
|
||||
* <p>Framework scope SPI extension can only obtain {@link FrameworkModel},
|
||||
* cannot get the {@link ApplicationModel} and {@link ModuleModel}.</p>
|
||||
*
|
||||
* <p></p>
|
||||
* Consideration:
|
||||
* <ol>
|
||||
* <li>Some SPI need share data between applications inside framework</li>
|
||||
* <li>Stateless SPI is safe shared inside framework</li>
|
||||
* </ol>
|
||||
*/
|
||||
FRAMEWORK,
|
||||
|
||||
/**
|
||||
* The extension instance is used within one application, shared with all modules of the application,
|
||||
* and different applications create different extension instances.
|
||||
*
|
||||
* <p>Application scope SPI extension can obtain {@link FrameworkModel} and {@link ApplicationModel},
|
||||
* cannot get the {@link ModuleModel}.</p>
|
||||
*
|
||||
* <p></p>
|
||||
* Consideration:
|
||||
* <ol>
|
||||
* <li>Isolate extension data in different applications inside framework</li>
|
||||
* <li>Share extension data between all modules inside application</li>
|
||||
* </ol>
|
||||
*/
|
||||
APPLICATION,
|
||||
|
||||
/**
|
||||
* The extension instance is used within one module, and different modules create different extension instances.
|
||||
*
|
||||
* <p>Module scope SPI extension can obtain {@link FrameworkModel}, {@link ApplicationModel} and {@link ModuleModel}.</p>
|
||||
*
|
||||
* <p></p>
|
||||
* Consideration:
|
||||
* <ol>
|
||||
* <li>Isolate extension data in different modules inside application</li>
|
||||
* </ol>
|
||||
*/
|
||||
MODULE,
|
||||
|
||||
/**
|
||||
* self-sufficient, creates an instance for per scope, for special SPI extension, like {@link ExtensionInjector}
|
||||
*/
|
||||
SELF
|
||||
}
|
||||
|
|
@ -61,4 +61,8 @@ public @interface SPI {
|
|||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* scope of SPI, default value is application scope.
|
||||
*/
|
||||
ExtensionScope scope() default ExtensionScope.APPLICATION;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.extension.factory;
|
||||
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AdaptiveExtensionFactory
|
||||
*/
|
||||
@Adaptive
|
||||
public class AdaptiveExtensionFactory implements ExtensionFactory {
|
||||
|
||||
private final List<ExtensionFactory> factories;
|
||||
|
||||
public AdaptiveExtensionFactory() {
|
||||
ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
|
||||
List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
|
||||
for (String name : loader.getSupportedExtensions()) {
|
||||
list.add(loader.getExtension(name));
|
||||
}
|
||||
factories = Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getExtension(Class<T> type, String name) {
|
||||
for (ExtensionFactory factory : factories) {
|
||||
T extension = factory.getExtension(type, name);
|
||||
if (extension != null) {
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.extension.inject;
|
||||
|
||||
import org.apache.dubbo.common.context.Lifecycle;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessor;
|
||||
import org.apache.dubbo.common.extension.ExtensionInjector;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AdaptiveExtensionInjector
|
||||
*/
|
||||
@Adaptive
|
||||
public class AdaptiveExtensionInjector implements ExtensionInjector, Lifecycle {
|
||||
|
||||
private List<ExtensionInjector> injectors = Collections.emptyList();
|
||||
|
||||
private ExtensionAccessor extensionAccessor;
|
||||
|
||||
public AdaptiveExtensionInjector() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtensionAccessor(ExtensionAccessor extensionAccessor) {
|
||||
this.extensionAccessor = extensionAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() throws IllegalStateException {
|
||||
ExtensionLoader<ExtensionInjector> loader = extensionAccessor.getExtensionLoader(ExtensionInjector.class);
|
||||
List<ExtensionInjector> list = new ArrayList<ExtensionInjector>();
|
||||
for (String name : loader.getSupportedExtensions()) {
|
||||
list.add(loader.getExtension(name));
|
||||
}
|
||||
injectors = Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInstance(Class<T> type, String name) {
|
||||
for (ExtensionInjector injector : injectors) {
|
||||
T extension = injector.getInstance(type, name);
|
||||
if (extension != null) {
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws IllegalStateException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws IllegalStateException {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -14,21 +14,32 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.extension.factory;
|
||||
package org.apache.dubbo.common.extension.inject;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessor;
|
||||
import org.apache.dubbo.common.extension.ExtensionInjector;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
/**
|
||||
* SpiExtensionFactory
|
||||
* SpiExtensionInjector
|
||||
*/
|
||||
public class SpiExtensionFactory implements ExtensionFactory {
|
||||
public class SpiExtensionInjector implements ExtensionInjector {
|
||||
|
||||
private ExtensionAccessor extensionAccessor;
|
||||
|
||||
@Override
|
||||
public <T> T getExtension(Class<T> type, String name) {
|
||||
public void setExtensionAccessor(ExtensionAccessor extensionAccessor) {
|
||||
this.extensionAccessor = extensionAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInstance(Class<T> type, String name) {
|
||||
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
|
||||
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
|
||||
ExtensionLoader<T> loader = extensionAccessor.getExtensionLoader(type);
|
||||
if (loader == null) {
|
||||
return null;
|
||||
}
|
||||
if (!loader.getSupportedExtensions().isEmpty()) {
|
||||
return loader.getAdaptiveExtension();
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.infra;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.util.Map;
|
||||
|
|
@ -26,7 +27,7 @@ import java.util.Map;
|
|||
* 2. get configurations from third-party systems which maybe useful for a specific component.
|
||||
*/
|
||||
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface InfraAdapter {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import org.apache.dubbo.common.config.ConfigurationUtils;
|
|||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.infra.InfraAdapter;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -31,7 +33,14 @@ import static org.apache.dubbo.common.constants.CommonConstants.EQUAL_SPLIT_PATT
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.SEMICOLON_SPLIT_PATTERN;
|
||||
|
||||
@Activate
|
||||
public class EnvironmentAdapter implements InfraAdapter {
|
||||
public class EnvironmentAdapter implements InfraAdapter, ScopeModelAware {
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. OS Environment: DUBBO_LABELS=tag=pre;key=value
|
||||
|
|
@ -41,7 +50,7 @@ public class EnvironmentAdapter implements InfraAdapter {
|
|||
public Map<String, String> getExtraAttributes(Map<String, String> params) {
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
|
||||
String rawLabels = ConfigurationUtils.getProperty(DUBBO_LABELS);
|
||||
String rawLabels = ConfigurationUtils.getProperty(applicationModel, DUBBO_LABELS);
|
||||
if (StringUtils.isNotEmpty(rawLabels)) {
|
||||
String[] labelPairs = SEMICOLON_SPLIT_PATTERN.split(rawLabels);
|
||||
for (String pair : labelPairs) {
|
||||
|
|
@ -52,11 +61,11 @@ public class EnvironmentAdapter implements InfraAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
String rawKeys = ConfigurationUtils.getProperty(DUBBO_ENV_KEYS);
|
||||
String rawKeys = ConfigurationUtils.getProperty(applicationModel, DUBBO_ENV_KEYS);
|
||||
if (StringUtils.isNotEmpty(rawKeys)) {
|
||||
String[] keys = COMMA_SPLIT_PATTERN.split(rawKeys);
|
||||
for (String key : keys) {
|
||||
String value = ConfigurationUtils.getProperty(key);
|
||||
String value = ConfigurationUtils.getProperty(applicationModel, key);
|
||||
if (value != null) {
|
||||
parameters.put(key, value);
|
||||
}
|
||||
|
|
@ -67,6 +76,6 @@ public class EnvironmentAdapter implements InfraAdapter {
|
|||
|
||||
@Override
|
||||
public String getAttribute(String key) {
|
||||
return ConfigurationUtils.getProperty(key);
|
||||
return ConfigurationUtils.getProperty(applicationModel, key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.lang;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
/**
|
||||
|
|
@ -23,7 +24,7 @@ import org.apache.dubbo.common.extension.SPI;
|
|||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface ShutdownHookCallback extends Prioritized {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.logger;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -23,7 +24,7 @@ import java.io.File;
|
|||
/**
|
||||
* Logger provider
|
||||
*/
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface LoggerAdapter {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -16,12 +16,13 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.status;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
/**
|
||||
* StatusChecker
|
||||
*/
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface StatusChecker {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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.status.reporter;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class FrameworkStatusReportService implements ScopeModelAware {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FrameworkStatusReporter.class);
|
||||
public static final String REGISTRATION_STATUS = "registration";
|
||||
public static final String ADDRESS_CONSUMPTION_STATUS = "consumption";
|
||||
public static final String MIGRATION_STEP_STATUS = "migrationStepStatus";
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
private Set<FrameworkStatusReporter> reporters;
|
||||
private Gson gson = new Gson();
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
reporters = applicationModel.getExtensionLoader(FrameworkStatusReporter.class).getSupportedExtensionInstances();
|
||||
}
|
||||
|
||||
public void reportRegistrationStatus(Object obj) {
|
||||
doReport(REGISTRATION_STATUS, obj);
|
||||
}
|
||||
|
||||
public void reportConsumptionStatus(Object obj) {
|
||||
doReport(ADDRESS_CONSUMPTION_STATUS, obj);
|
||||
}
|
||||
|
||||
public void reportMigrationStepStatus(Object obj) {
|
||||
doReport(MIGRATION_STEP_STATUS, obj);
|
||||
}
|
||||
|
||||
public boolean hasReporter() {
|
||||
return reporters.size() > 0;
|
||||
}
|
||||
|
||||
private void doReport(String type, Object obj) {
|
||||
// TODO, report asynchronously
|
||||
try {
|
||||
if (CollectionUtils.isNotEmpty(reporters)) {
|
||||
FrameworkStatusReporter reporter = reporters.iterator().next();
|
||||
reporter.report(type, obj);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.info("Report " + type + " status failed because of " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String createRegistrationReport(String status) {
|
||||
return "{\"application\":\"" +
|
||||
applicationModel.getApplicationName() +
|
||||
"\",\"status\":\"" +
|
||||
status +
|
||||
"\"}";
|
||||
}
|
||||
|
||||
public String createConsumptionReport(String interfaceName, String version, String group, String status) {
|
||||
HashMap<String, String> migrationStatus = new HashMap<>();
|
||||
migrationStatus.put("type", "consumption");
|
||||
migrationStatus.put("application", applicationModel.getApplicationName());
|
||||
migrationStatus.put("service", interfaceName);
|
||||
migrationStatus.put("version", version);
|
||||
migrationStatus.put("group", group);
|
||||
migrationStatus.put("status", status);
|
||||
return gson.toJson(migrationStatus);
|
||||
}
|
||||
|
||||
public String createMigrationStepReport(String interfaceName, String version, String group, String originStep, String newStep, String success) {
|
||||
HashMap<String, String> migrationStatus = new HashMap<>();
|
||||
migrationStatus.put("type", "migrationStepStatus");
|
||||
migrationStatus.put("application", applicationModel.getApplicationName());
|
||||
migrationStatus.put("service", interfaceName);
|
||||
migrationStatus.put("version", version);
|
||||
migrationStatus.put("group", group);
|
||||
migrationStatus.put("originStep", originStep);
|
||||
migrationStatus.put("newStep", newStep);
|
||||
migrationStatus.put("success", success);
|
||||
return gson.toJson(migrationStatus);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,86 +16,14 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.status.reporter;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
@SPI
|
||||
public interface FrameworkStatusReporter {
|
||||
static final Gson gson = new Gson();
|
||||
Logger logger = LoggerFactory.getLogger(FrameworkStatusReporter.class);
|
||||
String REGISTRATION_STATUS = "registration";
|
||||
String ADDRESS_CONSUMPTION_STATUS = "consumption";
|
||||
String MIGRATION_STEP_STATUS = "migrationStepStatus";
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface FrameworkStatusReporter extends ScopeModelAware {
|
||||
|
||||
void report(String type, Object obj);
|
||||
|
||||
static void reportRegistrationStatus(Object obj) {
|
||||
doReport(REGISTRATION_STATUS, obj);
|
||||
}
|
||||
|
||||
static void reportConsumptionStatus(Object obj) {
|
||||
doReport(ADDRESS_CONSUMPTION_STATUS, obj);
|
||||
}
|
||||
|
||||
static void reportMigrationStepStatus(Object obj) {
|
||||
doReport(MIGRATION_STEP_STATUS, obj);
|
||||
}
|
||||
|
||||
static boolean hasReporter() {
|
||||
return ExtensionLoader.getExtensionLoader(FrameworkStatusReporter.class).getSupportedExtensions().size() > 0;
|
||||
}
|
||||
|
||||
static void doReport(String type, Object obj) {
|
||||
// TODO, report asynchronously
|
||||
try {
|
||||
Set<FrameworkStatusReporter> reporters = ExtensionLoader.getExtensionLoader(FrameworkStatusReporter.class).getSupportedExtensionInstances();
|
||||
if (CollectionUtils.isNotEmpty(reporters)) {
|
||||
FrameworkStatusReporter reporter = reporters.iterator().next();
|
||||
reporter.report(type, obj);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.info("Report " + type + " status failed because of " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
static String createRegistrationReport(String status) {
|
||||
return "{\"application\":\"" +
|
||||
ApplicationModel.getName() +
|
||||
"\",\"status\":\"" +
|
||||
status +
|
||||
"\"}";
|
||||
}
|
||||
|
||||
static String createConsumptionReport(String interfaceName, String version, String group, String status) {
|
||||
HashMap<String, String> migrationStatus = new HashMap<>();
|
||||
migrationStatus.put("type", "consumption");
|
||||
migrationStatus.put("application", ApplicationModel.getName());
|
||||
migrationStatus.put("service", interfaceName);
|
||||
migrationStatus.put("version", version);
|
||||
migrationStatus.put("group", group);
|
||||
migrationStatus.put("status", status);
|
||||
return gson.toJson(migrationStatus);
|
||||
}
|
||||
|
||||
static String createMigrationStepReport(String interfaceName, String version, String group, String originStep, String newStep, String success) {
|
||||
HashMap<String, String> migrationStatus = new HashMap<>();
|
||||
migrationStatus.put("type", "migrationStepStatus");
|
||||
migrationStatus.put("application", ApplicationModel.getName());
|
||||
migrationStatus.put("service", interfaceName);
|
||||
migrationStatus.put("version", version);
|
||||
migrationStatus.put("group", group);
|
||||
migrationStatus.put("originStep", originStep);
|
||||
migrationStatus.put("newStep", newStep);
|
||||
migrationStatus.put("success", success);
|
||||
return gson.toJson(migrationStatus);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@
|
|||
|
||||
package org.apache.dubbo.common.store;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SPI("simple")
|
||||
@SPI(value = "simple", scope = ExtensionScope.APPLICATION)
|
||||
public interface DataStore {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.common.threadpool;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
|
@ -27,7 +28,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
|
|||
/**
|
||||
* ThreadPool
|
||||
*/
|
||||
@SPI("fixed")
|
||||
//TODO which scope for ThreadPool? APPLICATION or FRAMEWORK
|
||||
@SPI(value = "fixed", scope = ExtensionScope.FRAMEWORK)
|
||||
public interface ThreadPool {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
package org.apache.dubbo.common.threadpool.manager;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessor;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessorAware;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.threadlocal.NamedInternalThreadFactory;
|
||||
|
|
@ -27,6 +28,8 @@ import org.apache.dubbo.common.utils.ExecutorUtil;
|
|||
import org.apache.dubbo.common.utils.NamedThreadFactory;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -46,12 +49,11 @@ import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_REFER_TH
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
|
||||
import static org.apache.dubbo.rpc.model.ApplicationModel.getConfigManager;
|
||||
|
||||
/**
|
||||
* Consider implementing {@code Licycle} to enable executors shutdown when the process stops.
|
||||
*/
|
||||
public class DefaultExecutorRepository implements ExecutorRepository {
|
||||
public class DefaultExecutorRepository implements ExecutorRepository, ExtensionAccessorAware, ScopeModelAware {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultExecutorRepository.class);
|
||||
|
||||
private int DEFAULT_SCHEDULER_SIZE = Runtime.getRuntime().availableProcessors();
|
||||
|
|
@ -79,6 +81,9 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
private static Ring<ExecutorService> executorServiceRing = new Ring<ExecutorService>();
|
||||
|
||||
private static final Object LOCK = new Object();
|
||||
private ExtensionAccessor extensionAccessor;
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
|
||||
public DefaultExecutorRepository() {
|
||||
for (int i = 0; i < DEFAULT_SCHEDULER_SIZE; i++) {
|
||||
|
|
@ -228,7 +233,7 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
}
|
||||
|
||||
private Integer getExportThreadNum() {
|
||||
List<Integer> threadNum = getConfigManager().getProviders()
|
||||
List<Integer> threadNum = ApplicationModel.ofNullable(applicationModel).getApplicationConfigManager().getProviders()
|
||||
.stream()
|
||||
.map(ProviderConfig::getExportThreadNum)
|
||||
.filter(k -> k != null && k > 0)
|
||||
|
|
@ -275,7 +280,7 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
}
|
||||
|
||||
private Integer getReferThreadNum() {
|
||||
List<Integer> threadNum = getConfigManager().getConsumers()
|
||||
List<Integer> threadNum = ApplicationModel.ofNullable(applicationModel).getApplicationConfigManager().getConsumers()
|
||||
.stream()
|
||||
.map(ConsumerConfig::getReferThreadNum)
|
||||
.filter(k -> k != null && k > 0)
|
||||
|
|
@ -311,7 +316,7 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
}
|
||||
|
||||
private ExecutorService createExecutor(URL url) {
|
||||
return (ExecutorService) ExtensionLoader.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url);
|
||||
return (ExecutorService) extensionAccessor.getExtensionLoader(ThreadPool.class).getAdaptiveExtension().getExecutor(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -362,4 +367,14 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
// executorService.shutdown();
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtensionAccessor(ExtensionAccessor extensionAccessor) {
|
||||
this.extensionAccessor = extensionAccessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.dubbo.common.threadpool.manager;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
|
@ -25,7 +26,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
@SPI("default")
|
||||
@SPI(value = "default", scope = ExtensionScope.APPLICATION)
|
||||
public interface ExecutorRepository {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.dubbo.common.url.component;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceModel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
|
@ -96,6 +98,16 @@ public class DubboServiceAddressURL extends ServiceAddressURL {
|
|||
this.overrideURL = overrideURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScopeModel getScopeModel() {
|
||||
return consumerURL.getScopeModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceModel getServiceModel() {
|
||||
return consumerURL.getServiceModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
public class ServiceConfigURL extends URL {
|
||||
private final Map<String, Object> attributes;
|
||||
|
||||
private volatile transient String full;
|
||||
private volatile transient String string;
|
||||
|
|
@ -31,12 +30,11 @@ public class ServiceConfigURL extends URL {
|
|||
private volatile transient String parameter;
|
||||
|
||||
public ServiceConfigURL() {
|
||||
this.attributes = null;
|
||||
super();
|
||||
}
|
||||
|
||||
public ServiceConfigURL(URLAddress urlAddress, URLParam urlParam, Map<String, Object> attributes) {
|
||||
super(urlAddress, urlParam);
|
||||
this.attributes = (attributes != null ? attributes : new HashMap<>());
|
||||
super(urlAddress, urlParam, attributes);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -98,22 +96,11 @@ public class ServiceConfigURL extends URL {
|
|||
return (T) new ServiceConfigURL(urlAddress, urlParam, attributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String key) {
|
||||
return attributes.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL addAttributes(Map<String, Object> attributes) {
|
||||
Map<String, Object> newAttributes = new HashMap<>();
|
||||
newAttributes.putAll(this.attributes);
|
||||
newAttributes.putAll(attributes);
|
||||
|
||||
return new ServiceConfigURL(getUrlAddress(), getUrlParam(), newAttributes);
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +108,6 @@ public class ServiceConfigURL extends URL {
|
|||
public ServiceConfigURL putAttribute(String key, Object obj) {
|
||||
Map<String, Object> newAttributes = new HashMap<>(attributes);
|
||||
newAttributes.put(key, obj);
|
||||
|
||||
return new ServiceConfigURL(getUrlAddress(), getUrlParam(), newAttributes);
|
||||
}
|
||||
|
||||
|
|
@ -129,15 +115,9 @@ public class ServiceConfigURL extends URL {
|
|||
public URL removeAttribute(String key) {
|
||||
Map<String, Object> newAttributes = new HashMap<>(attributes);
|
||||
newAttributes.remove(key);
|
||||
|
||||
return new ServiceConfigURL(getUrlAddress(), getUrlParam(), newAttributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAttribute(String key) {
|
||||
return getAttribute(key) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (string != null) {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,12 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.url.component.param;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface DynamicParamSource {
|
||||
|
||||
void init(List<String> keys, List<ParamValue> values);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.common.constants.CommonConstants;
|
|||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.logger.support.FailsafeLogger;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
|
|
@ -237,8 +238,8 @@ public class NetUtils {
|
|||
return host;
|
||||
}
|
||||
|
||||
public static String getIpByConfig() {
|
||||
String configIp = ConfigurationUtils.getProperty(DUBBO_IP_TO_BIND);
|
||||
public static String getIpByConfig(ScopeModel scopeModel) {
|
||||
String configIp = ConfigurationUtils.getProperty(scopeModel, DUBBO_IP_TO_BIND);
|
||||
if (configIp != null) {
|
||||
return configIp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.config.ConfigurationUtils;
|
|||
import org.apache.dubbo.common.config.Environment;
|
||||
import org.apache.dubbo.common.config.InmemoryConfiguration;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
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.ClassUtils;
|
||||
|
|
@ -28,8 +29,11 @@ import org.apache.dubbo.common.utils.CollectionUtils;
|
|||
import org.apache.dubbo.common.utils.MethodUtils;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
|
|
@ -93,6 +97,21 @@ public abstract class AbstractConfig implements Serializable {
|
|||
*/
|
||||
protected Boolean isDefault;
|
||||
|
||||
/**
|
||||
* The scope model of this config instance.
|
||||
* <p>
|
||||
* <b>NOTE:</b> the model maybe changed during config processing,
|
||||
* the extension spi instance needs to be reinitialized after changing the model!
|
||||
*/
|
||||
protected ScopeModel scopeModel;
|
||||
|
||||
public AbstractConfig() {
|
||||
this(ApplicationModel.defaultModel());
|
||||
}
|
||||
|
||||
public AbstractConfig(ScopeModel scopeModel) {
|
||||
this.setScopeModel(scopeModel);
|
||||
}
|
||||
|
||||
public static String getTagName(Class<?> cls) {
|
||||
return tagNameCache.computeIfAbsent(cls, (key) -> {
|
||||
|
|
@ -302,6 +321,46 @@ public abstract class AbstractConfig implements Serializable {
|
|||
return result;
|
||||
}
|
||||
|
||||
public ApplicationModel getApplicationModel() {
|
||||
if (scopeModel instanceof ApplicationModel) {
|
||||
return (ApplicationModel) scopeModel;
|
||||
} else if (scopeModel instanceof ModuleModel) {
|
||||
return ((ModuleModel) scopeModel).getApplicationModel();
|
||||
} else {
|
||||
throw new IllegalStateException("scope model is invalid: " + scopeModel);
|
||||
}
|
||||
}
|
||||
|
||||
public ScopeModel getScopeModel() {
|
||||
return scopeModel;
|
||||
}
|
||||
|
||||
public void setScopeModel(ScopeModel scopeModel) {
|
||||
if (this.scopeModel != scopeModel) {
|
||||
this.scopeModel = scopeModel;
|
||||
// reinitialize spi extension here
|
||||
this.initExtensions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass should override this method to initialize its SPI extensions.
|
||||
* <p>
|
||||
* For example:
|
||||
* <pre>
|
||||
* this.protocol = this.getExtensionLoader(Protocol.class).getAdaptiveExtension();
|
||||
* </pre>
|
||||
*/
|
||||
protected void initExtensions() {
|
||||
}
|
||||
|
||||
protected <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
|
||||
if (scopeModel == null) {
|
||||
throw new IllegalStateException("owner module is not initialized");
|
||||
}
|
||||
return scopeModel.getExtensionLoader(type);
|
||||
}
|
||||
|
||||
@Parameter(excluded = true, attribute = true)
|
||||
public String getId() {
|
||||
return id;
|
||||
|
|
@ -443,7 +502,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
// check and init before do refresh
|
||||
preProcessRefresh();
|
||||
|
||||
Environment environment = ApplicationModel.getEnvironment();
|
||||
Environment environment = getApplicationModel().getApplicationEnvironment();
|
||||
List<Map<String, String>> configurationMaps = environment.getConfigurationMaps();
|
||||
|
||||
// Search props starts with PREFIX in order
|
||||
|
|
@ -729,4 +788,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
return methods;
|
||||
}
|
||||
|
||||
protected ConfigManager getConfigManager() {
|
||||
return getApplicationModel().getApplicationConfigManager();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.bytecode.Wrapper;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.config.Environment;
|
||||
import org.apache.dubbo.common.config.InmemoryConfiguration;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
|
|
@ -27,7 +28,7 @@ import org.apache.dubbo.common.utils.ConfigUtils;
|
|||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceMetadata;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -42,12 +43,12 @@ import java.util.stream.Collectors;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.NATIVE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.NATIVE;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -196,6 +197,34 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
return urls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScopeModel(ScopeModel scopeModel) {
|
||||
super.setScopeModel(scopeModel);
|
||||
// ApplicationModel applicationModel = ScopeModelUtil.getApplicationModel(scopeModel);
|
||||
// if (this.configCenter != null && this.configCenter.getScopeModel() != applicationModel) {
|
||||
// this.configCenter.setScopeModel(applicationModel);
|
||||
// }
|
||||
// if (this.metadataReportConfig != null && this.metadataReportConfig.getScopeModel() != applicationModel) {
|
||||
// this.metadataReportConfig.setScopeModel(applicationModel);
|
||||
// }
|
||||
// if (this.metrics != null && this.metrics.getScopeModel() != applicationModel) {
|
||||
// this.metrics.setScopeModel(applicationModel);
|
||||
// }
|
||||
// if (this.monitor != null && this.monitor.getScopeModel() != applicationModel) {
|
||||
// this.monitor.setScopeModel(applicationModel);
|
||||
// }
|
||||
// if (this.metadataReportConfig != null && this.metadataReportConfig.getScopeModel() != applicationModel) {
|
||||
// this.metadataReportConfig.setScopeModel(applicationModel);
|
||||
// }
|
||||
// if (CollectionUtils.isNotEmpty(this.registries)) {
|
||||
// this.registries.forEach(registryConfig -> {
|
||||
// if (registryConfig.getScopeModel() != applicationModel) {
|
||||
// registryConfig.setScopeModel(applicationModel);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the registry config is exists, and then conversion it to {@link RegistryConfig}
|
||||
*/
|
||||
|
|
@ -225,7 +254,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
* @return
|
||||
*/
|
||||
protected String[] methods(Class<?> interfaceClass) {
|
||||
boolean isNative = ApplicationModel.getEnvironment().getConfiguration().getBoolean(NATIVE, false);
|
||||
boolean isNative = getEnvironment().getConfiguration().getBoolean(NATIVE, false);
|
||||
if (isNative) {
|
||||
return Arrays.stream(interfaceClass.getMethods()).map(Method::getName).toArray(String[]::new);
|
||||
} else {
|
||||
|
|
@ -233,6 +262,10 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
}
|
||||
}
|
||||
|
||||
protected Environment getEnvironment() {
|
||||
return getApplicationModel().getApplicationEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processExtraRefresh(String preferredPrefix, InmemoryConfiguration subPropsConfiguration) {
|
||||
if (StringUtils.hasText(interfaceName)) {
|
||||
|
|
@ -278,13 +311,14 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
List<MethodConfig> methodConfigs = this.getMethods();
|
||||
if (methodConfigs != null && methodConfigs.size() > 0) {
|
||||
// whether ignore invalid method config
|
||||
Object ignoreInvalidMethodConfigVal = ApplicationModel.getEnvironment().getConfiguration()
|
||||
Object ignoreInvalidMethodConfigVal = getEnvironment().getConfiguration()
|
||||
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_INVALID_METHOD_CONFIG, "false");
|
||||
boolean ignoreInvalidMethodConfig = Boolean.parseBoolean(ignoreInvalidMethodConfigVal.toString());
|
||||
|
||||
Class<?> finalInterfaceClass = interfaceClass;
|
||||
List<MethodConfig> validMethodConfigs = methodConfigs.stream().filter(methodConfig -> {
|
||||
methodConfig.setParentPrefix(preferredPrefix);
|
||||
methodConfig.setScopeModel(getScopeModel());
|
||||
methodConfig.refresh();
|
||||
// verify method config
|
||||
return verifyMethodConfig(methodConfig, finalInterfaceClass, ignoreInvalidMethodConfig);
|
||||
|
|
@ -388,7 +422,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
computeValidRegistryIds();
|
||||
if (StringUtils.isEmpty(registryIds)) {
|
||||
if (CollectionUtils.isEmpty(registries)) {
|
||||
List<RegistryConfig> registryConfigs = ApplicationModel.getConfigManager().getDefaultRegistries();
|
||||
List<RegistryConfig> registryConfigs = getConfigManager().getDefaultRegistries();
|
||||
registryConfigs = new ArrayList<>(registryConfigs);
|
||||
setRegistries(registryConfigs);
|
||||
}
|
||||
|
|
@ -397,7 +431,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
List<RegistryConfig> tmpRegistries = new ArrayList<>();
|
||||
Arrays.stream(ids).forEach(id -> {
|
||||
if (tmpRegistries.stream().noneMatch(reg -> reg.getId().equals(id))) {
|
||||
Optional<RegistryConfig> globalRegistry = ApplicationModel.getConfigManager().getRegistry(id);
|
||||
Optional<RegistryConfig> globalRegistry = getConfigManager().getRegistry(id);
|
||||
if (globalRegistry.isPresent()) {
|
||||
tmpRegistries.add(globalRegistry.get());
|
||||
} else {
|
||||
|
|
@ -561,14 +595,14 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (application != null) {
|
||||
return application;
|
||||
}
|
||||
return ApplicationModel.getConfigManager().getApplicationOrElseThrow();
|
||||
return getConfigManager().getApplicationOrElseThrow();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setApplication(ApplicationConfig application) {
|
||||
this.application = application;
|
||||
if (application != null) {
|
||||
ApplicationModel.getConfigManager().setApplication(application);
|
||||
getConfigManager().setApplication(application);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -576,14 +610,14 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (module != null) {
|
||||
return module;
|
||||
}
|
||||
return ApplicationModel.getConfigManager().getModule().orElse(null);
|
||||
return getConfigManager().getModule().orElse(null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setModule(ModuleConfig module) {
|
||||
this.module = module;
|
||||
if (module != null) {
|
||||
ApplicationModel.getConfigManager().setModule(module);
|
||||
getConfigManager().setModule(module);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -637,7 +671,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
return monitor;
|
||||
}
|
||||
// FIXME: instead of return null, we should set default monitor when getMonitor() return null in ConfigManager
|
||||
return ApplicationModel.getConfigManager().getMonitor().orElse(null);
|
||||
return getConfigManager().getMonitor().orElse(null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
|
@ -649,7 +683,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
public void setMonitor(MonitorConfig monitor) {
|
||||
this.monitor = monitor;
|
||||
if (monitor != null) {
|
||||
ApplicationModel.getConfigManager().setMonitor(monitor);
|
||||
getConfigManager().setMonitor(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -666,7 +700,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (configCenter != null) {
|
||||
return configCenter;
|
||||
}
|
||||
Collection<ConfigCenterConfig> configCenterConfigs = ApplicationModel.getConfigManager().getConfigCenters();
|
||||
Collection<ConfigCenterConfig> configCenterConfigs = getConfigManager().getConfigCenters();
|
||||
if (CollectionUtils.isNotEmpty(configCenterConfigs)) {
|
||||
return configCenterConfigs.iterator().next();
|
||||
}
|
||||
|
|
@ -677,7 +711,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
public void setConfigCenter(ConfigCenterConfig configCenter) {
|
||||
this.configCenter = configCenter;
|
||||
if (configCenter != null) {
|
||||
ApplicationModel.getConfigManager().addConfigCenter(configCenter);
|
||||
getConfigManager().addConfigCenter(configCenter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -718,7 +752,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (metadataReportConfig != null) {
|
||||
return metadataReportConfig;
|
||||
}
|
||||
Collection<MetadataReportConfig> metadataReportConfigs = ApplicationModel.getConfigManager().getMetadataConfigs();
|
||||
Collection<MetadataReportConfig> metadataReportConfigs = getConfigManager().getMetadataConfigs();
|
||||
if (CollectionUtils.isNotEmpty(metadataReportConfigs)) {
|
||||
return metadataReportConfigs.iterator().next();
|
||||
}
|
||||
|
|
@ -729,7 +763,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
public void setMetadataReportConfig(MetadataReportConfig metadataReportConfig) {
|
||||
this.metadataReportConfig = metadataReportConfig;
|
||||
if (metadataReportConfig != null) {
|
||||
ApplicationModel.getConfigManager().addMetadataReport(metadataReportConfig);
|
||||
getConfigManager().addMetadataReport(metadataReportConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -738,14 +772,14 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (metrics != null) {
|
||||
return metrics;
|
||||
}
|
||||
return ApplicationModel.getConfigManager().getMetrics().orElse(null);
|
||||
return getConfigManager().getMetrics().orElse(null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setMetrics(MetricsConfig metrics) {
|
||||
this.metrics = metrics;
|
||||
if (metrics != null) {
|
||||
ApplicationModel.getConfigManager().setMetrics(metrics);
|
||||
getConfigManager().setMetrics(metrics);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -767,7 +801,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
}
|
||||
|
||||
public SslConfig getSslConfig() {
|
||||
return ApplicationModel.getConfigManager().getSsl().orElse(null);
|
||||
return getConfigManager().getSsl().orElse(null);
|
||||
}
|
||||
|
||||
protected void initServiceMetadata(AbstractInterfaceConfig interfaceConfig) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -95,6 +98,23 @@ public abstract class AbstractMethodConfig extends AbstractConfig {
|
|||
*/
|
||||
protected Integer forks;
|
||||
|
||||
public AbstractMethodConfig() {
|
||||
super(ApplicationModel.defaultModel().getDefaultModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScopeModel(ScopeModel scopeModel) {
|
||||
if (!(scopeModel instanceof ModuleModel)) {
|
||||
throw new IllegalArgumentException("Invalid scope model, expect to be a ModuleModel but got: " + scopeModel);
|
||||
}
|
||||
super.setScopeModel(scopeModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleModel getScopeModel() {
|
||||
return (ModuleModel) scopeModel;
|
||||
}
|
||||
|
||||
public Integer getForks() {
|
||||
return forks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.infra.InfraAdapter;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -34,17 +33,17 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUMP_DIRECTORY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.READINESS_PROBE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.READINESS_PROBE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.STARTUP_PROBE;
|
||||
import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
|
||||
import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
|
||||
|
|
@ -557,7 +556,7 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
parameters = new HashMap<>();
|
||||
}
|
||||
|
||||
Set<InfraAdapter> adapters = ExtensionLoader.getExtensionLoader(InfraAdapter.class).getSupportedExtensionInstances();
|
||||
Set<InfraAdapter> adapters = this.getExtensionLoader(InfraAdapter.class).getSupportedExtensionInstances();
|
||||
if (CollectionUtils.isNotEmpty(adapters)) {
|
||||
Map<String, String> inputParameters = new HashMap<>();
|
||||
inputParameters.put(APPLICATION_KEY, getName());
|
||||
|
|
|
|||
|
|
@ -149,7 +149,9 @@ public class ConfigCenterConfig extends AbstractConfig {
|
|||
if (StringUtils.isEmpty(map.get(PROTOCOL_KEY))) {
|
||||
map.put(PROTOCOL_KEY, ZOOKEEPER_PROTOCOL);
|
||||
}
|
||||
return UrlUtils.parseURL(address, map);
|
||||
URL url = UrlUtils.parseURL(address, map);
|
||||
url.setScopeModel(getScopeModel());
|
||||
return url;
|
||||
}
|
||||
|
||||
public boolean checkOrUpdateInitialized(boolean update) {
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ public class MetadataReportConfig extends AbstractConfig {
|
|||
throw new IllegalArgumentException("The address of metadata report is invalid.");
|
||||
}
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
URL url = URL.valueOf(address);
|
||||
URL url = URL.valueOf(address, getScopeModel());
|
||||
// Issue : https://github.com/apache/dubbo/issues/6491
|
||||
// Append the parameters from address
|
||||
map.putAll(url.getParameters());
|
||||
|
|
@ -135,7 +135,7 @@ public class MetadataReportConfig extends AbstractConfig {
|
|||
// put the protocol of URL as the "metadata"
|
||||
map.put("metadata", url.getProtocol());
|
||||
return new ServiceConfigURL("metadata", url.getUsername(), url.getPassword(), url.getHost(),
|
||||
url.getPort(), url.getPath(), map);
|
||||
url.getPort(), url.getPath(), map).setScopeModel(getScopeModel());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import org.apache.dubbo.common.utils.ReflectUtils;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Method;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.AsyncMethodInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -231,7 +230,7 @@ public class MethodConfig extends AbstractMethodConfig {
|
|||
private void refreshArgument(ArgumentConfig argument, InmemoryConfiguration subPropsConfiguration) {
|
||||
if (argument.getIndex() != null && argument.getIndex() >= 0) {
|
||||
String prefix = argument.getIndex() + ".";
|
||||
Environment environment = ApplicationModel.getEnvironment();
|
||||
Environment environment = getApplicationModel().getApplicationEnvironment();
|
||||
java.lang.reflect.Method[] methods = argument.getClass().getMethods();
|
||||
for (java.lang.reflect.Method method : methods) {
|
||||
if (MethodUtils.isSetter(method)) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import org.apache.dubbo.common.utils.RegexProperties;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceMetadata;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.apache.dubbo.rpc.support.ProtocolUtils;
|
||||
|
|
@ -115,7 +115,7 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
protected void preProcessRefresh() {
|
||||
super.preProcessRefresh();
|
||||
if (consumer == null) {
|
||||
consumer = ApplicationModel.getConfigManager()
|
||||
consumer = getConfigManager()
|
||||
.getDefaultConsumer()
|
||||
.orElseThrow(() -> new IllegalArgumentException("Default consumer is not initialized"));
|
||||
}
|
||||
|
|
@ -200,6 +200,14 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScopeModel(ScopeModel scopeModel) {
|
||||
super.setScopeModel(scopeModel);
|
||||
if (this.consumer != null && this.consumer.getScopeModel() != scopeModel) {
|
||||
this.consumer.setScopeModel(scopeModel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInterface() {
|
||||
return interfaceName;
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ public class RegistryConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
public void setTransporter(String transporter) {
|
||||
/*if(transporter != null && transporter.length() > 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(transporter)){
|
||||
/*if(transporter != null && transporter.length() > 0 && ! this.getExtensionLoader(Transporter.class).hasExtension(transporter)){
|
||||
throw new IllegalStateException("No such transporter type : " + transporter);
|
||||
}*/
|
||||
this.transporter = transporter;
|
||||
|
|
@ -338,7 +338,7 @@ public class RegistryConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
public void setServer(String server) {
|
||||
/*if(server != null && server.length() > 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(server)){
|
||||
/*if(server != null && server.length() > 0 && ! this.getExtensionLoader(Transporter.class).hasExtension(server)){
|
||||
throw new IllegalStateException("No such server type : " + server);
|
||||
}*/
|
||||
this.server = server;
|
||||
|
|
@ -349,7 +349,7 @@ public class RegistryConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
public void setClient(String client) {
|
||||
/*if(client != null && client.length() > 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(client)){
|
||||
/*if(client != null && client.length() > 0 && ! this.getExtensionLoader(Transporter.class).hasExtension(client)){
|
||||
throw new IllegalStateException("No such client type : " + client);
|
||||
}*/
|
||||
this.client = client;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import org.apache.dubbo.common.utils.CollectionUtils;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Service;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceMetadata;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.apache.dubbo.rpc.support.ProtocolUtils;
|
||||
|
|
@ -105,6 +105,14 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
return protocols;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScopeModel(ScopeModel scopeModel) {
|
||||
super.setScopeModel(scopeModel);
|
||||
if (this.provider != null && this.provider.getScopeModel() != scopeModel) {
|
||||
this.provider.setScopeModel(scopeModel);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static List<ProviderConfig> convertProtocolToProvider(List<ProtocolConfig> protocols) {
|
||||
if (CollectionUtils.isEmpty(protocols)) {
|
||||
|
|
@ -199,7 +207,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
super.preProcessRefresh();
|
||||
convertProviderIdToProvider();
|
||||
if (provider == null) {
|
||||
provider = ApplicationModel.getConfigManager()
|
||||
provider = getConfigManager()
|
||||
.getDefaultProvider()
|
||||
.orElseThrow(() -> new IllegalArgumentException("Default provider is not initialized"));
|
||||
}
|
||||
|
|
@ -247,7 +255,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
|
||||
protected void convertProviderIdToProvider() {
|
||||
if (provider == null && StringUtils.hasText(providerIds)) {
|
||||
provider = ApplicationModel.getConfigManager().getProvider(providerIds)
|
||||
provider = getConfigManager().getProvider(providerIds)
|
||||
.orElseThrow(() -> new IllegalStateException("Provider config not found: " + providerIds));
|
||||
}
|
||||
}
|
||||
|
|
@ -255,7 +263,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
protected void convertProtocolIdsToProtocols() {
|
||||
if (StringUtils.isEmpty(protocolIds)) {
|
||||
if (CollectionUtils.isEmpty(protocols)) {
|
||||
List<ProtocolConfig> protocolConfigs = ApplicationModel.getConfigManager().getDefaultProtocols();
|
||||
List<ProtocolConfig> protocolConfigs = getConfigManager().getDefaultProtocols();
|
||||
if (protocolConfigs.isEmpty()) {
|
||||
throw new IllegalStateException("The default protocol has not been initialized.");
|
||||
}
|
||||
|
|
@ -266,7 +274,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
Set<String> idsSet = new LinkedHashSet<>(Arrays.asList(idsArray));
|
||||
List<ProtocolConfig> tmpProtocols = new ArrayList<>();
|
||||
for (String id : idsSet) {
|
||||
Optional<ProtocolConfig> globalProtocol = ApplicationModel.getConfigManager().getProtocol(id);
|
||||
Optional<ProtocolConfig> globalProtocol = getConfigManager().getProtocol(id);
|
||||
if (globalProtocol.isPresent()) {
|
||||
tmpProtocols.add(globalProtocol.get());
|
||||
} else {
|
||||
|
|
@ -336,7 +344,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
}
|
||||
|
||||
public void setProvider(ProviderConfig provider) {
|
||||
ApplicationModel.getConfigManager().addProvider(provider);
|
||||
getConfigManager().addProvider(provider);
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import org.apache.dubbo.config.RegistryConfig;
|
|||
import org.apache.dubbo.config.ServiceConfigBase;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -66,7 +67,7 @@ import static org.apache.dubbo.config.AbstractConfig.getTagName;
|
|||
* A lock-free config manager (through ConcurrentHashMap), for fast read operation.
|
||||
* The Write operation lock with sub configs map of config type, for safely check and add new config.
|
||||
*/
|
||||
public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
||||
public class ConfigManager extends LifecycleAdapter implements FrameworkExt, ScopeModelAware {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
|
||||
|
||||
|
|
@ -105,12 +106,19 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
}
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
|
||||
public ConfigManager() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() throws IllegalStateException {
|
||||
CompositeConfiguration configuration = ApplicationModel.getEnvironment().getConfiguration();
|
||||
CompositeConfiguration configuration = applicationModel.getApplicationEnvironment().getConfiguration();
|
||||
String configModeStr = (String) configuration.getProperty(DUBBO_CONFIG_MODE);
|
||||
try {
|
||||
if (StringUtils.hasText(configModeStr)) {
|
||||
|
|
@ -367,6 +375,9 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
// ServiceConfig correlative methods
|
||||
|
||||
public void addService(ServiceConfigBase<?> serviceConfig) {
|
||||
if (serviceConfig.getScopeModel() == null) {
|
||||
serviceConfig.setScopeModel(applicationModel.getDefaultModule());
|
||||
}
|
||||
addConfig(serviceConfig);
|
||||
}
|
||||
|
||||
|
|
@ -385,6 +396,9 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
// ReferenceConfig correlative methods
|
||||
|
||||
public void addReference(ReferenceConfigBase<?> referenceConfig) {
|
||||
if (referenceConfig.getScopeModel() == null) {
|
||||
referenceConfig.setScopeModel(applicationModel.getDefaultModule());
|
||||
}
|
||||
addConfig(referenceConfig);
|
||||
}
|
||||
|
||||
|
|
@ -458,6 +472,9 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
if (config.getScopeModel() == null) {
|
||||
config.setScopeModel(applicationModel);
|
||||
}
|
||||
addConfig(config, isUniqueConfig(config));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface ApplicationInitListener {
|
||||
/**
|
||||
* init the application
|
||||
|
|
|
|||
|
|
@ -18,14 +18,19 @@ package org.apache.dubbo.rpc.model;
|
|||
|
||||
import org.apache.dubbo.common.config.Environment;
|
||||
import org.apache.dubbo.common.context.FrameworkExt;
|
||||
import org.apache.dubbo.common.extension.ExtensionDirector;
|
||||
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 org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
|
@ -43,18 +48,48 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
* <p>
|
||||
*/
|
||||
|
||||
public class ApplicationModel {
|
||||
public class ApplicationModel extends ScopeModel {
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(ApplicationModel.class);
|
||||
public static final String NAME = "application";
|
||||
private static volatile ApplicationModel defaultInstance;
|
||||
|
||||
private static AtomicBoolean INIT_FLAG = new AtomicBoolean(false);
|
||||
private static Environment environment;
|
||||
private static ConfigManager configManager;
|
||||
private static ServiceRepository serviceRepository;
|
||||
private volatile List<ModuleModel> moduleModels = Collections.synchronizedList(new ArrayList<>());
|
||||
private AtomicBoolean initFlag = new AtomicBoolean(false);
|
||||
private Environment environment;
|
||||
private ConfigManager configManager;
|
||||
private ServiceRepository serviceRepository;
|
||||
|
||||
public static void init() {
|
||||
if (INIT_FLAG.compareAndSet(false, true)) {
|
||||
ExtensionLoader<ApplicationInitListener> extensionLoader = ExtensionLoader.getExtensionLoader(ApplicationInitListener.class);
|
||||
private FrameworkModel frameworkModel;
|
||||
|
||||
public ApplicationModel(FrameworkModel frameworkModel) {
|
||||
super(frameworkModel, new ExtensionDirector(frameworkModel.getExtensionDirector(), ExtensionScope.APPLICATION));
|
||||
this.frameworkModel = frameworkModel;
|
||||
frameworkModel.addApplication(this);
|
||||
postProcessAfterCreated();
|
||||
}
|
||||
|
||||
public static ApplicationModel ofNullable(ApplicationModel applicationModel) {
|
||||
if (applicationModel != null) {
|
||||
return applicationModel;
|
||||
} else {
|
||||
return defaultModel();
|
||||
}
|
||||
}
|
||||
|
||||
public static ApplicationModel defaultModel() {
|
||||
if (defaultInstance == null) {
|
||||
synchronized (ApplicationModel.class) {
|
||||
if (defaultInstance == null) {
|
||||
defaultInstance = new ApplicationModel(FrameworkModel.defaultModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (initFlag.compareAndSet(false, true)) {
|
||||
ExtensionLoader<ApplicationInitListener> extensionLoader = this.getExtensionLoader(ApplicationInitListener.class);
|
||||
Set<String> listenerNames = extensionLoader.getSupportedExtensions();
|
||||
for (String listenerName : listenerNames) {
|
||||
extensionLoader.getExtension(listenerName).init();
|
||||
|
|
@ -62,99 +97,159 @@ public class ApplicationModel {
|
|||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
// TODO destroy application resources
|
||||
}
|
||||
|
||||
public boolean isInit() {
|
||||
return initFlag.get();
|
||||
}
|
||||
|
||||
public FrameworkModel getFrameworkModel() {
|
||||
return frameworkModel;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Collection<ConsumerModel> allConsumerModels() {
|
||||
return getServiceRepository().getReferredServices();
|
||||
return defaultModel().getApplicationServiceRepository().getReferredServices();
|
||||
}
|
||||
|
||||
public Collection<ConsumerModel> allApplicationConsumerModels() {
|
||||
// TODO: aggregate from sub modules
|
||||
return defaultModel().getApplicationServiceRepository().getReferredServices();
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public static Collection<ProviderModel> allProviderModels() {
|
||||
return getServiceRepository().getExportedServices();
|
||||
return defaultModel().getApplicationServiceRepository().getExportedServices();
|
||||
}
|
||||
|
||||
public Collection<ProviderModel> allApplicationProviderModels() {
|
||||
// TODO: aggregate from sub modules
|
||||
return defaultModel().getApplicationServiceRepository().getExportedServices();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ProviderModel getProviderModel(String serviceKey) {
|
||||
return getServiceRepository().lookupExportedService(serviceKey);
|
||||
return defaultModel().getApplicationServiceRepository().lookupExportedService(serviceKey);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ConsumerModel getConsumerModel(String serviceKey) {
|
||||
return getServiceRepository().lookupReferredService(serviceKey);
|
||||
return defaultModel().getApplicationServiceRepository().lookupReferredService(serviceKey);
|
||||
}
|
||||
|
||||
private static ExtensionLoader<FrameworkExt> LOADER = ExtensionLoader.getExtensionLoader(FrameworkExt.class);
|
||||
|
||||
public static void initFrameworkExts() {
|
||||
Set<FrameworkExt> exts = ExtensionLoader.getExtensionLoader(FrameworkExt.class).getSupportedExtensionInstances();
|
||||
public void initFrameworkExts() {
|
||||
Set<FrameworkExt> exts = this.getExtensionLoader(FrameworkExt.class).getSupportedExtensionInstances();
|
||||
for (FrameworkExt ext : exts) {
|
||||
ext.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Environment getEnvironment() {
|
||||
return defaultModel().getApplicationEnvironment();
|
||||
}
|
||||
|
||||
public Environment getApplicationEnvironment() {
|
||||
if (environment == null) {
|
||||
environment = (Environment) LOADER.getExtension(Environment.NAME);
|
||||
environment = (Environment) this.getExtensionLoader(FrameworkExt.class)
|
||||
.getExtension(Environment.NAME);
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ConfigManager getConfigManager() {
|
||||
return defaultModel().getApplicationConfigManager();
|
||||
}
|
||||
|
||||
public ConfigManager getApplicationConfigManager() {
|
||||
if (configManager == null) {
|
||||
configManager = (ConfigManager) LOADER.getExtension(ConfigManager.NAME);
|
||||
configManager = (ConfigManager) this.getExtensionLoader(FrameworkExt.class)
|
||||
.getExtension(ConfigManager.NAME);
|
||||
}
|
||||
return configManager;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ServiceRepository getServiceRepository() {
|
||||
return defaultModel().getApplicationServiceRepository();
|
||||
}
|
||||
|
||||
public ServiceRepository getApplicationServiceRepository() {
|
||||
if (serviceRepository == null) {
|
||||
serviceRepository = (ServiceRepository) LOADER.getExtension(ServiceRepository.NAME);
|
||||
serviceRepository = (ServiceRepository) this.getExtensionLoader(FrameworkExt.class)
|
||||
.getExtension(ServiceRepository.NAME);
|
||||
}
|
||||
return serviceRepository;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ExecutorRepository getExecutorRepository() {
|
||||
return ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
|
||||
return defaultModel().getApplicationExecutorRepository();
|
||||
}
|
||||
|
||||
public static ApplicationConfig getApplicationConfig() {
|
||||
return getConfigManager().getApplicationOrElseThrow();
|
||||
}
|
||||
|
||||
public static String getName() {
|
||||
return getApplicationConfig().getName();
|
||||
public ExecutorRepository getApplicationExecutorRepository() {
|
||||
return this.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
//It will be remove at next version
|
||||
private static String application;
|
||||
public static ApplicationConfig getApplicationConfig() {
|
||||
return defaultModel().getCurrentConfig();
|
||||
}
|
||||
|
||||
public ApplicationConfig getCurrentConfig() {
|
||||
return getApplicationConfigManager().getApplicationOrElseThrow();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getName() {
|
||||
return defaultModel().getCurrentConfig().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated Use {@link #getName()} instead. It will be remove at next version.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getApplication() {
|
||||
return application == null ? getName() : application;
|
||||
return getName();
|
||||
}
|
||||
|
||||
// Currently used by UT, it will be remove at next version.
|
||||
@Deprecated
|
||||
public static void setApplication(String application) {
|
||||
ApplicationModel.application = application;
|
||||
public String getApplicationName() {
|
||||
return getCurrentConfig().getName();
|
||||
}
|
||||
|
||||
public void addModule(ModuleModel model) {
|
||||
if (!this.moduleModels.contains(model)) {
|
||||
this.moduleModels.add(model);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeModule(ModuleModel model) {
|
||||
this.moduleModels.remove(model);
|
||||
}
|
||||
|
||||
public List<ModuleModel> getModuleModels() {
|
||||
return moduleModels;
|
||||
}
|
||||
|
||||
public synchronized ModuleModel getDefaultModule() {
|
||||
if (moduleModels.isEmpty()) {
|
||||
this.addModule(new ModuleModel(this));
|
||||
}
|
||||
return moduleModels.get(0);
|
||||
}
|
||||
|
||||
// only for unit test
|
||||
@Deprecated
|
||||
public static void reset() {
|
||||
if (serviceRepository!=null){
|
||||
serviceRepository.destroy();
|
||||
serviceRepository = null;
|
||||
if (defaultInstance != null) {
|
||||
defaultInstance.destroy();
|
||||
defaultInstance = null;
|
||||
}
|
||||
if (configManager != null) {
|
||||
configManager.destroy();
|
||||
configManager = null;
|
||||
}
|
||||
if (environment != null) {
|
||||
environment.destroy();
|
||||
environment = null;
|
||||
}
|
||||
ExtensionLoader.resetExtensionLoader(FrameworkExt.class);
|
||||
LOADER = ExtensionLoader.getExtensionLoader(FrameworkExt.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApplicationModel";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface BuiltinServiceDetector {
|
||||
|
||||
Class<?> getService();
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.BaseServiceMetadata;
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.config.ReferenceConfigBase;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -34,15 +32,11 @@ import java.util.TreeSet;
|
|||
/**
|
||||
* This model is bound to your reference's configuration, for example, group, version or method level configuration.
|
||||
*/
|
||||
public class ConsumerModel {
|
||||
private String serviceKey;
|
||||
private final ServiceDescriptor serviceModel;
|
||||
private final ReferenceConfigBase<?> referenceConfig;
|
||||
public class ConsumerModel extends ServiceModel {
|
||||
private final Set<String> apps = new TreeSet<>();
|
||||
|
||||
private Object proxyObject;
|
||||
|
||||
private final Map<String, AsyncMethodInfo> methodConfigs;
|
||||
private Map<Method, ConsumerMethodModel> methodModels = new HashMap<>();
|
||||
|
||||
/**
|
||||
* This constructor create an instance of ConsumerModel and passed objects should not be null.
|
||||
|
|
@ -58,57 +52,43 @@ public class ConsumerModel {
|
|||
ReferenceConfigBase<?> referenceConfig,
|
||||
Map<String, AsyncMethodInfo> methodConfigs) {
|
||||
|
||||
super(proxyObject, serviceKey, serviceModel, referenceConfig);
|
||||
Assert.notEmptyString(serviceKey, "Service name can't be null or blank");
|
||||
|
||||
this.serviceKey = serviceKey;
|
||||
this.proxyObject = proxyObject;
|
||||
this.serviceModel = serviceModel;
|
||||
this.referenceConfig = referenceConfig;
|
||||
this.methodConfigs = methodConfigs == null ? new HashMap<>() : methodConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the proxy object used by called while creating instance of ConsumerModel
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Object getProxyObject() {
|
||||
return proxyObject;
|
||||
public ConsumerModel(String serviceKey,
|
||||
Object proxyObject,
|
||||
ServiceDescriptor serviceModel,
|
||||
ReferenceConfigBase<?> referenceConfig,
|
||||
ServiceMetadata metadata,
|
||||
Map<String, AsyncMethodInfo> methodConfigs) {
|
||||
|
||||
super(proxyObject, serviceKey, serviceModel, referenceConfig, metadata);
|
||||
Assert.notEmptyString(serviceKey, "Service name can't be null or blank");
|
||||
|
||||
this.methodConfigs = methodConfigs == null ? new HashMap<>() : methodConfigs;
|
||||
}
|
||||
|
||||
public void setProxyObject(Object proxyObject) {
|
||||
this.proxyObject = proxyObject;
|
||||
}
|
||||
public ConsumerModel(String serviceKey,
|
||||
Object proxyObject,
|
||||
ServiceDescriptor serviceModel,
|
||||
ReferenceConfigBase<?> referenceConfig,
|
||||
ModuleModel moduleModel,
|
||||
ServiceMetadata metadata,
|
||||
Map<String, AsyncMethodInfo> methodConfigs) {
|
||||
|
||||
/**
|
||||
* Return all method models for the current service
|
||||
*
|
||||
* @return method model list
|
||||
*/
|
||||
public Set<MethodDescriptor> getAllMethods() {
|
||||
return serviceModel.getAllMethods();
|
||||
}
|
||||
super(proxyObject, serviceKey, serviceModel, referenceConfig, moduleModel, metadata);
|
||||
Assert.notEmptyString(serviceKey, "Service name can't be null or blank");
|
||||
|
||||
public Class<?> getServiceInterfaceClass() {
|
||||
return serviceModel.getServiceInterfaceClass();
|
||||
}
|
||||
|
||||
public String getServiceKey() {
|
||||
return serviceKey;
|
||||
this.methodConfigs = methodConfigs == null ? new HashMap<>() : methodConfigs;
|
||||
}
|
||||
|
||||
public AsyncMethodInfo getMethodConfig(String methodName) {
|
||||
return methodConfigs.get(methodName);
|
||||
}
|
||||
|
||||
public ServiceDescriptor getServiceModel() {
|
||||
return serviceModel;
|
||||
}
|
||||
|
||||
public ReferenceConfigBase getReferenceConfig() {
|
||||
return referenceConfig;
|
||||
}
|
||||
|
||||
public Set<String> getApps() {
|
||||
return apps;
|
||||
}
|
||||
|
|
@ -117,41 +97,17 @@ public class ConsumerModel {
|
|||
return methodConfigs.get(methodName);
|
||||
}
|
||||
|
||||
/* *************** Start, metadata compatible **************** */
|
||||
|
||||
private ServiceMetadata serviceMetadata;
|
||||
private Map<Method, ConsumerMethodModel> methodModels = new HashMap<>();
|
||||
|
||||
public ConsumerModel(String serviceKey,
|
||||
Object proxyObject,
|
||||
ServiceDescriptor serviceModel,
|
||||
ReferenceConfigBase<?> referenceConfig,
|
||||
ServiceMetadata metadata,
|
||||
Map<String, AsyncMethodInfo> methodConfigs) {
|
||||
|
||||
this(serviceKey, proxyObject, serviceModel, referenceConfig, methodConfigs);
|
||||
this.serviceMetadata = metadata;
|
||||
}
|
||||
|
||||
public void setServiceKey(String serviceKey) {
|
||||
this.serviceKey = serviceKey;
|
||||
if (serviceMetadata != null) {
|
||||
serviceMetadata.setServiceKey(serviceKey);
|
||||
serviceMetadata.setGroup(BaseServiceMetadata.groupFromServiceKey(serviceKey));
|
||||
}
|
||||
}
|
||||
|
||||
public void initMethodModels() {
|
||||
Class<?>[] interfaceList;
|
||||
if (proxyObject == null) {
|
||||
Class<?> serviceInterfaceClass = referenceConfig.getServiceInterfaceClass();
|
||||
if (getProxyObject() == null) {
|
||||
Class<?> serviceInterfaceClass = getReferenceConfig().getServiceInterfaceClass();
|
||||
if (serviceInterfaceClass != null) {
|
||||
interfaceList = new Class[]{serviceInterfaceClass};
|
||||
} else {
|
||||
interfaceList = new Class[0];
|
||||
}
|
||||
} else {
|
||||
interfaceList = proxyObject.getClass().getInterfaces();
|
||||
interfaceList = getProxyObject().getClass().getInterfaces();
|
||||
}
|
||||
for (Class<?> interfaceClass : interfaceList) {
|
||||
for (Method method : interfaceClass.getMethods()) {
|
||||
|
|
@ -160,18 +116,6 @@ public class ConsumerModel {
|
|||
}
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
Class<?> serviceType = serviceMetadata.getServiceType();
|
||||
return serviceType != null ? serviceType.getClassLoader() : ClassUtils.getClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return serviceMetadata
|
||||
*/
|
||||
public ServiceMetadata getServiceMetadata() {
|
||||
return serviceMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return method model for the given method on consumer side
|
||||
*
|
||||
|
|
@ -214,10 +158,4 @@ public class ConsumerModel {
|
|||
public List<ConsumerMethodModel> getAllMethodModels() {
|
||||
return new ArrayList<>(methodModels.values());
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return this.serviceMetadata.getServiceKey();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.ExtensionDirector;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Model of dubbo framework, it can be shared with multiple applications.
|
||||
*/
|
||||
public class FrameworkModel extends ScopeModel {
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(FrameworkModel.class);
|
||||
|
||||
private volatile static FrameworkModel defaultInstance;
|
||||
|
||||
private List<ApplicationModel> applicationModels = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
public FrameworkModel() {
|
||||
super(null, new ExtensionDirector(null, ExtensionScope.FRAMEWORK));
|
||||
postProcessAfterCreated();
|
||||
}
|
||||
|
||||
public static FrameworkModel defaultModel() {
|
||||
if (defaultInstance == null) {
|
||||
synchronized (FrameworkModel.class) {
|
||||
if (defaultInstance == null) {
|
||||
defaultInstance = new FrameworkModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
public void addApplication(ApplicationModel model) {
|
||||
if (!this.applicationModels.contains(model)) {
|
||||
this.applicationModels.add(model);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeApplication(ApplicationModel model) {
|
||||
this.applicationModels.remove(model);
|
||||
}
|
||||
|
||||
public List<ApplicationModel> getApplicationModels() {
|
||||
return applicationModels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FrameworkModel";
|
||||
}
|
||||
}
|
||||
|
|
@ -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.model;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionDirector;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
|
||||
/**
|
||||
* Model of a service module
|
||||
*/
|
||||
public class ModuleModel extends ScopeModel {
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
|
||||
public ModuleModel(ApplicationModel applicationModel) {
|
||||
super(applicationModel, new ExtensionDirector(applicationModel.getExtensionDirector(), ExtensionScope.MODULE));
|
||||
this.applicationModel = applicationModel;
|
||||
applicationModel.addModule(this);
|
||||
postProcessAfterCreated();
|
||||
}
|
||||
|
||||
public ApplicationModel getApplicationModel() {
|
||||
return applicationModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModuleModel";
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.BaseServiceMetadata;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.config.ServiceConfigBase;
|
||||
|
||||
|
|
@ -27,56 +26,57 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* ProviderModel is about published services
|
||||
*/
|
||||
public class ProviderModel {
|
||||
private String serviceKey;
|
||||
private final Object serviceInstance;
|
||||
private final ServiceDescriptor serviceModel;
|
||||
private final ServiceConfigBase<?> serviceConfig;
|
||||
public class ProviderModel extends ServiceModel {
|
||||
private final List<RegisterStatedURL> urls;
|
||||
private final Map<String, List<ProviderMethodModel>> methods = new HashMap<String, List<ProviderMethodModel>>();
|
||||
|
||||
public ProviderModel(String serviceKey,
|
||||
Object serviceInstance,
|
||||
ServiceDescriptor serviceModel,
|
||||
ServiceConfigBase<?> serviceConfig) {
|
||||
super(serviceInstance, serviceKey, serviceModel, serviceConfig);
|
||||
if (null == serviceInstance) {
|
||||
throw new IllegalArgumentException("Service[" + serviceKey + "]Target is NULL.");
|
||||
}
|
||||
|
||||
this.serviceKey = serviceKey;
|
||||
this.serviceInstance = serviceInstance;
|
||||
this.serviceModel = serviceModel;
|
||||
this.serviceConfig = serviceConfig;
|
||||
this.urls = new ArrayList<>(1);
|
||||
}
|
||||
|
||||
public String getServiceKey() {
|
||||
return serviceKey;
|
||||
public ProviderModel(String serviceKey,
|
||||
Object serviceInstance,
|
||||
ServiceDescriptor serviceModel,
|
||||
ServiceConfigBase<?> serviceConfig,
|
||||
ServiceMetadata serviceMetadata) {
|
||||
super(serviceInstance, serviceKey, serviceModel, serviceConfig, serviceMetadata);
|
||||
if (null == serviceInstance) {
|
||||
throw new IllegalArgumentException("Service[" + serviceKey + "]Target is NULL.");
|
||||
}
|
||||
|
||||
initMethod(serviceModel.getServiceInterfaceClass());
|
||||
this.urls = new ArrayList<>(1);
|
||||
}
|
||||
|
||||
public ProviderModel(String serviceKey,
|
||||
Object serviceInstance,
|
||||
ServiceDescriptor serviceModel,
|
||||
ServiceConfigBase<?> serviceConfig,
|
||||
ModuleModel moduleModel,
|
||||
ServiceMetadata serviceMetadata) {
|
||||
super(serviceInstance, serviceKey, serviceModel, serviceConfig, moduleModel, serviceMetadata);
|
||||
if (null == serviceInstance) {
|
||||
throw new IllegalArgumentException("Service[" + serviceKey + "]Target is NULL.");
|
||||
}
|
||||
|
||||
public Class<?> getServiceInterfaceClass() {
|
||||
return serviceModel.getServiceInterfaceClass();
|
||||
initMethod(serviceModel.getServiceInterfaceClass());
|
||||
this.urls = new ArrayList<>(1);
|
||||
}
|
||||
|
||||
public Object getServiceInstance() {
|
||||
return serviceInstance;
|
||||
}
|
||||
|
||||
public Set<MethodDescriptor> getAllMethods() {
|
||||
return serviceModel.getAllMethods();
|
||||
}
|
||||
|
||||
public ServiceDescriptor getServiceModel() {
|
||||
return serviceModel;
|
||||
}
|
||||
|
||||
public ServiceConfigBase getServiceConfig() {
|
||||
return serviceConfig;
|
||||
return getProxyObject();
|
||||
}
|
||||
|
||||
public List<RegisterStatedURL> getStatedUrl() {
|
||||
|
|
@ -125,35 +125,6 @@ public class ProviderModel {
|
|||
}
|
||||
}
|
||||
|
||||
/* *************** Start, metadata compatible **************** */
|
||||
|
||||
private ServiceMetadata serviceMetadata;
|
||||
private final Map<String, List<ProviderMethodModel>> methods = new HashMap<String, List<ProviderMethodModel>>();
|
||||
|
||||
public ProviderModel(String serviceKey,
|
||||
Object serviceInstance,
|
||||
ServiceDescriptor serviceModel,
|
||||
ServiceConfigBase<?> serviceConfig,
|
||||
ServiceMetadata serviceMetadata) {
|
||||
this(serviceKey, serviceInstance, serviceModel, serviceConfig);
|
||||
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
initMethod(serviceModel.getServiceInterfaceClass());
|
||||
}
|
||||
|
||||
|
||||
public void setServiceKey(String serviceKey) {
|
||||
this.serviceKey = serviceKey;
|
||||
if (serviceMetadata != null) {
|
||||
serviceMetadata.setServiceKey(serviceKey);
|
||||
serviceMetadata.setGroup(BaseServiceMetadata.groupFromServiceKey(serviceKey));
|
||||
}
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return this.serviceMetadata.getServiceKey();
|
||||
}
|
||||
|
||||
public List<ProviderMethodModel> getAllMethodModels() {
|
||||
List<ProviderMethodModel> result = new ArrayList<ProviderMethodModel>();
|
||||
for (List<ProviderMethodModel> models : methods.values()) {
|
||||
|
|
@ -195,10 +166,4 @@ public class ProviderModel {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return serviceMetadata
|
||||
*/
|
||||
public ServiceMetadata getServiceMetadata() {
|
||||
return serviceMetadata;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessor;
|
||||
import org.apache.dubbo.common.extension.ExtensionDirector;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class ScopeModel implements ExtensionAccessor {
|
||||
|
||||
private final ScopeModel parent;
|
||||
|
||||
private final ExtensionDirector extensionDirector;
|
||||
|
||||
private final ScopeBeanFactory beanFactory;
|
||||
|
||||
public ScopeModel(ScopeModel parent, ExtensionDirector extensionDirector) {
|
||||
this.parent = parent;
|
||||
this.extensionDirector = extensionDirector;
|
||||
this.extensionDirector.addExtensionPostProcessor(new ScopeModelAwareExtensionProcessor(this));
|
||||
this.beanFactory = new ScopeBeanFactory(parent != null ? parent.getBeanFactory() : null, extensionDirector);
|
||||
}
|
||||
|
||||
public ExtensionDirector getExtensionDirector() {
|
||||
return extensionDirector;
|
||||
}
|
||||
|
||||
public ScopeBeanFactory getBeanFactory() {
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
public ScopeModel getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void postProcessAfterCreated() {
|
||||
Set<ScopeModelPostProcessor> scopeModelPostProcessors = getExtensionLoader(ScopeModelPostProcessor.class)
|
||||
.getSupportedExtensionInstances();
|
||||
for (ScopeModelPostProcessor processor : scopeModelPostProcessors) {
|
||||
processor.postProcessScopeModel(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
/**
|
||||
* An accessor for scope model, it can be use in interface default methods to get scope model.
|
||||
*/
|
||||
public interface ScopeModelAccessor {
|
||||
|
||||
ScopeModel getScopeModel();
|
||||
|
||||
default FrameworkModel getFrameworkModel() {
|
||||
return ScopeModelUtil.getFrameworkModel(getScopeModel());
|
||||
}
|
||||
|
||||
default ApplicationModel getApplicationModel() {
|
||||
return ScopeModelUtil.getApplicationModel(getScopeModel());
|
||||
}
|
||||
|
||||
default ModuleModel getModuleModel() {
|
||||
return ScopeModelUtil.getModuleModel(getScopeModel());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
/**
|
||||
* An interface to inject FrameworkModel/ApplicationModel/ModuleModel for SPI extensions and internal beans.
|
||||
*/
|
||||
public interface ScopeModelAware {
|
||||
|
||||
/**
|
||||
* Override this method if you need get the scope model (maybe one of FrameworkModel/ApplicationModel/ModuleModel).
|
||||
* @param scopeModel
|
||||
*/
|
||||
default void setScopeModel(ScopeModel scopeModel) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method if you just need framework model
|
||||
* @param frameworkModel
|
||||
*/
|
||||
default void setFrameworkModel(FrameworkModel frameworkModel) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method if you just need application model
|
||||
* @param applicationModel
|
||||
*/
|
||||
default void setApplicationModel(ApplicationModel applicationModel) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method if you just need module model
|
||||
* @param moduleModel
|
||||
*/
|
||||
default void setModuleModel(ModuleModel moduleModel) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.ExtensionPostProcessor;
|
||||
|
||||
public class ScopeModelAwareExtensionProcessor implements ExtensionPostProcessor {
|
||||
private ScopeModel scopeModel;
|
||||
private FrameworkModel frameworkModel;
|
||||
private ApplicationModel applicationModel;
|
||||
private ModuleModel moduleModel;
|
||||
private volatile boolean inited;
|
||||
|
||||
public ScopeModelAwareExtensionProcessor(ScopeModel scopeModel) {
|
||||
this.scopeModel = scopeModel;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
if (inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Do not create a new model or use the default application/module model here!
|
||||
// Only the visible and only matching scope model can be injected, that is, module -> application -> framework.
|
||||
// The converse is a one-to-many relationship and cannot be injected.
|
||||
// One framework may have multiple applications, and one application may have multiple modules.
|
||||
// So, the spi extension/bean of application scope can be injected it's application model and framework model,
|
||||
// but the spi extension/bean of framework scope cannot be injected an application or module model.
|
||||
|
||||
if (scopeModel instanceof FrameworkModel) {
|
||||
frameworkModel = (FrameworkModel) scopeModel;
|
||||
} else if (scopeModel instanceof ApplicationModel) {
|
||||
applicationModel = (ApplicationModel) scopeModel;
|
||||
frameworkModel = applicationModel.getFrameworkModel();
|
||||
} else if (scopeModel instanceof ModuleModel) {
|
||||
moduleModel = (ModuleModel) scopeModel;
|
||||
applicationModel = moduleModel.getApplicationModel();
|
||||
frameworkModel = applicationModel.getFrameworkModel();
|
||||
}
|
||||
inited = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object instance, String name) throws Exception {
|
||||
init();
|
||||
if (instance instanceof ScopeModelAware) {
|
||||
ScopeModelAware modelAware = (ScopeModelAware) instance;
|
||||
modelAware.setScopeModel(scopeModel);
|
||||
if (this.moduleModel != null) {
|
||||
modelAware.setModuleModel(this.moduleModel);
|
||||
}
|
||||
if (this.applicationModel != null) {
|
||||
modelAware.setApplicationModel(this.applicationModel);
|
||||
}
|
||||
if (this.frameworkModel != null) {
|
||||
modelAware.setFrameworkModel(this.frameworkModel);
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A post-processor after scope model is created (one of FrameworkModel/ApplicationModel/ModuleModel)
|
||||
*/
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface ScopeModelPostProcessor {
|
||||
|
||||
/**
|
||||
* Post-process after a scope model is created.
|
||||
* @param scopeModel
|
||||
*/
|
||||
void postProcessScopeModel(ScopeModel scopeModel);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
public class ScopeModelUtil {
|
||||
|
||||
public static ModuleModel getModuleModel(ScopeModel scopeModel) {
|
||||
if (scopeModel == null) {
|
||||
return ApplicationModel.defaultModel().getDefaultModule();
|
||||
}
|
||||
if (scopeModel instanceof ModuleModel) {
|
||||
return (ModuleModel) scopeModel;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unable to get ModuleModel from" + scopeModel);
|
||||
}
|
||||
}
|
||||
|
||||
public static ApplicationModel getApplicationModel(ScopeModel scopeModel) {
|
||||
if (scopeModel == null) {
|
||||
return ApplicationModel.defaultModel();
|
||||
}
|
||||
if (scopeModel instanceof ApplicationModel) {
|
||||
return (ApplicationModel) scopeModel;
|
||||
} else if (scopeModel instanceof ModuleModel) {
|
||||
ModuleModel moduleModel = (ModuleModel) scopeModel;
|
||||
return moduleModel.getApplicationModel();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unable to get ApplicationModel from" + scopeModel);
|
||||
}
|
||||
}
|
||||
|
||||
public static FrameworkModel getFrameworkModel(ScopeModel scopeModel) {
|
||||
if (scopeModel == null) {
|
||||
return FrameworkModel.defaultModel();
|
||||
}
|
||||
if (scopeModel instanceof ApplicationModel) {
|
||||
return ((ApplicationModel) scopeModel).getFrameworkModel();
|
||||
} else if (scopeModel instanceof ModuleModel) {
|
||||
ModuleModel moduleModel = (ModuleModel) scopeModel;
|
||||
return moduleModel.getApplicationModel().getFrameworkModel();
|
||||
} else if (scopeModel instanceof FrameworkModel) {
|
||||
return (FrameworkModel) scopeModel;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unable to get FrameworkModel from" + scopeModel);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type, ScopeModel scopeModel) {
|
||||
if(scopeModel != null) {
|
||||
return scopeModel.getExtensionLoader(type);
|
||||
} else {
|
||||
SPI spi = type.getAnnotation(SPI.class);
|
||||
switch (spi.scope()) {
|
||||
case FRAMEWORK:
|
||||
return FrameworkModel.defaultModel().getExtensionLoader(type);
|
||||
case APPLICATION:
|
||||
return ApplicationModel.defaultModel().getExtensionLoader(type);
|
||||
default:
|
||||
return ApplicationModel.defaultModel().getDefaultModule().getExtensionLoader(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.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;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class ServiceModel {
|
||||
private String serviceKey;
|
||||
private Object proxyObject;
|
||||
private final ModuleModel moduleModel;
|
||||
private final ServiceDescriptor serviceModel;
|
||||
private final AbstractInterfaceConfig config;
|
||||
|
||||
private ServiceMetadata serviceMetadata;
|
||||
|
||||
public ServiceModel(Object proxyObject, String serviceKey, ServiceDescriptor serviceModel, AbstractInterfaceConfig config) {
|
||||
this(proxyObject, serviceKey, serviceModel, config, null);
|
||||
}
|
||||
|
||||
public ServiceModel(Object proxyObject, String serviceKey, ServiceDescriptor serviceModel, AbstractInterfaceConfig config, ServiceMetadata serviceMetadata) {
|
||||
this(proxyObject, serviceKey, serviceModel, config, ScopeModelUtil.getModuleModel(config != null ? config.getScopeModel() : null), serviceMetadata);
|
||||
}
|
||||
public ServiceModel(Object proxyObject, String serviceKey, ServiceDescriptor serviceModel, AbstractInterfaceConfig config, ModuleModel moduleModel, ServiceMetadata serviceMetadata) {
|
||||
this.proxyObject = proxyObject;
|
||||
this.serviceKey = serviceKey;
|
||||
this.serviceModel = serviceModel;
|
||||
this.moduleModel = moduleModel;
|
||||
this.config = config;
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
}
|
||||
|
||||
public String getServiceKey() {
|
||||
return serviceKey;
|
||||
}
|
||||
|
||||
public void setProxyObject(Object proxyObject) {
|
||||
this.proxyObject = proxyObject;
|
||||
}
|
||||
|
||||
public Object getProxyObject() {
|
||||
return proxyObject;
|
||||
}
|
||||
|
||||
public ServiceDescriptor getServiceModel() {
|
||||
return serviceModel;
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
Class<?> serviceType = serviceMetadata.getServiceType();
|
||||
return serviceType != null ? serviceType.getClassLoader() : ClassUtils.getClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all method models for the current service
|
||||
*
|
||||
* @return method model list
|
||||
*/
|
||||
public Set<MethodDescriptor> getAllMethods() {
|
||||
return serviceModel.getAllMethods();
|
||||
}
|
||||
|
||||
public Class<?> getServiceInterfaceClass() {
|
||||
return serviceModel.getServiceInterfaceClass();
|
||||
}
|
||||
|
||||
public AbstractInterfaceConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public ReferenceConfigBase<?> getReferenceConfig() {
|
||||
if (config instanceof ReferenceConfigBase) {
|
||||
return (ReferenceConfigBase<?>) config;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Current ServiceModel is not a ConsumerModel");
|
||||
}
|
||||
}
|
||||
|
||||
public ServiceConfigBase<?> getServiceConfig() {
|
||||
if (config instanceof ServiceConfigBase) {
|
||||
return (ServiceConfigBase<?>) config;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Current ServiceModel is not a ProviderModel");
|
||||
}
|
||||
}
|
||||
|
||||
public void setServiceKey(String serviceKey) {
|
||||
this.serviceKey = serviceKey;
|
||||
if (serviceMetadata != null) {
|
||||
serviceMetadata.setServiceKey(serviceKey);
|
||||
serviceMetadata.setGroup(BaseServiceMetadata.groupFromServiceKey(serviceKey));
|
||||
}
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
return this.serviceMetadata.getServiceKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return serviceMetadata
|
||||
*/
|
||||
public ServiceMetadata getServiceMetadata() {
|
||||
return serviceMetadata;
|
||||
}
|
||||
|
||||
public ModuleModel getModuleModel() {
|
||||
return moduleModel;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,8 @@ package org.apache.dubbo.rpc.model;
|
|||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.context.FrameworkExt;
|
||||
import org.apache.dubbo.common.context.LifecycleAdapter;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessor;
|
||||
import org.apache.dubbo.common.extension.ExtensionAccessorAware;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
|
@ -30,14 +31,13 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static org.apache.dubbo.common.BaseServiceMetadata.interfaceFromServiceKey;
|
||||
import static org.apache.dubbo.common.BaseServiceMetadata.versionFromServiceKey;
|
||||
|
||||
public class ServiceRepository extends LifecycleAdapter implements FrameworkExt {
|
||||
public class ServiceRepository extends LifecycleAdapter implements FrameworkExt, ExtensionAccessorAware {
|
||||
|
||||
public static final String NAME = "repository";
|
||||
|
||||
|
|
@ -55,10 +55,15 @@ public class ServiceRepository extends LifecycleAdapter implements FrameworkExt
|
|||
|
||||
// useful to find a url quickly with serviceInterfaceName:version
|
||||
private ConcurrentMap<String, Set<URL>> providerUrlsWithoutGroup = new ConcurrentHashMap<>();
|
||||
private ExtensionAccessor extensionAccessor;
|
||||
|
||||
public ServiceRepository() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() throws IllegalStateException {
|
||||
Set<BuiltinServiceDetector> builtinServices
|
||||
= ExtensionLoader.getExtensionLoader(BuiltinServiceDetector.class).getSupportedExtensionInstances();
|
||||
= extensionAccessor.getExtensionLoader(BuiltinServiceDetector.class).getSupportedExtensionInstances();
|
||||
if (CollectionUtils.isNotEmpty(builtinServices)) {
|
||||
for (BuiltinServiceDetector service : builtinServices) {
|
||||
registerService(service.getService());
|
||||
|
|
@ -104,13 +109,16 @@ public class ServiceRepository extends LifecycleAdapter implements FrameworkExt
|
|||
ServiceDescriptor serviceDescriptor,
|
||||
ReferenceConfigBase<?> rc,
|
||||
Object proxy,
|
||||
ServiceMetadata serviceMetadata,
|
||||
Map<String, AsyncMethodInfo> methodConfigs) {
|
||||
ServiceMetadata serviceMetadata) {
|
||||
ConsumerModel consumerModel = new ConsumerModel(serviceMetadata.getServiceKey(), proxy, serviceDescriptor, rc,
|
||||
serviceMetadata, methodConfigs);
|
||||
serviceMetadata, null);
|
||||
consumers.putIfAbsent(serviceKey, consumerModel);
|
||||
}
|
||||
|
||||
public void registerConsumer(ConsumerModel consumerModel) {
|
||||
consumers.putIfAbsent(consumerModel.getServiceKey(), consumerModel);
|
||||
}
|
||||
|
||||
public void reRegisterConsumer(String newServiceKey, String serviceKey) {
|
||||
ConsumerModel consumerModel = consumers.get(serviceKey);
|
||||
consumerModel.setServiceKey(newServiceKey);
|
||||
|
|
@ -124,12 +132,17 @@ public class ServiceRepository extends LifecycleAdapter implements FrameworkExt
|
|||
ServiceDescriptor serviceModel,
|
||||
ServiceConfigBase<?> serviceConfig,
|
||||
ServiceMetadata serviceMetadata) {
|
||||
ProviderModel providerModel = new ProviderModel(serviceKey, serviceInstance, serviceModel, serviceConfig,
|
||||
serviceMetadata);
|
||||
ProviderModel providerModel = new ProviderModel(serviceKey, serviceInstance, serviceModel,
|
||||
serviceConfig, serviceMetadata);
|
||||
providers.putIfAbsent(serviceKey, providerModel);
|
||||
providersWithoutGroup.putIfAbsent(keyWithoutGroup(serviceKey), providerModel);
|
||||
}
|
||||
|
||||
public void registerProvider(ProviderModel providerModel) {
|
||||
providers.putIfAbsent(providerModel.getServiceKey(), providerModel);
|
||||
providersWithoutGroup.putIfAbsent(keyWithoutGroup(providerModel.getServiceKey()), providerModel);
|
||||
}
|
||||
|
||||
private static String keyWithoutGroup(String serviceKey) {
|
||||
String interfaceName = interfaceFromServiceKey(serviceKey);
|
||||
String version = versionFromServiceKey(serviceKey);
|
||||
|
|
@ -213,4 +226,9 @@ public class ServiceRepository extends LifecycleAdapter implements FrameworkExt
|
|||
providers.clear();
|
||||
providersWithoutGroup.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtensionAccessor(ExtensionAccessor extensionAccessor) {
|
||||
this.extensionAccessor = extensionAccessor;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
|
||||
spi=org.apache.dubbo.common.extension.factory.SpiExtensionFactory
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
adaptive=org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector
|
||||
spi=org.apache.dubbo.common.extension.inject.SpiExtensionInjector
|
||||
scopeBean=org.apache.dubbo.common.beans.ScopeBeanExtensionInjector
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.config;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -31,14 +33,14 @@ public class ConfigurationUtilsTest {
|
|||
@Test
|
||||
public void testGetServerShutdownTimeout () {
|
||||
System.setProperty(SHUTDOWN_WAIT_KEY, " 10000");
|
||||
Assertions.assertEquals(10000, ConfigurationUtils.getServerShutdownTimeout());
|
||||
Assertions.assertEquals(10000, ConfigurationUtils.getServerShutdownTimeout(ApplicationModel.defaultModel()));
|
||||
System.clearProperty(SHUTDOWN_WAIT_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProperty () {
|
||||
System.setProperty(SHUTDOWN_WAIT_KEY, " 10000");
|
||||
Assertions.assertEquals("10000", ConfigurationUtils.getProperty(SHUTDOWN_WAIT_KEY));
|
||||
Assertions.assertEquals("10000", ConfigurationUtils.getProperty(ApplicationModel.defaultModel(), SHUTDOWN_WAIT_KEY));
|
||||
System.clearProperty(SHUTDOWN_WAIT_KEY);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.dubbo.common.config;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
|
@ -31,7 +32,7 @@ public class EnvironmentTest {
|
|||
|
||||
@Test
|
||||
public void testResolvePlaceholders1() {
|
||||
Environment environment = ApplicationModel.getEnvironment();
|
||||
Environment environment = ApplicationModel.defaultModel().getApplicationEnvironment();
|
||||
|
||||
Map<String, String> externalMap = new LinkedHashMap<>();
|
||||
externalMap.put("zookeeper.address", "127.0.0.1");
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.config.configcenter.file;
|
||||
|
||||
import org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
|
@ -31,6 +32,6 @@ public class FileSystemDynamicConfigurationFactoryTest {
|
|||
|
||||
@Test
|
||||
public void testGetFactory() {
|
||||
assertEquals(FileSystemDynamicConfigurationFactory.class, DynamicConfigurationFactory.getDynamicConfigurationFactory("file").getClass());
|
||||
assertEquals(FileSystemDynamicConfigurationFactory.class, ConfigurationUtils.getDynamicConfigurationFactory(ApplicationModel.defaultModel(), "file").getClass());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* 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.extension;
|
||||
|
||||
import org.apache.dubbo.common.extension.director.FooAppService;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkService;
|
||||
import org.apache.dubbo.common.extension.director.FooModuleProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooModuleService;
|
||||
import org.apache.dubbo.common.extension.director.impl.TestAppService;
|
||||
import org.apache.dubbo.common.extension.director.impl.TestFrameworkService;
|
||||
import org.apache.dubbo.common.extension.director.impl.TestModuleService;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ExtensionDirectorTest {
|
||||
|
||||
String testFwSrvName = "testFwSrv";
|
||||
String testAppSrvName = "testAppSrv";
|
||||
String testMdSrvName = "testMdSrv";
|
||||
|
||||
String testAppProviderName = "testAppProvider";
|
||||
String testModuleProviderName = "testModuleProvider";
|
||||
String testFrameworkProviderName = "testFrameworkProvider";
|
||||
|
||||
@Test
|
||||
public void testInheritanceAndScope() {
|
||||
|
||||
// Expecting:
|
||||
// 1. SPI extension only be created in ExtensionDirector which matched scope
|
||||
// 2. Child ExtensionDirector can get extension instance from parent
|
||||
// 3. Parent ExtensionDirector can't get extension instance from child
|
||||
|
||||
ExtensionDirector fwExtensionDirector = new ExtensionDirector(null, ExtensionScope.FRAMEWORK);
|
||||
ExtensionDirector appExtensionDirector = new ExtensionDirector(fwExtensionDirector, ExtensionScope.APPLICATION);
|
||||
ExtensionDirector moduleExtensionDirector = new ExtensionDirector(appExtensionDirector, ExtensionScope.MODULE);
|
||||
|
||||
// test module extension loader
|
||||
FooFrameworkService testFwSrvFromModule = moduleExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooAppService testAppSrvFromModule = moduleExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
|
||||
FooModuleService testMdSrvFromModule = moduleExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
|
||||
|
||||
Assertions.assertNotNull(testFwSrvFromModule);
|
||||
Assertions.assertNotNull(testAppSrvFromModule);
|
||||
Assertions.assertNotNull(testMdSrvFromModule);
|
||||
|
||||
// test app extension loader
|
||||
FooFrameworkService testFwSrvFromApp = appExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooAppService testAppSrvFromApp = appExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
|
||||
FooModuleService testMdSrvFromApp = appExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
|
||||
|
||||
Assertions.assertSame(testFwSrvFromApp, testFwSrvFromModule);
|
||||
Assertions.assertSame(testAppSrvFromApp, testAppSrvFromModule);
|
||||
Assertions.assertNull(testMdSrvFromApp);
|
||||
|
||||
// test framework extension loader
|
||||
FooFrameworkService testFwSrvFromFw = fwExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooAppService testAppSrvFromFw = fwExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
|
||||
FooModuleService testMdSrvFromFw = fwExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
|
||||
|
||||
Assertions.assertSame(testFwSrvFromFw, testFwSrvFromApp);
|
||||
Assertions.assertNull(testAppSrvFromFw);
|
||||
Assertions.assertNull(testMdSrvFromFw);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostProcessor() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModelAware() {
|
||||
// Expecting:
|
||||
// 1. Module scope SPI can be injected ModuleModel, ApplicationModel, FrameworkModel
|
||||
// 2. Application scope SPI can be injected ApplicationModel, FrameworkModel, but not ModuleModel
|
||||
// 3. Framework scope SPI can be injected FrameworkModel, but not ModuleModel, ApplicationModel
|
||||
|
||||
FrameworkModel frameworkModel = new FrameworkModel();
|
||||
ApplicationModel applicationModel = new ApplicationModel(frameworkModel);
|
||||
ModuleModel moduleModel = new ModuleModel(applicationModel);
|
||||
|
||||
ExtensionDirector moduleExtensionDirector = moduleModel.getExtensionDirector();
|
||||
ExtensionDirector appExtensionDirector = applicationModel.getExtensionDirector();
|
||||
ExtensionDirector fwExtensionDirector = frameworkModel.getExtensionDirector();
|
||||
|
||||
// check extension director inheritance
|
||||
Assertions.assertSame(appExtensionDirector, moduleExtensionDirector.getParent());
|
||||
Assertions.assertSame(fwExtensionDirector, appExtensionDirector.getParent());
|
||||
Assertions.assertSame(null, fwExtensionDirector.getParent());
|
||||
|
||||
// check module extension aware
|
||||
TestFrameworkService testFwSrvFromModule = (TestFrameworkService) moduleExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
TestAppService testAppSrvFromModule = (TestAppService) moduleExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
|
||||
TestModuleService testMdSrvFromModule = (TestModuleService) moduleExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
|
||||
|
||||
Assertions.assertSame(frameworkModel, testFwSrvFromModule.getFrameworkModel());
|
||||
Assertions.assertSame(null, testFwSrvFromModule.getApplicationModel());
|
||||
Assertions.assertSame(null, testFwSrvFromModule.getModuleModel());
|
||||
|
||||
Assertions.assertSame(frameworkModel, testAppSrvFromModule.getFrameworkModel());
|
||||
Assertions.assertSame(applicationModel, testAppSrvFromModule.getApplicationModel());
|
||||
Assertions.assertSame(null, testAppSrvFromModule.getModuleModel());
|
||||
|
||||
Assertions.assertSame(frameworkModel, testMdSrvFromModule.getFrameworkModel());
|
||||
Assertions.assertSame(applicationModel, testMdSrvFromModule.getApplicationModel());
|
||||
Assertions.assertSame(moduleModel, testMdSrvFromModule.getModuleModel());
|
||||
|
||||
// check app extension aware
|
||||
TestFrameworkService testFwSrvFromApp = (TestFrameworkService) appExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
TestAppService testAppSrvFromApp = (TestAppService) appExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
|
||||
TestModuleService testMdSrvFromApp = (TestModuleService) appExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
|
||||
|
||||
Assertions.assertSame(testFwSrvFromApp, testFwSrvFromModule);
|
||||
Assertions.assertSame(testAppSrvFromApp, testAppSrvFromModule);
|
||||
Assertions.assertNull(testMdSrvFromApp);
|
||||
|
||||
// check framework extension aware
|
||||
FooFrameworkService testFwSrvFromFw = fwExtensionDirector.getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooAppService testAppSrvFromFw = fwExtensionDirector.getExtension(FooAppService.class, testAppSrvName);
|
||||
FooModuleService testMdSrvFromFw = fwExtensionDirector.getExtension(FooModuleService.class, testMdSrvName);
|
||||
|
||||
Assertions.assertSame(testFwSrvFromFw, testFwSrvFromApp);
|
||||
Assertions.assertNull(testAppSrvFromFw);
|
||||
Assertions.assertNull(testMdSrvFromFw);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModelDataIsolation() {
|
||||
//Model Tree
|
||||
//├─frameworkModel1
|
||||
//│ ├─applicationModel11
|
||||
//│ │ ├─moduleModel111
|
||||
//│ │ └─moduleModel112
|
||||
//│ └─applicationModel12
|
||||
//│ └─moduleModel121
|
||||
//└─frameworkModel2
|
||||
// └─applicationModel21
|
||||
// └─moduleModel211
|
||||
|
||||
FrameworkModel frameworkModel1 = new FrameworkModel();
|
||||
ApplicationModel applicationModel11 = new ApplicationModel(frameworkModel1);
|
||||
ModuleModel moduleModel111 = new ModuleModel(applicationModel11);
|
||||
ModuleModel moduleModel112 = new ModuleModel(applicationModel11);
|
||||
|
||||
ApplicationModel applicationModel12 = new ApplicationModel(frameworkModel1);
|
||||
ModuleModel moduleModel121 = new ModuleModel(applicationModel12);
|
||||
|
||||
FrameworkModel frameworkModel2 = new FrameworkModel();
|
||||
ApplicationModel applicationModel21 = new ApplicationModel(frameworkModel2);
|
||||
ModuleModel moduleModel211 = new ModuleModel(applicationModel21);
|
||||
|
||||
// test model references
|
||||
Collection<ApplicationModel> applicationsOfFw1 = frameworkModel1.getApplicationModels();
|
||||
Assertions.assertEquals(2, applicationsOfFw1.size());
|
||||
Assertions.assertTrue(applicationsOfFw1.contains(applicationModel11));
|
||||
Assertions.assertTrue(applicationsOfFw1.contains(applicationModel12));
|
||||
Assertions.assertFalse(applicationsOfFw1.contains(applicationModel21));
|
||||
|
||||
Collection<ModuleModel> modulesOfApp11 = applicationModel11.getModuleModels();
|
||||
Assertions.assertEquals(2, modulesOfApp11.size());
|
||||
Assertions.assertTrue(modulesOfApp11.contains(moduleModel111));
|
||||
Assertions.assertTrue(modulesOfApp11.contains(moduleModel112));
|
||||
|
||||
// test isolation of FrameworkModel
|
||||
FooFrameworkService frameworkService1 = frameworkModel1.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooFrameworkService frameworkService2 = frameworkModel2.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
Assertions.assertNotSame(frameworkService1, frameworkService2);
|
||||
|
||||
// test isolation of ApplicationModel
|
||||
// applicationModel11 and applicationModel12 are shared frameworkModel1
|
||||
FooFrameworkService frameworkService11 = applicationModel11.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooFrameworkService frameworkService12 = applicationModel12.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
Assertions.assertSame(frameworkService1, frameworkService11);
|
||||
Assertions.assertSame(frameworkService1, frameworkService12);
|
||||
|
||||
// applicationModel11 and applicationModel12 are isolated in application scope
|
||||
FooAppService applicationService11 = applicationModel11.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
|
||||
FooAppService applicationService12 = applicationModel12.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
|
||||
Assertions.assertNotSame(applicationService11, applicationService12);
|
||||
|
||||
// applicationModel11 and applicationModel21 are isolated in both framework and application scope
|
||||
FooFrameworkService frameworkService21 = applicationModel21.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooAppService applicationService21 = applicationModel21.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
|
||||
Assertions.assertNotSame(frameworkService11, frameworkService21);
|
||||
Assertions.assertNotSame(applicationService11, applicationService21);
|
||||
|
||||
// test isolation of ModuleModel
|
||||
FooModuleService moduleService111 = moduleModel111.getExtensionDirector().getExtension(FooModuleService.class, testMdSrvName);
|
||||
FooModuleService moduleService112 = moduleModel112.getExtensionDirector().getExtension(FooModuleService.class, testMdSrvName);
|
||||
|
||||
// moduleModel111 and moduleModel112 are isolated in module scope
|
||||
Assertions.assertNotSame(moduleService111, moduleService112);
|
||||
|
||||
// moduleModel111 and moduleModel112 are shared applicationModel11
|
||||
FooAppService applicationService111 = moduleModel111.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
|
||||
FooAppService applicationService112 = moduleModel112.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
|
||||
Assertions.assertSame(applicationService111, applicationService112);
|
||||
|
||||
// moduleModel111 and moduleModel121 are isolated in application scope, but shared frameworkModel1
|
||||
FooAppService applicationService121 = moduleModel121.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
|
||||
Assertions.assertNotSame(applicationService111, applicationService121);
|
||||
|
||||
FooFrameworkService frameworkService111 = moduleModel111.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
FooFrameworkService frameworkService121 = moduleModel121.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
Assertions.assertSame(frameworkService111, frameworkService121);
|
||||
|
||||
// moduleModel111 and moduleModel211 are isolated in both framework and application scope
|
||||
FooModuleService moduleService211 = moduleModel211.getExtensionDirector().getExtension(FooModuleService.class, testMdSrvName);
|
||||
FooAppService applicationService211 = moduleModel211.getExtensionDirector().getExtension(FooAppService.class, testAppSrvName);
|
||||
FooFrameworkService frameworkService211 = moduleModel211.getExtensionDirector().getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
Assertions.assertNotSame(moduleService111, moduleService211);
|
||||
Assertions.assertNotSame(applicationService111, applicationService211);
|
||||
Assertions.assertNotSame(frameworkService111, frameworkService211);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInjection() {
|
||||
|
||||
// Expect:
|
||||
// 1. Framework scope extension can be injected to extensions of Framework/Application/Module scope
|
||||
// 2. Application scope extension can be injected to extensions of Application/Module scope, but not Framework scope
|
||||
// 3. Module scope extension can be injected to extensions of Module scope, but not Framework/Application scope
|
||||
|
||||
FrameworkModel frameworkModel = new FrameworkModel();
|
||||
ApplicationModel applicationModel = new ApplicationModel(frameworkModel);
|
||||
ModuleModel moduleModel = new ModuleModel(applicationModel);
|
||||
|
||||
// check module service
|
||||
TestModuleService moduleService = (TestModuleService) moduleModel.getExtensionDirector()
|
||||
.getExtension(FooModuleService.class, testMdSrvName);
|
||||
Assertions.assertNotNull(moduleService.getFrameworkService());
|
||||
Assertions.assertNotNull(moduleService.getFrameworkProvider());
|
||||
Assertions.assertNotNull(moduleService.getAppService());
|
||||
Assertions.assertNotNull(moduleService.getAppProvider());
|
||||
Assertions.assertNotNull(moduleService.getModuleProvider());
|
||||
|
||||
// check app service
|
||||
TestAppService appService = (TestAppService) applicationModel.getExtensionDirector()
|
||||
.getExtension(FooAppService.class, testAppSrvName);
|
||||
Assertions.assertNotNull(appService.getFrameworkService());
|
||||
Assertions.assertNotNull(appService.getFrameworkProvider());
|
||||
Assertions.assertNotNull(appService.getAppProvider());
|
||||
Assertions.assertNull(appService.getModuleProvider());
|
||||
|
||||
// check framework service
|
||||
TestFrameworkService frameworkService = (TestFrameworkService) frameworkModel.getExtensionDirector()
|
||||
.getExtension(FooFrameworkService.class, testFwSrvName);
|
||||
Assertions.assertNotNull(frameworkService.getFrameworkProvider());
|
||||
Assertions.assertNull(frameworkService.getAppProvider());
|
||||
Assertions.assertNull(frameworkService.getModuleProvider());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -61,6 +61,7 @@ import org.apache.dubbo.common.extension.injection.impl.InjectExtImpl;
|
|||
import org.apache.dubbo.common.lang.Prioritized;
|
||||
import org.apache.dubbo.common.url.component.ServiceConfigURL;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -70,7 +71,6 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getLoadingStrategies;
|
||||
import static org.hamcrest.CoreMatchers.allOf;
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
|
|
@ -84,6 +84,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class ExtensionLoaderTest {
|
||||
|
||||
private <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
|
||||
return ApplicationModel.defaultModel().getExtensionDirector().getExtensionLoader(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_getExtensionLoader_Null() throws Exception {
|
||||
try {
|
||||
|
|
@ -266,7 +271,6 @@ public class ExtensionLoaderTest {
|
|||
|
||||
assertThat(ext, instanceOf(AddExt1_ManualAdd1.class));
|
||||
assertEquals("Manual1", getExtensionLoader(AddExt1.class).getExtensionName(AddExt1_ManualAdd1.class));
|
||||
ExtensionLoader.resetExtensionLoader(AddExt1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -277,7 +281,6 @@ public class ExtensionLoaderTest {
|
|||
|
||||
assertThat(ext, instanceOf(Ext9Empty.class));
|
||||
assertEquals("ext9", getExtensionLoader(Ext9Empty.class).getExtensionName(Ext9EmptyImpl.class));
|
||||
ExtensionLoader.resetExtensionLoader(Ext9Empty.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -299,7 +302,6 @@ public class ExtensionLoaderTest {
|
|||
|
||||
AddExt2 adaptive = loader.getAdaptiveExtension();
|
||||
assertTrue(adaptive instanceof AddExt2_ManualAdaptive);
|
||||
ExtensionLoader.resetExtensionLoader(AddExt2.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -338,7 +340,6 @@ public class ExtensionLoaderTest {
|
|||
assertThat(ext, instanceOf(AddExt1_ManualAdd2.class));
|
||||
assertEquals("impl1", getExtensionLoader(AddExt1.class).getExtensionName(AddExt1_ManualAdd2.class));
|
||||
}
|
||||
ExtensionLoader.resetExtensionLoader(AddExt1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -352,7 +353,6 @@ public class ExtensionLoaderTest {
|
|||
|
||||
adaptive = loader.getAdaptiveExtension();
|
||||
assertTrue(adaptive instanceof AddExt3_ManualAdaptive);
|
||||
ExtensionLoader.resetExtensionLoader(AddExt3.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -559,7 +559,7 @@ public class ExtensionLoaderTest {
|
|||
List<LoadingStrategy> loadingStrategies = ExtensionLoader.getLoadingStrategies();
|
||||
ExtensionLoader.setLoadingStrategies(new DubboExternalLoadingStrategyTest(false),
|
||||
new DubboInternalLoadingStrategyTest(false));
|
||||
ExtensionLoader<DuplicatedWithoutOverriddenExt> extensionLoader = ExtensionLoader.getExtensionLoader(DuplicatedWithoutOverriddenExt.class);
|
||||
ExtensionLoader<DuplicatedWithoutOverriddenExt> extensionLoader = getExtensionLoader(DuplicatedWithoutOverriddenExt.class);
|
||||
try {
|
||||
extensionLoader.getExtension("duplicated");
|
||||
fail();
|
||||
|
|
@ -577,7 +577,7 @@ public class ExtensionLoaderTest {
|
|||
List<LoadingStrategy> loadingStrategies = ExtensionLoader.getLoadingStrategies();
|
||||
ExtensionLoader.setLoadingStrategies(new DubboExternalLoadingStrategyTest(true),
|
||||
new DubboInternalLoadingStrategyTest(true));
|
||||
ExtensionLoader<DuplicatedOverriddenExt> extensionLoader = ExtensionLoader.getExtensionLoader(DuplicatedOverriddenExt.class);
|
||||
ExtensionLoader<DuplicatedOverriddenExt> extensionLoader = getExtensionLoader(DuplicatedOverriddenExt.class);
|
||||
DuplicatedOverriddenExt duplicatedOverriddenExt = extensionLoader.getExtension("duplicated");
|
||||
assertEquals("DuplicatedOverriddenExt1", duplicatedOverriddenExt.echo());
|
||||
//recover the loading strategies
|
||||
|
|
|
|||
|
|
@ -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.common.extension.director;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface FooAppProvider {
|
||||
|
||||
@Adaptive
|
||||
void process(URL url);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.extension.director;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI(scope = ExtensionScope.APPLICATION)
|
||||
public interface FooAppService {
|
||||
@Adaptive
|
||||
void process(URL url);
|
||||
}
|
||||
|
|
@ -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.common.extension.director;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface FooFrameworkProvider {
|
||||
|
||||
@Adaptive
|
||||
void process(URL url);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.extension.director;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI(scope = ExtensionScope.FRAMEWORK)
|
||||
public interface FooFrameworkService {
|
||||
@Adaptive
|
||||
void process(URL url);
|
||||
}
|
||||
|
|
@ -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.common.extension.director;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI(scope = ExtensionScope.MODULE)
|
||||
public interface FooModuleProvider {
|
||||
|
||||
@Adaptive
|
||||
void process(URL url);
|
||||
|
||||
}
|
||||
|
|
@ -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.common.extension.director;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.Adaptive;
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI(scope = ExtensionScope.MODULE)
|
||||
public interface FooModuleService {
|
||||
|
||||
@Adaptive
|
||||
void process(URL url);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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.extension.director.impl;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelAware;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
public class BaseTestService implements ScopeModelAware {
|
||||
private FrameworkModel frameworkModel;
|
||||
private ApplicationModel applicationModel;
|
||||
private ModuleModel moduleModel;
|
||||
|
||||
@Override
|
||||
public void setFrameworkModel(FrameworkModel frameworkModel) {
|
||||
this.frameworkModel = frameworkModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationModel(ApplicationModel applicationModel) {
|
||||
this.applicationModel = applicationModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModuleModel(ModuleModel moduleModel) {
|
||||
this.moduleModel = moduleModel;
|
||||
}
|
||||
|
||||
public FrameworkModel getFrameworkModel() {
|
||||
return frameworkModel;
|
||||
}
|
||||
|
||||
public ApplicationModel getApplicationModel() {
|
||||
return applicationModel;
|
||||
}
|
||||
|
||||
public ModuleModel getModuleModel() {
|
||||
return moduleModel;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.extension.director.impl;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.director.FooAppProvider;
|
||||
|
||||
public class TestAppProvider implements FooAppProvider {
|
||||
@Override
|
||||
public void process(URL url) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.extension.director.impl;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.director.FooAppProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooAppService;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkService;
|
||||
import org.apache.dubbo.common.extension.director.FooModuleProvider;
|
||||
|
||||
public class TestAppService extends BaseTestService implements FooAppService {
|
||||
|
||||
private FooFrameworkService frameworkService;
|
||||
|
||||
private FooFrameworkProvider frameworkProvider;
|
||||
|
||||
private FooAppProvider appProvider;
|
||||
|
||||
private FooModuleProvider moduleProvider;
|
||||
|
||||
public FooFrameworkService getFrameworkService() {
|
||||
return frameworkService;
|
||||
}
|
||||
|
||||
public void setFrameworkService(FooFrameworkService frameworkService) {
|
||||
this.frameworkService = frameworkService;
|
||||
}
|
||||
|
||||
public FooAppProvider getAppProvider() {
|
||||
return appProvider;
|
||||
}
|
||||
|
||||
public void setAppProvider(FooAppProvider appProvider) {
|
||||
this.appProvider = appProvider;
|
||||
}
|
||||
|
||||
public FooModuleProvider getModuleProvider() {
|
||||
return moduleProvider;
|
||||
}
|
||||
|
||||
public void setModuleProvider(FooModuleProvider moduleProvider) {
|
||||
this.moduleProvider = moduleProvider;
|
||||
}
|
||||
|
||||
public FooFrameworkProvider getFrameworkProvider() {
|
||||
return frameworkProvider;
|
||||
}
|
||||
|
||||
public void setFrameworkProvider(FooFrameworkProvider frameworkProvider) {
|
||||
this.frameworkProvider = frameworkProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(URL url) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.extension.director.impl;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
|
||||
|
||||
public class TestFrameworkProvider implements FooFrameworkProvider {
|
||||
@Override
|
||||
public void process(URL url) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.extension.director.impl;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.director.FooAppProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkService;
|
||||
import org.apache.dubbo.common.extension.director.FooModuleProvider;
|
||||
|
||||
public class TestFrameworkService extends BaseTestService implements FooFrameworkService {
|
||||
|
||||
private FooFrameworkProvider frameworkProvider;
|
||||
|
||||
private FooAppProvider appProvider;
|
||||
|
||||
private FooModuleProvider moduleProvider;
|
||||
|
||||
public FooFrameworkProvider getFrameworkProvider() {
|
||||
return frameworkProvider;
|
||||
}
|
||||
|
||||
public void setFrameworkProvider(FooFrameworkProvider frameworkProvider) {
|
||||
this.frameworkProvider = frameworkProvider;
|
||||
}
|
||||
|
||||
public FooAppProvider getAppProvider() {
|
||||
return appProvider;
|
||||
}
|
||||
|
||||
public void setAppProvider(FooAppProvider appProvider) {
|
||||
this.appProvider = appProvider;
|
||||
}
|
||||
|
||||
public FooModuleProvider getModuleProvider() {
|
||||
return moduleProvider;
|
||||
}
|
||||
|
||||
public void setModuleProvider(FooModuleProvider moduleProvider) {
|
||||
this.moduleProvider = moduleProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(URL url) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.extension.director.impl;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.director.FooModuleProvider;
|
||||
|
||||
public class TestModuleProvider implements FooModuleProvider {
|
||||
|
||||
public void process(URL url) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.extension.director.impl;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.director.FooAppProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooAppService;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooFrameworkService;
|
||||
import org.apache.dubbo.common.extension.director.FooModuleProvider;
|
||||
import org.apache.dubbo.common.extension.director.FooModuleService;
|
||||
|
||||
public class TestModuleService extends BaseTestService implements FooModuleService {
|
||||
|
||||
private FooFrameworkService frameworkService;
|
||||
|
||||
private FooFrameworkProvider frameworkProvider;
|
||||
|
||||
private FooAppService appService;
|
||||
|
||||
private FooAppProvider appProvider;
|
||||
|
||||
private FooModuleProvider moduleProvider;
|
||||
|
||||
public FooFrameworkService getFrameworkService() {
|
||||
return frameworkService;
|
||||
}
|
||||
|
||||
public void setFrameworkService(FooFrameworkService frameworkService) {
|
||||
this.frameworkService = frameworkService;
|
||||
}
|
||||
|
||||
public FooAppProvider getAppProvider() {
|
||||
return appProvider;
|
||||
}
|
||||
|
||||
public void setAppProvider(FooAppProvider appProvider) {
|
||||
this.appProvider = appProvider;
|
||||
}
|
||||
|
||||
public FooModuleProvider getModuleProvider() {
|
||||
return moduleProvider;
|
||||
}
|
||||
|
||||
public void setModuleProvider(FooModuleProvider moduleProvider) {
|
||||
this.moduleProvider = moduleProvider;
|
||||
}
|
||||
|
||||
public FooFrameworkProvider getFrameworkProvider() {
|
||||
return frameworkProvider;
|
||||
}
|
||||
|
||||
public void setFrameworkProvider(FooFrameworkProvider frameworkProvider) {
|
||||
this.frameworkProvider = frameworkProvider;
|
||||
}
|
||||
|
||||
public FooAppService getAppService() {
|
||||
return appService;
|
||||
}
|
||||
|
||||
public void setAppService(FooAppService appService) {
|
||||
this.appService = appService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(URL url) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -25,8 +25,8 @@ import org.apache.dubbo.config.MonitorConfig;
|
|||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
|
||||
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;
|
||||
|
|
@ -36,7 +36,6 @@ import java.util.Collection;
|
|||
import static java.util.Arrays.asList;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
|
||||
import static org.apache.dubbo.config.context.ConfigManager.DUBBO_CONFIG_MODE;
|
||||
import static org.apache.dubbo.rpc.model.ApplicationModel.getConfigManager;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
|
@ -50,7 +49,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
*/
|
||||
public class ConfigManagerTest {
|
||||
|
||||
private ConfigManager configManager = getConfigManager();
|
||||
private ConfigManager configManager = ApplicationModel.defaultModel().getApplicationConfigManager();
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
|
|
@ -256,15 +255,16 @@ public class ConfigManagerTest {
|
|||
try {
|
||||
// test strict mode
|
||||
ApplicationModel.reset();
|
||||
Assertions.assertEquals(ConfigMode.STRICT, getConfigManager().getConfigMode());
|
||||
ConfigManager configManager = ApplicationModel.defaultModel().getApplicationConfigManager();
|
||||
Assertions.assertEquals(ConfigMode.STRICT, configManager.getConfigMode());
|
||||
|
||||
System.setProperty(DUBBO_CONFIG_MODE, ConfigMode.STRICT.name());
|
||||
ApplicationModel.reset();
|
||||
Assertions.assertEquals(ConfigMode.STRICT, getConfigManager().getConfigMode());
|
||||
Assertions.assertEquals(ConfigMode.STRICT, configManager.getConfigMode());
|
||||
|
||||
getConfigManager().addConfig(applicationConfig1);
|
||||
configManager.addConfig(applicationConfig1);
|
||||
try {
|
||||
getConfigManager().addConfig(applicationConfig2);
|
||||
configManager.addConfig(applicationConfig2);
|
||||
fail("strict mode cannot add two application configs");
|
||||
} catch (Exception e) {
|
||||
assertEquals(IllegalStateException.class, e.getClass());
|
||||
|
|
@ -274,21 +274,23 @@ public class ConfigManagerTest {
|
|||
// test override mode
|
||||
System.setProperty(DUBBO_CONFIG_MODE, ConfigMode.OVERRIDE.name());
|
||||
ApplicationModel.reset();
|
||||
Assertions.assertEquals(ConfigMode.OVERRIDE, getConfigManager().getConfigMode());
|
||||
configManager = ApplicationModel.defaultModel().getApplicationConfigManager();
|
||||
Assertions.assertEquals(ConfigMode.OVERRIDE, configManager.getConfigMode());
|
||||
|
||||
getConfigManager().addConfig(applicationConfig1);
|
||||
getConfigManager().addConfig(applicationConfig2);
|
||||
assertEquals(applicationConfig2, getConfigManager().getApplicationOrElseThrow());
|
||||
configManager.addConfig(applicationConfig1);
|
||||
configManager.addConfig(applicationConfig2);
|
||||
assertEquals(applicationConfig2, configManager.getApplicationOrElseThrow());
|
||||
|
||||
|
||||
// test ignore mode
|
||||
System.setProperty(DUBBO_CONFIG_MODE, ConfigMode.IGNORE.name());
|
||||
ApplicationModel.reset();
|
||||
Assertions.assertEquals(ConfigMode.IGNORE, getConfigManager().getConfigMode());
|
||||
configManager = ApplicationModel.defaultModel().getApplicationConfigManager();
|
||||
Assertions.assertEquals(ConfigMode.IGNORE, configManager.getConfigMode());
|
||||
|
||||
getConfigManager().addConfig(applicationConfig1);
|
||||
getConfigManager().addConfig(applicationConfig2);
|
||||
assertEquals(applicationConfig1, getConfigManager().getApplicationOrElseThrow());
|
||||
configManager.addConfig(applicationConfig1);
|
||||
configManager.addConfig(applicationConfig2);
|
||||
assertEquals(applicationConfig1, configManager.getApplicationOrElseThrow());
|
||||
} finally {
|
||||
System.clearProperty(DUBBO_CONFIG_MODE);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue