blob: f7488f648fe5583345318d9cb0914ac9da5ea275 [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 org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
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.ServiceMetadata;
import org.apache.dubbo.rpc.service.GenericService;
import org.apache.dubbo.rpc.support.ProtocolUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
/**
* ServiceConfig
*
* @export
*/
public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
private static final long serialVersionUID = 3033787999037024738L;
/**
* The interface name of the exported service
*/
protected String interfaceName;
/**
* The interface class of the exported service
*/
protected Class<?> interfaceClass;
/**
* The reference of the interface implementation
*/
protected T ref;
/**
* The service name
*/
protected String path;
/**
* The provider configuration
*/
protected ProviderConfig provider;
/**
* The providerIds
*/
protected String providerIds;
/**
* whether it is a GenericService
*/
protected volatile String generic;
protected ServiceMetadata serviceMetadata;
public ServiceConfigBase() {
serviceMetadata = new ServiceMetadata();
serviceMetadata.addAttribute("ORIGIN_CONFIG", this);
}
public ServiceConfigBase(Service service) {
serviceMetadata = new ServiceMetadata();
serviceMetadata.addAttribute("ORIGIN_CONFIG", this);
appendAnnotation(Service.class, service);
setMethods(MethodConfig.constructMethodConfig(service.methods()));
}
public void exported() {
}
@Deprecated
private static List<ProtocolConfig> convertProviderToProtocol(List<ProviderConfig> providers) {
if (CollectionUtils.isEmpty(providers)) {
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 (CollectionUtils.isEmpty(protocols)) {
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;
}
public boolean shouldExport() {
Boolean export = getExport();
// default value is true
return export == null ? true : export;
}
@Override
public Boolean getExport() {
return (export == null && provider != null) ? provider.getExport() : export;
}
public boolean shouldDelay() {
Integer delay = getDelay();
return delay != null && delay > 0;
}
@Override
public Integer getDelay() {
return (delay == null && provider != null) ? provider.getDelay() : delay;
}
public 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 Optional<String> getContextPath(ProtocolConfig protocolConfig) {
String contextPath = protocolConfig.getContextpath();
if (StringUtils.isEmpty(contextPath) && provider != null) {
contextPath = provider.getContextpath();
}
return Optional.ofNullable(contextPath);
}
protected Class getServiceClass(T ref) {
return ref.getClass();
}
public void completeCompoundConfigs() {
if (provider != null) {
if (application == null) {
setApplication(provider.getApplication());
}
if (module == null) {
setModule(provider.getModule());
}
if (registries == null) {
setRegistries(provider.getRegistries());
}
if (monitor == null) {
setMonitor(provider.getMonitor());
}
if (protocols == null) {
setProtocols(provider.getProtocols());
}
if (configCenter == null) {
setConfigCenter(provider.getConfigCenter());
}
}
if (module != null) {
if (registries == null) {
setRegistries(module.getRegistries());
}
if (monitor == null) {
setMonitor(module.getMonitor());
}
}
if (application != null) {
if (registries == null) {
setRegistries(application.getRegistries());
}
if (monitor == null) {
setMonitor(application.getMonitor());
}
}
}
public void checkDefault() {
createProviderIfAbsent();
}
private void createProviderIfAbsent() {
if (provider != null) {
return;
}
setProvider(
ApplicationModel.getConfigManager()
.getDefaultProvider()
.orElseGet(() -> {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.refresh();
return providerConfig;
})
);
}
public void checkProtocol() {
if (CollectionUtils.isEmpty(protocols) && provider != null) {
setProtocols(provider.getProtocols());
}
convertProtocolIdsToProtocols();
}
private void convertProtocolIdsToProtocols() {
computeValidProtocolIds();
if (StringUtils.isEmpty(protocolIds)) {
if (CollectionUtils.isEmpty(protocols)) {
List<ProtocolConfig> protocolConfigs = ApplicationModel.getConfigManager().getDefaultProtocols();
if (protocolConfigs.isEmpty()) {
protocolConfigs = new ArrayList<>(1);
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.refresh();
protocolConfigs.add(protocolConfig);
}
setProtocols(protocolConfigs);
}
} else {
String[] arr = COMMA_SPLIT_PATTERN.split(protocolIds);
List<ProtocolConfig> tmpProtocols = CollectionUtils.isNotEmpty(protocols) ? protocols : new ArrayList<>();
Arrays.stream(arr).forEach(id -> {
if (tmpProtocols.stream().noneMatch(prot -> prot.getId().equals(id))) {
Optional<ProtocolConfig> globalProtocol = ApplicationModel.getConfigManager().getProtocol(id);
if (globalProtocol.isPresent()) {
tmpProtocols.add(globalProtocol.get());
} else {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setId(id);
protocolConfig.refresh();
tmpProtocols.add(protocolConfig);
}
}
});
if (tmpProtocols.size() > arr.length) {
throw new IllegalStateException("Too much protocols found, the protocols comply to this service are :" + protocolIds + " but got " + protocols
.size() + " registries!");
}
setProtocols(tmpProtocols);
}
}
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(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 void setInterface(String interfaceName) {
this.interfaceName = interfaceName;
if (StringUtils.isEmpty(id)) {
id = interfaceName;
}
}
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) {
this.path = path;
}
public ProviderConfig getProvider() {
return provider;
}
public void setProvider(ProviderConfig provider) {
ApplicationModel.getConfigManager().addProvider(provider);
this.provider = provider;
}
@Parameter(excluded = true)
public String getProviderIds() {
return providerIds;
}
public void setProviderIds(String providerIds) {
this.providerIds = providerIds;
}
public String getGeneric() {
return generic;
}
public void setGeneric(String generic) {
if (StringUtils.isEmpty(generic)) {
return;
}
if (ProtocolUtils.isValidGenericValue(generic)) {
this.generic = generic;
} else {
throw new IllegalArgumentException("Unsupported generic type " + generic);
}
}
@Override
public void setMock(Boolean mock) {
throw new IllegalArgumentException("mock doesn't support on provider side");
}
@Override
public void setMock(String mock) {
throw new IllegalArgumentException("mock doesn't support on provider side");
}
public ServiceMetadata getServiceMetadata() {
return serviceMetadata;
}
/**
* @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);
}
@Override
@Parameter(excluded = true)
public String getPrefix() {
return DUBBO + ".service." + interfaceName;
}
@Parameter(excluded = true)
public String getUniqueServiceName() {
return URL.buildKey(interfaceName, group, version);
}
private void computeValidProtocolIds() {
if (StringUtils.isEmpty(getProtocolIds())) {
if (getProvider() != null && StringUtils.isNotEmpty(getProvider().getProtocolIds())) {
setProtocolIds(getProvider().getProtocolIds());
}
}
}
@Override
protected void computeValidRegistryIds() {
super.computeValidRegistryIds();
if (StringUtils.isEmpty(getRegistryIds())) {
if (getProvider() != null && StringUtils.isNotEmpty(getProvider().getRegistryIds())) {
setRegistryIds(getProvider().getRegistryIds());
}
}
}
public abstract void export();
public abstract void unexport();
public abstract boolean isExported();
public abstract boolean isUnexported();
}