blob: 8637662d3357962892118bbe80debfe41e6e0819 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.config;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.Version;
import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.utils.ClassHelper;
import com.alibaba.dubbo.common.utils.ConfigUtils;
import com.alibaba.dubbo.common.utils.NamedThreadFactory;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
import com.alibaba.dubbo.config.model.ApplicationModel;
import com.alibaba.dubbo.config.model.ProviderModel;
import com.alibaba.dubbo.config.support.Parameter;
import com.alibaba.dubbo.rpc.Exporter;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Protocol;
import com.alibaba.dubbo.rpc.ProxyFactory;
import com.alibaba.dubbo.rpc.ServiceClassHolder;
import com.alibaba.dubbo.rpc.cluster.ConfiguratorFactory;
import com.alibaba.dubbo.rpc.service.GenericService;
import com.alibaba.dubbo.rpc.support.ProtocolUtils;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static com.alibaba.dubbo.common.utils.NetUtils.LOCALHOST;
import static com.alibaba.dubbo.common.utils.NetUtils.getAvailablePort;
import static com.alibaba.dubbo.common.utils.NetUtils.getLocalHost;
import static com.alibaba.dubbo.common.utils.NetUtils.isInvalidLocalHost;
import static com.alibaba.dubbo.common.utils.NetUtils.isInvalidPort;
/**
* ServiceConfig
*
* @export
*/
public class ServiceConfig<T> extends AbstractServiceConfig {
private static final long serialVersionUID = 3033787999037024738L;
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
private static final Map<String, Integer> RANDOM_PORT_MAP = new HashMap<String, Integer>();
private static final ScheduledExecutorService delayExportExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("DubboServiceDelayExporter", true));
private final List<URL> urls = new ArrayList<URL>();
private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
// interface type
private String interfaceName;
private Class<?> interfaceClass;
// reference to interface impl
private T ref;
// service name
private String path;
// method configuration
private List<MethodConfig> methods;
private ProviderConfig provider;
private transient volatile boolean exported;
private transient volatile boolean unexported;
private volatile String generic;
public ServiceConfig() {
}
public ServiceConfig(Service service) {
appendAnnotation(Service.class, service);
}
@Deprecated
private static List<ProtocolConfig> convertProviderToProtocol(List<ProviderConfig> providers) {
if (providers == null || providers.isEmpty()) {
return null;
}
List<ProtocolConfig> protocols = new ArrayList<ProtocolConfig>(providers.size());
for (ProviderConfig provider : providers) {
protocols.add(convertProviderToProtocol(provider));
}
return protocols;
}
@Deprecated
private static List<ProviderConfig> convertProtocolToProvider(List<ProtocolConfig> protocols) {
if (protocols == null || protocols.isEmpty()) {
return null;
}
List<ProviderConfig> providers = new ArrayList<ProviderConfig>(protocols.size());
for (ProtocolConfig provider : protocols) {
providers.add(convertProtocolToProvider(provider));
}
return providers;
}
@Deprecated
private static ProtocolConfig convertProviderToProtocol(ProviderConfig provider) {
ProtocolConfig protocol = new ProtocolConfig();
protocol.setName(provider.getProtocol().getName());
protocol.setServer(provider.getServer());
protocol.setClient(provider.getClient());
protocol.setCodec(provider.getCodec());
protocol.setHost(provider.getHost());
protocol.setPort(provider.getPort());
protocol.setPath(provider.getPath());
protocol.setPayload(provider.getPayload());
protocol.setThreads(provider.getThreads());
protocol.setParameters(provider.getParameters());
return protocol;
}
@Deprecated
private static ProviderConfig convertProtocolToProvider(ProtocolConfig protocol) {
ProviderConfig provider = new ProviderConfig();
provider.setProtocol(protocol);
provider.setServer(protocol.getServer());
provider.setClient(protocol.getClient());
provider.setCodec(protocol.getCodec());
provider.setHost(protocol.getHost());
provider.setPort(protocol.getPort());
provider.setPath(protocol.getPath());
provider.setPayload(protocol.getPayload());
provider.setThreads(protocol.getThreads());
provider.setParameters(protocol.getParameters());
return provider;
}
private static Integer getRandomPort(String protocol) {
protocol = protocol.toLowerCase();
if (RANDOM_PORT_MAP.containsKey(protocol)) {
return RANDOM_PORT_MAP.get(protocol);
}
return Integer.MIN_VALUE;
}
private static void putRandomPort(String protocol, Integer port) {
protocol = protocol.toLowerCase();
if (!RANDOM_PORT_MAP.containsKey(protocol)) {
RANDOM_PORT_MAP.put(protocol, port);
}
}
public URL toUrl() {
return urls.isEmpty() ? null : urls.iterator().next();
}
public List<URL> toUrls() {
return urls;
}
@Parameter(excluded = true)
public boolean isExported() {
return exported;
}
@Parameter(excluded = true)
public boolean isUnexported() {
return unexported;
}
public synchronized void export() {
if (provider != null) {
if (export == null) {
export = provider.getExport();
}
if (delay == null) {
delay = provider.getDelay();
}
}
if (export != null && !export) {
return;
}
if (delay != null && delay > 0) {
delayExportExecutor.schedule(new Runnable() {
@Override
public void run() {
doExport();
}
}, delay, TimeUnit.MILLISECONDS);
} else {
doExport();
}
}
protected synchronized void doExport() {
if (unexported) {
throw new IllegalStateException("Already unexported!");
}
if (exported) {
return;
}
exported = true;
if (interfaceName == null || interfaceName.length() == 0) {
throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
}
checkDefault();
if (provider != null) {
if (application == null) {
application = provider.getApplication();
}
if (module == null) {
module = provider.getModule();
}
if (registries == null) {
registries = provider.getRegistries();
}
if (monitor == null) {
monitor = provider.getMonitor();
}
if (protocols == null) {
protocols = provider.getProtocols();
}
}
if (module != null) {
if (registries == null) {
registries = module.getRegistries();
}
if (monitor == null) {
monitor = module.getMonitor();
}
}
if (application != null) {
if (registries == null) {
registries = application.getRegistries();
}
if (monitor == null) {
monitor = application.getMonitor();
}
}
if (ref instanceof GenericService) {
interfaceClass = GenericService.class;
if (StringUtils.isEmpty(generic)) {
generic = Boolean.TRUE.toString();
}
} else {
try {
interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
.getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
checkInterfaceAndMethods(interfaceClass, methods);
checkRef();
generic = Boolean.FALSE.toString();
}
if (local != null) {
if ("true".equals(local)) {
local = interfaceName + "Local";
}
Class<?> localClass;
try {
localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
if (!interfaceClass.isAssignableFrom(localClass)) {
throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
}
}
if (stub != null) {
if ("true".equals(stub)) {
stub = interfaceName + "Stub";
}
Class<?> stubClass;
try {
stubClass = ClassHelper.forNameWithThreadContextClassLoader(stub);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
if (!interfaceClass.isAssignableFrom(stubClass)) {
throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
}
}
checkApplication();
checkRegistry();
checkProtocol();
appendProperties(this);
checkStubAndMock(interfaceClass);
if (path == null || path.length() == 0) {
path = interfaceName;
}
doExportUrls();
ProviderModel providerModel = new ProviderModel(getUniqueServiceName(), this, ref);
ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
}
private void checkRef() {
// reference should not be null, and is the implementation of the given interface
if (ref == null) {
throw new IllegalStateException("ref not allow null!");
}
if (!interfaceClass.isInstance(ref)) {
throw new IllegalStateException("The class "
+ ref.getClass().getName() + " unimplemented interface "
+ interfaceClass + "!");
}
}
public synchronized void unexport() {
if (!exported) {
return;
}
if (unexported) {
return;
}
if (!exporters.isEmpty()) {
for (Exporter<?> exporter : exporters) {
try {
exporter.unexport();
} catch (Throwable t) {
logger.warn("unexpected err when unexport" + exporter, t);
}
}
exporters.clear();
}
unexported = true;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void doExportUrls() {
List<URL> registryURLs = loadRegistries(true);
for (ProtocolConfig protocolConfig : protocols) {
doExportUrlsFor1Protocol(protocolConfig, registryURLs);
}
}
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
String name = protocolConfig.getName();
if (name == null || name.length() == 0) {
name = "dubbo";
}
Map<String, String> map = new HashMap<String, String>();
map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion());
map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
if (ConfigUtils.getPid() > 0) {
map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
}
appendParameters(map, application);
appendParameters(map, module);
appendParameters(map, provider, Constants.DEFAULT_KEY);
appendParameters(map, protocolConfig);
appendParameters(map, this);
if (methods != null && !methods.isEmpty()) {
for (MethodConfig method : methods) {
appendParameters(map, method, method.getName());
String retryKey = method.getName() + ".retry";
if (map.containsKey(retryKey)) {
String retryValue = map.remove(retryKey);
if ("false".equals(retryValue)) {
map.put(method.getName() + ".retries", "0");
}
}
List<ArgumentConfig> arguments = method.getArguments();
if (arguments != null && !arguments.isEmpty()) {
for (ArgumentConfig argument : arguments) {
// convert argument type
if (argument.getType() != null && argument.getType().length() > 0) {
Method[] methods = interfaceClass.getMethods();
// visit all methods
if (methods != null && methods.length > 0) {
for (int i = 0; i < methods.length; i++) {
String methodName = methods[i].getName();
// target the method, and get its signature
if (methodName.equals(method.getName())) {
Class<?>[] argtypes = methods[i].getParameterTypes();
// one callback in the method
if (argument.getIndex() != -1) {
if (argtypes[argument.getIndex()].getName().equals(argument.getType())) {
appendParameters(map, argument, method.getName() + "." + argument.getIndex());
} else {
throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());
}
} else {
// multiple callbacks in the method
for (int j = 0; j < argtypes.length; j++) {
Class<?> argclazz = argtypes[j];
if (argclazz.getName().equals(argument.getType())) {
appendParameters(map, argument, method.getName() + "." + j);
if (argument.getIndex() != -1 && argument.getIndex() != j) {
throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());
}
}
}
}
}
}
}
} else if (argument.getIndex() != -1) {
appendParameters(map, argument, method.getName() + "." + argument.getIndex());
} else {
throw new IllegalArgumentException("argument config must set index or type attribute.eg: <dubbo:argument index='0' .../> or <dubbo:argument type=xxx .../>");
}
}
}
} // end of methods for
}
if (ProtocolUtils.isGeneric(generic)) {
map.put(Constants.GENERIC_KEY, generic);
map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
} else {
String revision = Version.getVersion(interfaceClass, version);
if (revision != null && revision.length() > 0) {
map.put("revision", revision);
}
String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
if (methods.length == 0) {
logger.warn("NO method found in service interface " + interfaceClass.getName());
map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
} else {
map.put(Constants.METHODS_KEY, StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));
}
}
if (!ConfigUtils.isEmpty(token)) {
if (ConfigUtils.isDefault(token)) {
map.put(Constants.TOKEN_KEY, UUID.randomUUID().toString());
} else {
map.put(Constants.TOKEN_KEY, token);
}
}
if (Constants.LOCAL_PROTOCOL.equals(protocolConfig.getName())) {
protocolConfig.setRegister(false);
map.put("notify", "false");
}
// export service
String contextPath = protocolConfig.getContextpath();
if ((contextPath == null || contextPath.length() == 0) && provider != null) {
contextPath = provider.getContextpath();
}
String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
Integer port = this.findConfigedPorts(protocolConfig, name, map);
URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
.hasExtension(url.getProtocol())) {
url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
.getExtension(url.getProtocol()).getConfigurator(url).configure(url);
}
String scope = url.getParameter(Constants.SCOPE_KEY);
// don't export when none is configured
if (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
// export to local if the config is not remote (export to remote only when config is remote)
if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
exportLocal(url);
}
// export to remote if the config is not local (export to local only when config is local)
if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
if (logger.isInfoEnabled()) {
logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
}
if (registryURLs != null && !registryURLs.isEmpty()) {
for (URL registryURL : registryURLs) {
url = url.addParameterIfAbsent(Constants.DYNAMIC_KEY, registryURL.getParameter(Constants.DYNAMIC_KEY));
URL monitorUrl = loadMonitor(registryURL);
if (monitorUrl != null) {
url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
}
if (logger.isInfoEnabled()) {
logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
}
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
Exporter<?> exporter = protocol.export(wrapperInvoker);
exporters.add(exporter);
}
} else {
Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
Exporter<?> exporter = protocol.export(wrapperInvoker);
exporters.add(exporter);
}
}
}
this.urls.add(url);
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void exportLocal(URL url) {
if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
URL local = URL.valueOf(url.toFullString())
.setProtocol(Constants.LOCAL_PROTOCOL)
.setHost(LOCALHOST)
.setPort(0);
ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref));
Exporter<?> exporter = protocol.export(
proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
exporters.add(exporter);
logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry");
}
}
protected Class getServiceClass(T ref) {
return ref.getClass();
}
/**
* Register & bind IP address for service provider, can be configured separately.
* Configuration priority: environment variables -> java system properties -> host property in config file ->
* /etc/hosts -> default network address -> first available network address
*
* @param protocolConfig
* @param registryURLs
* @param map
* @return
*/
private String findConfigedHosts(ProtocolConfig protocolConfig, List<URL> registryURLs, Map<String, String> map) {
boolean anyhost = false;
String hostToBind = getValueFromConfig(protocolConfig, Constants.DUBBO_IP_TO_BIND);
if (hostToBind != null && hostToBind.length() > 0 && isInvalidLocalHost(hostToBind)) {
throw new IllegalArgumentException("Specified invalid bind ip from property:" + Constants.DUBBO_IP_TO_BIND + ", value:" + hostToBind);
}
// if bind ip is not found in environment, keep looking up
if (hostToBind == null || hostToBind.length() == 0) {
hostToBind = protocolConfig.getHost();
if (provider != null && (hostToBind == null || hostToBind.length() == 0)) {
hostToBind = provider.getHost();
}
if (isInvalidLocalHost(hostToBind)) {
anyhost = true;
try {
hostToBind = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
logger.warn(e.getMessage(), e);
}
if (isInvalidLocalHost(hostToBind)) {
if (registryURLs != null && !registryURLs.isEmpty()) {
for (URL registryURL : registryURLs) {
if (Constants.MULTICAST.equalsIgnoreCase(registryURL.getParameter("registry"))) {
// skip multicast registry since we cannot connect to it via Socket
continue;
}
try {
Socket socket = new Socket();
try {
SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
socket.connect(addr, 1000);
hostToBind = socket.getLocalAddress().getHostAddress();
break;
} finally {
try {
socket.close();
} catch (Throwable e) {
}
}
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
}
if (isInvalidLocalHost(hostToBind)) {
hostToBind = getLocalHost();
}
}
}
}
map.put(Constants.BIND_IP_KEY, hostToBind);
// registry ip is not used for bind ip by default
String hostToRegistry = getValueFromConfig(protocolConfig, Constants.DUBBO_IP_TO_REGISTRY);
if (hostToRegistry != null && hostToRegistry.length() > 0 && isInvalidLocalHost(hostToRegistry)) {
throw new IllegalArgumentException("Specified invalid registry ip from property:" + Constants.DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
} else if (hostToRegistry == null || hostToRegistry.length() == 0) {
// bind ip is used as registry ip by default
hostToRegistry = hostToBind;
}
map.put(Constants.ANYHOST_KEY, String.valueOf(anyhost));
return hostToRegistry;
}
/**
* Register port and bind port for the provider, can be configured separately
* Configuration priority: environment variable -> java system properties -> port property in protocol config file
* -> protocol default port
*
* @param protocolConfig
* @param name
* @return
*/
private Integer findConfigedPorts(ProtocolConfig protocolConfig, String name, Map<String, String> map) {
Integer portToBind = null;
// parse bind port from environment
String port = getValueFromConfig(protocolConfig, Constants.DUBBO_PORT_TO_BIND);
portToBind = parsePort(port);
// if there's no bind port found from environment, keep looking up.
if (portToBind == null) {
portToBind = protocolConfig.getPort();
if (provider != null && (portToBind == null || portToBind == 0)) {
portToBind = provider.getPort();
}
final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
if (portToBind == null || portToBind == 0) {
portToBind = defaultPort;
}
if (portToBind == null || portToBind <= 0) {
portToBind = getRandomPort(name);
if (portToBind == null || portToBind < 0) {
portToBind = getAvailablePort(defaultPort);
putRandomPort(name, portToBind);
}
logger.warn("Use random available port(" + portToBind + ") for protocol " + name);
}
}
// save bind port, used as url's key later
map.put(Constants.BIND_PORT_KEY, String.valueOf(portToBind));
// registry port, not used as bind port by default
String portToRegistryStr = getValueFromConfig(protocolConfig, Constants.DUBBO_PORT_TO_REGISTRY);
Integer portToRegistry = parsePort(portToRegistryStr);
if (portToRegistry == null) {
portToRegistry = portToBind;
}
return portToRegistry;
}
private Integer parsePort(String configPort) {
Integer port = null;
if (configPort != null && configPort.length() > 0) {
try {
Integer intPort = Integer.parseInt(configPort);
if (isInvalidPort(intPort)) {
throw new IllegalArgumentException("Specified invalid port from env value:" + configPort);
}
port = intPort;
} catch (Exception e) {
throw new IllegalArgumentException("Specified invalid port from env value:" + configPort);
}
}
return port;
}
private String getValueFromConfig(ProtocolConfig protocolConfig, String key) {
String protocolPrefix = protocolConfig.getName().toUpperCase() + "_";
String port = ConfigUtils.getSystemProperty(protocolPrefix + key);
if (port == null || port.length() == 0) {
port = ConfigUtils.getSystemProperty(key);
}
return port;
}
private void checkDefault() {
if (provider == null) {
provider = new ProviderConfig();
}
appendProperties(provider);
}
private void checkProtocol() {
if ((protocols == null || protocols.isEmpty())
&& provider != null) {
setProtocols(provider.getProtocols());
}
// backward compatibility
if (protocols == null || protocols.isEmpty()) {
setProtocol(new ProtocolConfig());
}
for (ProtocolConfig protocolConfig : protocols) {
if (StringUtils.isEmpty(protocolConfig.getName())) {
protocolConfig.setName(Constants.DUBBO_VERSION_KEY);
}
appendProperties(protocolConfig);
}
}
public Class<?> getInterfaceClass() {
if (interfaceClass != null) {
return interfaceClass;
}
if (ref instanceof GenericService) {
return GenericService.class;
}
try {
if (interfaceName != null && interfaceName.length() > 0) {
this.interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
.getContextClassLoader());
}
} catch (ClassNotFoundException t) {
throw new IllegalStateException(t.getMessage(), t);
}
return interfaceClass;
}
/**
* @param interfaceClass
* @see #setInterface(Class)
* @deprecated
*/
public void setInterfaceClass(Class<?> interfaceClass) {
setInterface(interfaceClass);
}
public String getInterface() {
return interfaceName;
}
public void setInterface(String interfaceName) {
this.interfaceName = interfaceName;
if (id == null || id.length() == 0) {
id = interfaceName;
}
}
public void setInterface(Class<?> interfaceClass) {
if (interfaceClass != null && !interfaceClass.isInterface()) {
throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
}
this.interfaceClass = interfaceClass;
setInterface(interfaceClass == null ? null : interfaceClass.getName());
}
public T getRef() {
return ref;
}
public void setRef(T ref) {
this.ref = ref;
}
@Parameter(excluded = true)
public String getPath() {
return path;
}
public void setPath(String path) {
checkPathName(Constants.PATH_KEY, path);
this.path = path;
}
public List<MethodConfig> getMethods() {
return methods;
}
// ======== Deprecated ========
@SuppressWarnings("unchecked")
public void setMethods(List<? extends MethodConfig> methods) {
this.methods = (List<MethodConfig>) methods;
}
public ProviderConfig getProvider() {
return provider;
}
public void setProvider(ProviderConfig provider) {
this.provider = provider;
}
public String getGeneric() {
return generic;
}
public void setGeneric(String generic) {
if (StringUtils.isEmpty(generic)) {
return;
}
if (ProtocolUtils.isGeneric(generic)) {
this.generic = generic;
} else {
throw new IllegalArgumentException("Unsupported generic type " + generic);
}
}
public List<URL> getExportedUrls() {
return urls;
}
/**
* @deprecated Replace to getProtocols()
*/
@Deprecated
public List<ProviderConfig> getProviders() {
return convertProtocolToProvider(protocols);
}
/**
* @deprecated Replace to setProtocols()
*/
@Deprecated
public void setProviders(List<ProviderConfig> providers) {
this.protocols = convertProviderToProtocol(providers);
}
@Parameter(excluded = true)
public String getUniqueServiceName() {
StringBuilder buf = new StringBuilder();
if (group != null && group.length() > 0) {
buf.append(group).append("/");
}
buf.append(interfaceName);
if (version != null && version.length() > 0) {
buf.append(":").append(version);
}
return buf.toString();
}
}