fix Applicaiton Model related issues.

This commit is contained in:
ken.lj 2019-10-28 20:38:52 +08:00
parent f5899d80d0
commit ec4ee5c4da
7 changed files with 170 additions and 91 deletions

View File

@ -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));
}

View File

@ -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;

View File

@ -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() {

View File

@ -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() {

View File

@ -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
*

View File

@ -136,6 +136,7 @@ public class ProviderModel {
this(serviceKey, serviceInstance, serviceModel, serviceConfig);
this.serviceMetadata = serviceMetadata;
initMethod(serviceModel.getServiceInterfaceClass());
}
public String getServiceName() {

View File

@ -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;
}