org.apache.dubbo.config.AbstractInterfaceConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dubbo Show documentation
Show all versions of dubbo Show documentation
The all in one project of dubbo
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.common.utils.CollectionUtils;
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.context.ConfigManager;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ServiceMetadata;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
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.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;
/**
* AbstractDefaultConfig
*
* @export
*/
public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
private static final long serialVersionUID = -1559314110797223229L;
/**
* The interface name of the exported service
*/
protected String interfaceName;
/**
* The remote service version the customer/provider side will reference
*/
protected String version;
/**
* The remote service group the customer/provider side will reference
*/
protected String group;
protected ServiceMetadata serviceMetadata;
/**
* Local impl class name for the service interface
*/
protected String local;
/**
* Local stub class name for the service interface
*/
protected String stub;
/**
* Service monitor
*/
protected MonitorConfig monitor;
/**
* Strategies for generating dynamic agents,there are two strategies can be choosed: jdk and javassist
*/
protected String proxy;
/**
* Cluster type
*/
protected String cluster;
/**
* The {@code Filter} when the provider side exposed a service or the customer side references a remote service used,
* if there are more than one, you can use commas to separate them
*/
protected String filter;
/**
* The Listener when the provider side exposes a service or the customer side references a remote service used
* if there are more than one, you can use commas to separate them
*/
protected String listener;
/**
* The owner of the service providers
*/
protected String owner;
/**
* Connection limits, 0 means shared connection, otherwise it defines the connections delegated to the current service
*/
protected Integer connections;
/**
* The layer of service providers
*/
protected String layer;
/**
* The application info
*/
protected ApplicationConfig application;
/**
* The module info
*/
protected ModuleConfig module;
/**
* The registry list the service will register to
* Also see {@link #registryIds}, only one of them will work.
*/
protected List registries;
/**
* The method configuration
*/
private List methods;
/**
* The id list of registries the service will register to
* Also see {@link #registries}, only one of them will work.
*/
protected String registryIds;
// connection events
protected String onconnect;
/**
* Disconnection events
*/
protected String ondisconnect;
/**
* The metrics configuration
*/
protected MetricsConfig metrics;
protected MetadataReportConfig metadataReportConfig;
protected ConfigCenterConfig configCenter;
// callback limits
private Integer callbacks;
// the scope for referring/exporting a service, if it's local, it means searching in current JVM only.
private String scope;
protected String tag;
private Boolean auth;
/**
* The url of the reference service
*/
protected final List urls = new ArrayList();
public List getExportedUrls() {
return urls;
}
public URL toUrl() {
return urls.isEmpty() ? null : urls.iterator().next();
}
public List toUrls() {
return urls;
}
/**
* Check whether the registry config is exists, and then conversion it to {@link RegistryConfig}
*/
public void checkRegistry() {
convertRegistryIdsToRegistries();
for (RegistryConfig registryConfig : registries) {
if (!registryConfig.isValid()) {
throw new IllegalStateException("No registry config found or it's not a valid config! " +
"The registry config is: " + registryConfig);
}
}
}
public static void appendRuntimeParameters(Map map) {
map.put(DUBBO_VERSION_KEY, Version.getProtocolVersion());
map.put(RELEASE_KEY, Version.getVersion());
map.put(TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
if (ConfigUtils.getPid() > 0) {
map.put(PID_KEY, String.valueOf(ConfigUtils.getPid()));
}
}
/**
* Check whether the remote service interface and the methods meet with Dubbo's requirements.it mainly check, if the
* methods configured in the configuration file are included in the interface of remote service
*
* @param interfaceClass the interface of remote service
* @param methods the methods configured
*/
public void checkInterfaceAndMethods(Class interfaceClass, List methods) {
// interface cannot be null
Assert.notNull(interfaceClass, new IllegalStateException("interface not allow null!"));
// to verify interfaceClass is an interface
if (!interfaceClass.isInterface()) {
throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
}
// check if methods exist in the remote service interface
if (CollectionUtils.isNotEmpty(methods)) {
for (MethodConfig methodBean : methods) {
methodBean.setService(interfaceClass.getName());
methodBean.setServiceId(this.getId());
methodBean.refresh();
String methodName = methodBean.getName();
if (StringUtils.isEmpty(methodName)) {
throw new IllegalStateException(" name attribute is required! Please check: " +
"" +
" ");
}
boolean hasMethod = Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> method.getName().equals(methodName));
if (!hasMethod) {
throw new IllegalStateException("The interface " + interfaceClass.getName()
+ " not found method " + methodName);
}
}
}
}
/**
* Legitimacy check of stub, note that: the local will deprecated, and replace with stub
*
* @param interfaceClass for provider side, it is the {@link Class} of the service that will be exported; for consumer
* side, it is the {@link Class} of the remote service interface
*/
public void checkStubAndLocal(Class interfaceClass) {
verifyStubAndLocal(local, "Local", interfaceClass);
verifyStubAndLocal(stub, "Stub", interfaceClass);
}
public void verifyStubAndLocal(String className, String label, Class interfaceClass){
if (ConfigUtils.isNotEmpty(className)) {
Class localClass = ConfigUtils.isDefault(className) ?
ReflectUtils.forName(interfaceClass.getName() + label) : ReflectUtils.forName(className);
verify(interfaceClass, localClass);
}
}
private void verify(Class interfaceClass, Class localClass) {
if (!interfaceClass.isAssignableFrom(localClass)) {
throw new IllegalStateException("The local implementation class " + localClass.getName() +
" not implement interface " + interfaceClass.getName());
}
try {
//Check if the localClass a constructor with parameter who's type is interfaceClass
ReflectUtils.findConstructor(localClass, interfaceClass);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() +
"(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
}
}
private void convertRegistryIdsToRegistries() {
computeValidRegistryIds();
if (StringUtils.isEmpty(registryIds)) {
if (CollectionUtils.isEmpty(registries)) {
List registryConfigs = ApplicationModel.getConfigManager().getDefaultRegistries();
if (registryConfigs.isEmpty()) {
registryConfigs = new ArrayList<>();
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.refresh();
registryConfigs.add(registryConfig);
} else {
registryConfigs = new ArrayList<>(registryConfigs);
}
setRegistries(registryConfigs);
}
} else {
String[] ids = COMMA_SPLIT_PATTERN.split(registryIds);
List tmpRegistries = new ArrayList<>();
Arrays.stream(ids).forEach(id -> {
if (tmpRegistries.stream().noneMatch(reg -> reg.getId().equals(id))) {
Optional globalRegistry = ApplicationModel.getConfigManager().getRegistry(id);
if (globalRegistry.isPresent()) {
tmpRegistries.add(globalRegistry.get());
} else {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setId(id);
registryConfig.refresh();
tmpRegistries.add(registryConfig);
}
}
});
if (tmpRegistries.size() > ids.length) {
throw new IllegalStateException("Too much registries found, the registries assigned to this service " +
"are :" + registryIds + ", but got " + tmpRegistries.size() + " registries!");
}
setRegistries(tmpRegistries);
}
}
protected boolean notHasSelfRegistryProperty() {
return CollectionUtils.isEmpty(registries) && StringUtils.isEmpty(registryIds);
}
public void completeCompoundConfigs(AbstractInterfaceConfig interfaceConfig) {
if (interfaceConfig != null) {
if (application == null) {
setApplication(interfaceConfig.getApplication());
}
if (module == null) {
setModule(interfaceConfig.getModule());
}
if (notHasSelfRegistryProperty()) {
setRegistries(interfaceConfig.getRegistries());
setRegistryIds(interfaceConfig.getRegistryIds());
}
if (monitor == null) {
setMonitor(interfaceConfig.getMonitor());
}
}
if (module != null) {
if (notHasSelfRegistryProperty()) {
setRegistries(module.getRegistries());
}
if (monitor == null) {
setMonitor(module.getMonitor());
}
}
if (application != null) {
if (notHasSelfRegistryProperty()) {
setRegistries(application.getRegistries());
setRegistryIds(application.getRegistryIds());
}
if (monitor == null) {
setMonitor(application.getMonitor());
}
}
}
protected void computeValidRegistryIds() {
if (application != null && notHasSelfRegistryProperty()) {
setRegistries(application.getRegistries());
setRegistryIds(application.getRegistryIds());
}
}
/**
* @return local
* @deprecated Replace to getStub()
*/
@Deprecated
public String getLocal() {
return local;
}
/**
* @param local
* @deprecated Replace to setStub(Boolean)
*/
@Deprecated
public void setLocal(Boolean local) {
if (local == null) {
setLocal((String) null);
} else {
setLocal(local.toString());
}
}
/**
* @param local
* @deprecated Replace to setStub(String)
*/
@Deprecated
public void setLocal(String local) {
this.local = local;
}
public String getStub() {
return stub;
}
public void setStub(Boolean stub) {
if (stub == null) {
setStub((String) null);
} else {
setStub(stub.toString());
}
}
public void setStub(String stub) {
this.stub = stub;
}
public String getCluster() {
return cluster;
}
public void setCluster(String cluster) {
this.cluster = cluster;
}
public String getProxy() {
return proxy;
}
public void setProxy(String proxy) {
this.proxy = proxy;
}
public Integer getConnections() {
return connections;
}
public void setConnections(Integer connections) {
this.connections = connections;
}
@Parameter(key = REFERENCE_FILTER_KEY, append = true)
public String getFilter() {
return filter;
}
public void setFilter(String filter) {
this.filter = filter;
}
@Parameter(key = INVOKER_LISTENER_KEY, append = true)
public String getListener() {
return listener;
}
public void setListener(String listener) {
this.listener = listener;
}
public String getLayer() {
return layer;
}
public void setLayer(String layer) {
this.layer = layer;
}
/**
* Always use the global ApplicationConfig
*/
public ApplicationConfig getApplication() {
ApplicationConfig globalApplication = ApplicationModel.getConfigManager().getApplicationOrElseThrow();
if (globalApplication == null) {
return application;
}
if (application != null && !StringUtils.isEquals(application.getName(), globalApplication.getName())) {
return application;
}
return globalApplication;
}
@Deprecated
public void setApplication(ApplicationConfig application) {
this.application = application;
if (application != null) {
ConfigManager configManager = ApplicationModel.getConfigManager();
configManager.getApplication().orElseGet(() -> {
configManager.setApplication(application);
return application;
});
}
}
public ModuleConfig getModule() {
if (module != null) {
return module;
}
return ApplicationModel.getConfigManager().getModule().orElse(null);
}
@Deprecated
public void setModule(ModuleConfig module) {
this.module = module;
if (module != null) {
ConfigManager configManager = ApplicationModel.getConfigManager();
configManager.getModule().orElseGet(() -> {
configManager.setModule(module);
return module;
});
}
}
public RegistryConfig getRegistry() {
return CollectionUtils.isEmpty(registries) ? null : registries.get(0);
}
public void setRegistry(RegistryConfig registry) {
List registries = new ArrayList(1);
registries.add(registry);
setRegistries(registries);
}
public List getRegistries() {
return registries;
}
@SuppressWarnings({"unchecked"})
public void setRegistries(List registries) {
this.registries = (List) registries;
}
@Parameter(excluded = true)
public String getRegistryIds() {
return registryIds;
}
public void setRegistryIds(String registryIds) {
this.registryIds = registryIds;
}
public List getMethods() {
return methods;
}
// ======== Deprecated ========
@SuppressWarnings("unchecked")
public void setMethods(List methods) {
this.methods = (List) methods;
}
public MonitorConfig getMonitor() {
if (monitor != null) {
return monitor;
}
// FIXME: instead of return null, we should set default monitor when getMonitor() return null in ConfigManager
return ApplicationModel.getConfigManager().getMonitor().orElse(null);
}
@Deprecated
public void setMonitor(String monitor) {
setMonitor(new MonitorConfig(monitor));
}
@Deprecated
public void setMonitor(MonitorConfig monitor) {
this.monitor = monitor;
if (monitor != null) {
ConfigManager configManager = ApplicationModel.getConfigManager();
configManager.getMonitor().orElseGet(() -> {
configManager.setMonitor(monitor);
return monitor;
});
}
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
@Deprecated
public ConfigCenterConfig getConfigCenter() {
if (configCenter != null) {
return configCenter;
}
Collection configCenterConfigs = ApplicationModel.getConfigManager().getConfigCenters();
if (CollectionUtils.isNotEmpty(configCenterConfigs)) {
return configCenterConfigs.iterator().next();
}
return null;
}
@Deprecated
public void setConfigCenter(ConfigCenterConfig configCenter) {
this.configCenter = configCenter;
if (configCenter != null) {
ConfigManager configManager = ApplicationModel.getConfigManager();
Collection configs = configManager.getConfigCenters();
if (CollectionUtils.isEmpty(configs)
|| configs.stream().noneMatch(existed -> existed.equals(configCenter))) {
configManager.addConfigCenter(configCenter);
}
}
}
public Integer getCallbacks() {
return callbacks;
}
public void setCallbacks(Integer callbacks) {
this.callbacks = callbacks;
}
public String getOnconnect() {
return onconnect;
}
public void setOnconnect(String onconnect) {
this.onconnect = onconnect;
}
public String getOndisconnect() {
return ondisconnect;
}
public void setOndisconnect(String ondisconnect) {
this.ondisconnect = ondisconnect;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
@Deprecated
public MetadataReportConfig getMetadataReportConfig() {
if (metadataReportConfig != null) {
return metadataReportConfig;
}
Collection metadataReportConfigs = ApplicationModel.getConfigManager().getMetadataConfigs();
if (CollectionUtils.isNotEmpty(metadataReportConfigs)) {
return metadataReportConfigs.iterator().next();
}
return null;
}
@Deprecated
public void setMetadataReportConfig(MetadataReportConfig metadataReportConfig) {
this.metadataReportConfig = metadataReportConfig;
if (metadataReportConfig != null) {
ConfigManager configManager = ApplicationModel.getConfigManager();
Collection configs = configManager.getMetadataConfigs();
if (CollectionUtils.isEmpty(configs)
|| configs.stream().noneMatch(existed -> existed.equals(metadataReportConfig))) {
configManager.addMetadataReport(metadataReportConfig);
}
}
}
@Deprecated
public MetricsConfig getMetrics() {
if (metrics != null) {
return metrics;
}
return ApplicationModel.getConfigManager().getMetrics().orElse(null);
}
@Deprecated
public void setMetrics(MetricsConfig metrics) {
this.metrics = metrics;
if (metrics != null) {
ConfigManager configManager = ApplicationModel.getConfigManager();
configManager.getMetrics().orElseGet(() -> {
configManager.setMetrics(metrics);
return metrics;
});
}
}
@Parameter(key = TAG_KEY, useKeyAsProperty = false)
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public Boolean getAuth() {
return auth;
}
public void setAuth(Boolean auth) {
this.auth = auth;
}
public SslConfig getSslConfig() {
return ApplicationModel.getConfigManager().getSsl().orElse(null);
}
public void initServiceMetadata(AbstractInterfaceConfig interfaceConfig) {
serviceMetadata.setVersion(getVersion(interfaceConfig));
serviceMetadata.setGroup(getGroup(interfaceConfig));
serviceMetadata.setDefaultGroup(getGroup(interfaceConfig));
serviceMetadata.setServiceInterfaceName(getInterface());
}
public String getGroup(AbstractInterfaceConfig interfaceConfig) {
return StringUtils.isEmpty(this.group) ? (interfaceConfig != null ? interfaceConfig.getGroup() : this.group) : this.group;
}
public String getVersion(AbstractInterfaceConfig interfaceConfig) {
return StringUtils.isEmpty(this.version) ? (interfaceConfig != null ? interfaceConfig.getVersion() : this.version) : this.version;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getInterface() {
return interfaceName;
}
public void setInterface(String interfaceName) {
this.interfaceName = interfaceName;
// if (StringUtils.isEmpty(id)) {
// id = interfaceName;
// }
}
}