fix Applicaiton Model related issues.
This commit is contained in:
parent
f5899d80d0
commit
ec4ee5c4da
|
|
@ -208,9 +208,9 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
|
||||
private ReferenceConfigCache cache;
|
||||
|
||||
private volatile boolean initialized = false;
|
||||
private AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
|
||||
private volatile boolean started = false;
|
||||
private AtomicBoolean started = new AtomicBoolean(false);
|
||||
|
||||
private volatile ServiceInstance serviceInstance;
|
||||
|
||||
|
|
@ -525,37 +525,74 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* export a single ServiceConfig
|
||||
* <p>
|
||||
* Bootstrap must has been started before calling this method.
|
||||
*/
|
||||
public void export(ServiceConfig<?> serviceConfig) {
|
||||
if (!isStarted()) {
|
||||
throw new IllegalStateException("Bootstrap hasn't been started yet.");
|
||||
}
|
||||
this.service(serviceConfig);
|
||||
exporter.accept(serviceConfig);
|
||||
}
|
||||
|
||||
public void unExport(ServiceConfig<?> serviceConfig) {
|
||||
if (!isStarted()) {
|
||||
throw new IllegalStateException("Bootstrap hasn't been started yet.");
|
||||
}
|
||||
configManager.removeConfig(serviceConfig);
|
||||
List<Exporter<?>> scExporters = exporters.get(serviceConfig);
|
||||
if (CollectionUtils.isNotEmpty(scExporters)) {
|
||||
scExporters.forEach(Exporter::unexport);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* refer a single ReferenceConfig
|
||||
* <p>
|
||||
* Bootstrap must has been started before calling this method.
|
||||
*/
|
||||
public void refer(ReferenceConfig<?> referenceConfig) {
|
||||
if (!isStarted()) {
|
||||
throw new IllegalStateException("Bootstrap hasn't been started yet.");
|
||||
}
|
||||
this.reference(referenceConfig);
|
||||
referrer.accept(referenceConfig);
|
||||
}
|
||||
|
||||
public void unRefer(ReferenceConfig<?> referenceConfig) {
|
||||
if (!isStarted()) {
|
||||
throw new IllegalStateException("Bootstrap hasn't been started yet.");
|
||||
}
|
||||
configManager.removeConfig(referenceConfig);
|
||||
cache.destroy(referenceConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public DubboBootstrap initialize() {
|
||||
if (!isInitialized()) {
|
||||
private void initialize() {
|
||||
ApplicationModel.initApplication();
|
||||
|
||||
ApplicationModel.initApplication();
|
||||
startConfigCenter();
|
||||
|
||||
startConfigCenter();
|
||||
startMetadataReport();
|
||||
|
||||
startMetadataReport();
|
||||
loadRemoteConfigs();
|
||||
|
||||
loadRemoteConfigs();
|
||||
useRegistryAsConfigCenterIfNecessary();
|
||||
|
||||
useRegistryAsConfigCenterIfNecessary();
|
||||
initMetadataService();
|
||||
|
||||
initMetadataService();
|
||||
initMetadataServiceExporter();
|
||||
|
||||
initMetadataServiceExporter();
|
||||
|
||||
initEventListener();
|
||||
|
||||
initialized = true;
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " has been initialized!");
|
||||
}
|
||||
initEventListener();
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " has been initialized!");
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void startConfigCenter() {
|
||||
|
|
@ -696,29 +733,24 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
* Start the bootstrap
|
||||
*/
|
||||
public DubboBootstrap start() {
|
||||
if (!isInitialized()) {
|
||||
if (started.compareAndSet(false, true)) {
|
||||
initialize();
|
||||
}
|
||||
if (!isStarted()) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " is starting...");
|
||||
}
|
||||
// 1. export Dubbo Services
|
||||
exportServices();
|
||||
|
||||
// 2. export MetadataService
|
||||
exportMetadataService();
|
||||
|
||||
// Not only provider register
|
||||
if (!isOnlyRegisterProvider() || hasExportedServices()) {
|
||||
// 2. export MetadataService
|
||||
exportMetadataService();
|
||||
//3. Register the local ServiceInstance if required
|
||||
registerServiceInstance();
|
||||
}
|
||||
|
||||
referServices();
|
||||
|
||||
started = true;
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " has started.");
|
||||
}
|
||||
|
|
@ -779,11 +811,11 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
return initialized.get();
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
return started.get();
|
||||
}
|
||||
|
||||
public DubboBootstrap stop() throws IllegalStateException {
|
||||
|
|
@ -872,29 +904,7 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
}
|
||||
|
||||
private void exportServices() {
|
||||
configManager.getServices().forEach(sc -> {
|
||||
// Make sure services with the same service key can be exported only once.
|
||||
if (exporters.keySet().stream()
|
||||
.anyMatch(exportedService -> exportedService.getUniqueServiceName().equals(sc.getUniqueServiceName()))
|
||||
) {
|
||||
logger.warn("Service " + sc.getUniqueServiceName() + "has been exported, it's not allowed to export " +
|
||||
"a service with the same group/interface:version more than once.");
|
||||
return;
|
||||
}
|
||||
|
||||
CompletableFuture<List<Exporter<?>>> future = Helper.export(sc);
|
||||
if (future == null) {
|
||||
return;
|
||||
}
|
||||
future.whenComplete((v, t) -> {
|
||||
if (t != null) {
|
||||
throw new RuntimeException(t);
|
||||
} else {
|
||||
exporters.put(sc, v);
|
||||
}
|
||||
});
|
||||
delayedExportingFutures.add(future);
|
||||
});
|
||||
configManager.getServices().forEach(exporter);
|
||||
}
|
||||
|
||||
private void unexportServices() {
|
||||
|
|
@ -910,21 +920,7 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
cache = ReferenceConfigCache.getCache();
|
||||
}
|
||||
|
||||
configManager.getReferences().forEach((rc) -> {
|
||||
// Make sure service with the same key only refer once.
|
||||
if (cache.getReferredReferences().values().stream()
|
||||
.anyMatch(referredService -> referredService.getUniqueServiceName().equals(rc.getUniqueServiceName()))
|
||||
) {
|
||||
logger.warn("Service " + rc.getUniqueServiceName() + "has been referred, it's not allowed to refer " +
|
||||
"one service with the same group/interface:version more than once.");
|
||||
return;
|
||||
}
|
||||
|
||||
// check eager init or not.
|
||||
if (rc.shouldInit()) {
|
||||
cache.get(rc);
|
||||
}
|
||||
});
|
||||
configManager.getReferences().forEach(referrer);
|
||||
}
|
||||
|
||||
private void unreferServices() {
|
||||
|
|
@ -996,20 +992,20 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
}
|
||||
|
||||
public void destroy() {
|
||||
started = false;
|
||||
if (started.compareAndSet(true, false)) {
|
||||
unregisterServiceInstance();
|
||||
unexportMetadataService();
|
||||
unexportServices();
|
||||
unreferServices();
|
||||
|
||||
unregisterServiceInstance();
|
||||
unexportMetadataService();
|
||||
unexportServices();
|
||||
unreferServices();
|
||||
destroyRegistries();
|
||||
destroyProtocols();
|
||||
destroyServiceDiscoveries();
|
||||
|
||||
destroyRegistries();
|
||||
destroyProtocols();
|
||||
destroyServiceDiscoveries();
|
||||
|
||||
clear();
|
||||
shutdown();
|
||||
release();
|
||||
clear();
|
||||
shutdown();
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyProtocols() {
|
||||
|
|
@ -1079,6 +1075,46 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
private Consumer<? super ServiceConfig> exporter = (sc) -> {
|
||||
// Make sure services with the same service key can be exported only once.
|
||||
if (exporters.keySet().stream()
|
||||
.anyMatch(exportedService -> exportedService.getUniqueServiceName().equals(sc.getUniqueServiceName()))
|
||||
) {
|
||||
logger.warn("Service " + sc.getUniqueServiceName() + "has been exported, it's not allowed to export " +
|
||||
"a service with the same group/interface:version more than once.");
|
||||
return;
|
||||
}
|
||||
|
||||
CompletableFuture<List<Exporter<?>>> future = Helper.export(sc);
|
||||
if (future == null) {
|
||||
return;
|
||||
}
|
||||
future.whenComplete((v, t) -> {
|
||||
if (t != null) {
|
||||
throw new RuntimeException(t);
|
||||
} else {
|
||||
exporters.put(sc, v);
|
||||
}
|
||||
});
|
||||
delayedExportingFutures.add(future);
|
||||
};
|
||||
|
||||
private Consumer<? super ReferenceConfig> referrer = (rc) -> {
|
||||
// Make sure service with the same key only refer once.
|
||||
if (cache.getReferredReferences().values().stream()
|
||||
.anyMatch(referredService -> referredService.getUniqueServiceName().equals(rc.getUniqueServiceName()))
|
||||
) {
|
||||
logger.warn("Service " + rc.getUniqueServiceName() + "has been referred, it's not allowed to refer " +
|
||||
"one service with the same group/interface:version more than once.");
|
||||
return;
|
||||
}
|
||||
|
||||
// check eager init or not.
|
||||
if (rc.shouldInit()) {
|
||||
cache.get(rc);
|
||||
}
|
||||
};
|
||||
|
||||
public static class Helper {
|
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(Helper.class);
|
||||
|
|
@ -1250,6 +1286,7 @@ public class DubboBootstrap extends GenericEventListener {
|
|||
String pathKey = URL.buildKey(sc.getContextPath(protocolConfig)
|
||||
.map(p -> p + "/" + sc.getPath())
|
||||
.orElse(sc.getPath()), sc.getGroup(), sc.getVersion());
|
||||
// TODO, uncomment this line once service key is unified
|
||||
sc.getServiceMetadata().setServiceKey(pathKey);
|
||||
exporters.addAll(doExportUrlsFor1Protocol(sc, protocolConfig, registryURLs));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,6 +337,7 @@ public class ReferenceConfigCache {
|
|||
serviceMetadata.setDefaultGroup(rc.getGroup());
|
||||
serviceMetadata.setServiceType(rc.getActualInterface());
|
||||
serviceMetadata.setServiceInterfaceName(interfaceName);
|
||||
// TODO, uncomment this line once service key is unified
|
||||
serviceMetadata.setServiceKey(URL.buildKey(interfaceName, rc.getGroup(), rc.getVersion()));
|
||||
|
||||
rc.checkStubAndLocal(interfaceClass);
|
||||
|
|
@ -398,11 +399,6 @@ public class ReferenceConfigCache {
|
|||
|
||||
serviceMetadata.getAttachments().putAll(map);
|
||||
|
||||
T proxy = createProxy(map, rc);
|
||||
|
||||
serviceMetadata.setTarget(proxy);
|
||||
serviceMetadata.addAttribute(PROXY_CLASS_REF, proxy);
|
||||
|
||||
ServiceRepository repository = ApplicationModel.getServiceRepository();
|
||||
ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
|
||||
repository.registerConsumer(
|
||||
|
|
@ -410,9 +406,15 @@ public class ReferenceConfigCache {
|
|||
attributes,
|
||||
serviceDescriptor,
|
||||
rc,
|
||||
proxy,
|
||||
null,
|
||||
serviceMetadata);
|
||||
|
||||
T proxy = createProxy(map, rc);
|
||||
|
||||
serviceMetadata.setTarget(proxy);
|
||||
serviceMetadata.addAttribute(PROXY_CLASS_REF, proxy);
|
||||
repository.lookupReferredService(serviceMetadata.getServiceKey()).setProxyObject(proxy);
|
||||
|
||||
// dispatch a ReferenceConfigDestroyedEvent since 2.7.4
|
||||
dispatch(new ReferenceConfigDestroyedEvent(rc));
|
||||
return proxy;
|
||||
|
|
|
|||
|
|
@ -89,11 +89,15 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
|
||||
public void setExternalConfigMap(Map<String, String> externalConfiguration) {
|
||||
this.externalConfigurationMap = externalConfiguration;
|
||||
if (externalConfiguration != null) {
|
||||
this.externalConfigurationMap = externalConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAppExternalConfigMap(Map<String, String> appExternalConfiguration) {
|
||||
this.appExternalConfigurationMap = appExternalConfiguration;
|
||||
if (appExternalConfiguration != null) {
|
||||
this.appExternalConfigurationMap = appExternalConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getExternalConfigurationMap() {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
|
@ -496,8 +497,14 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
return application;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setApplication(ApplicationConfig application) {
|
||||
this.application = application;
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
configManager.getApplication().orElseGet(() -> {
|
||||
configManager.setApplication(application);
|
||||
return application;
|
||||
});
|
||||
}
|
||||
|
||||
private void createApplicationIfAbsent() {
|
||||
|
|
@ -586,12 +593,20 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ConfigCenterConfig getConfigCenter() {
|
||||
return configCenter;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setConfigCenter(ConfigCenterConfig configCenter) {
|
||||
this.configCenter = configCenter;
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
Collection<ConfigCenterConfig> configs = configManager.getConfigCenters();
|
||||
if (CollectionUtils.isEmpty(configs)
|
||||
|| configs.stream().noneMatch(existed -> existed.getAddress().equals(configCenter.getAddress()))) {
|
||||
configManager.addConfigCenter(configCenter);
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getCallbacks() {
|
||||
|
|
@ -626,12 +641,20 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
this.scope = scope;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public MetadataReportConfig getMetadataReportConfig() {
|
||||
return metadataReportConfig;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setMetadataReportConfig(MetadataReportConfig metadataReportConfig) {
|
||||
this.metadataReportConfig = metadataReportConfig;
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
Collection<MetadataReportConfig> configs = configManager.getMetadataConfigs();
|
||||
if (CollectionUtils.isEmpty(configs)
|
||||
|| configs.stream().noneMatch(existed -> existed.getAddress().equals(metadataReportConfig.getAddress()))) {
|
||||
configManager.addMetadataReport(metadataReportConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public MetricsConfig getMetrics() {
|
||||
|
|
|
|||
|
|
@ -35,10 +35,11 @@ import java.util.Set;
|
|||
*/
|
||||
public class ConsumerModel {
|
||||
private final String serviceKey;
|
||||
private final Object proxyObject;
|
||||
private final ServiceDescriptor serviceModel;
|
||||
private final ReferenceConfig<?> referenceConfig;
|
||||
|
||||
private Object proxyObject;
|
||||
|
||||
private final Map<String, AsyncMethodInfo> methodConfigs = new HashMap<>();
|
||||
|
||||
/**
|
||||
|
|
@ -56,7 +57,7 @@ public class ConsumerModel {
|
|||
, Map<String, Object> attributes) {
|
||||
|
||||
Assert.notEmptyString(serviceKey, "Service name can't be null or blank");
|
||||
Assert.notNull(proxyObject, "Proxy object can't be null");
|
||||
// Assert.notNull(proxyObject, "Proxy object can't be null");
|
||||
|
||||
this.serviceKey = serviceKey;
|
||||
this.proxyObject = proxyObject;
|
||||
|
|
@ -78,6 +79,10 @@ public class ConsumerModel {
|
|||
return proxyObject;
|
||||
}
|
||||
|
||||
public void setProxyObject(Object proxyObject) {
|
||||
this.proxyObject = proxyObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all method models for the current service
|
||||
*
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ public class ProviderModel {
|
|||
this(serviceKey, serviceInstance, serviceModel, serviceConfig);
|
||||
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
initMethod(serviceModel.getServiceInterfaceClass());
|
||||
}
|
||||
|
||||
public String getServiceName() {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,14 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.model;
|
||||
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Notice, this class currently has no usage inside Dubbo.
|
||||
*
|
||||
* data related to service level such as name, version, classloader of business service,
|
||||
* security info, etc. Also with a AttributeMap for extension.
|
||||
*/
|
||||
|
|
@ -53,6 +57,9 @@ public class ServiceMetadata {
|
|||
}
|
||||
|
||||
public String getServiceKey() {
|
||||
if (StringUtils.isNotEmpty(serviceKey)) {
|
||||
return serviceKey;
|
||||
}
|
||||
return serviceInterfaceName + ":" + version;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue