Feature improvement, only register one url for port unification. (#12528)
This commit is contained in:
parent
186ec674bf
commit
8e55dae8f9
|
|
@ -641,7 +641,13 @@ public interface CommonConstants {
|
|||
|
||||
String REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY = "restServiceDeployerAttributeKey";
|
||||
|
||||
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer"; String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest";
|
||||
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer";
|
||||
|
||||
String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest";
|
||||
|
||||
String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register";
|
||||
|
||||
String EXT_PROTOCOL = "ext.protocol";
|
||||
|
||||
String IS_EXTRA = "isExtra";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ public interface ApplicationDeployer extends Deployer<ApplicationModel> {
|
|||
/**
|
||||
* Register application instance and start internal services
|
||||
*/
|
||||
void prepareApplicationInstance();
|
||||
void prepareApplicationInstance(ModuleModel moduleModel);
|
||||
|
||||
void exportMetadataService();
|
||||
|
||||
/**
|
||||
* Register application instance and start internal services
|
||||
|
|
|
|||
|
|
@ -50,4 +50,8 @@ public interface ModuleDeployer extends Deployer<ModuleModel> {
|
|||
* Whether start in background, do not await finish
|
||||
*/
|
||||
boolean isBackground();
|
||||
|
||||
boolean hasRegistryInteraction();
|
||||
|
||||
ApplicationDeployer getApplicationDeployer();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
|
||||
|
|
@ -82,6 +83,8 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
|
||||
private static final long serialVersionUID = 5508512956753757169L;
|
||||
|
||||
private static final String DEFAULT_NAME_PREFIX = "DUBBO_APP_";
|
||||
|
||||
/**
|
||||
* Application name
|
||||
*/
|
||||
|
|
@ -747,6 +750,12 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
public void refresh() {
|
||||
super.refresh();
|
||||
appendEnvironmentProperties();
|
||||
if (StringUtils.isEmpty(getName())) {
|
||||
String defaultName = DEFAULT_NAME_PREFIX + UUID.randomUUID();
|
||||
this.setName(defaultName);
|
||||
LOGGER.info("No application name was set, '" + defaultName + "' will be used as the default application name," +
|
||||
" it's highly recommended to set a unique and customized name for it can be critical for some service governance features.");
|
||||
}
|
||||
}
|
||||
|
||||
private void appendEnvironmentProperties() {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_ISOLATION;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.IS_EXTRA;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
|
||||
|
|
@ -366,7 +368,17 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
mapServiceName(url, serviceNameMapping, scheduledExecutor);
|
||||
}
|
||||
});
|
||||
|
||||
onExported();
|
||||
|
||||
if (hasRegistrySpecified()) {
|
||||
getScopeModel().getDeployer().getApplicationDeployer().exportMetadataService();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasRegistrySpecified() {
|
||||
return CollectionUtils.isNotEmpty(this.getRegistries())
|
||||
|| CollectionUtils.isNotEmpty(getScopeModel().getApplicationModel().getApplicationConfigManager().getRegistries());
|
||||
}
|
||||
|
||||
protected void mapServiceName(URL url, ServiceNameMapping serviceNameMapping, ScheduledExecutorService scheduledExecutor) {
|
||||
|
|
@ -740,14 +752,13 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
// export to remote if the config is not local (export to local only when config is local)
|
||||
if (!SCOPE_LOCAL.equalsIgnoreCase(scope)) {
|
||||
// export to extra protocol is used in remote export
|
||||
String extProtocol = url.getParameter("ext.protocol", "");
|
||||
String extProtocol = url.getParameter(EXT_PROTOCOL, "");
|
||||
List<String> protocols = new ArrayList<>();
|
||||
|
||||
if (StringUtils.isNotBlank(extProtocol)) {
|
||||
// export original url
|
||||
url = URLBuilder.from(url).
|
||||
addParameter(IS_PU_SERVER_KEY, Boolean.TRUE.toString()).
|
||||
removeParameter("ext.protocol").
|
||||
build();
|
||||
}
|
||||
|
||||
|
|
@ -765,6 +776,8 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
if (StringUtils.isNotBlank(protocol)) {
|
||||
URL localUrl = URLBuilder.from(url).
|
||||
setProtocol(protocol).
|
||||
addParameter(IS_EXTRA, Boolean.TRUE.toString()).
|
||||
removeParameter(EXT_PROTOCOL).
|
||||
build();
|
||||
localUrl = exportRemote(localUrl, registryURLs, registerType);
|
||||
if (!isGeneric(generic) && !getScopeModel().isInternal()) {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
|
|||
public class InternalServiceConfigBuilder<T> {
|
||||
|
||||
private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass());
|
||||
private static final Set<String> UNACCEPTABLE_PROTOCOL = Stream.of("rest", "grpc").collect(Collectors.toSet());
|
||||
private static final Set<String> ACCEPTABLE_PROTOCOL = Stream.of("dubbo", "tri", "injvm").collect(Collectors.toSet());
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
private String protocol;
|
||||
|
|
@ -112,19 +112,20 @@ public class InternalServiceConfigBuilder<T> {
|
|||
*/
|
||||
private String getRelatedOrDefaultProtocol() {
|
||||
String protocol = "";
|
||||
// <dubbo:consumer/>
|
||||
List<ModuleModel> moduleModels = applicationModel.getPubModuleModels();
|
||||
protocol = moduleModels.stream()
|
||||
.map(ModuleModel::getConfigManager)
|
||||
.map(ModuleConfigManager::getConsumers)
|
||||
.filter(CollectionUtils::isNotEmpty)
|
||||
.flatMap(Collection::stream)
|
||||
.map(ConsumerConfig::getProtocol)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> !UNACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
// <dubbo:protocol/>
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
Collection<ProtocolConfig> protocols = applicationModel.getApplicationConfigManager().getProtocols();
|
||||
if (CollectionUtils.isNotEmpty(protocols)) {
|
||||
protocol = protocols.stream()
|
||||
.map(ProtocolConfig::getName)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> ACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
}
|
||||
// <dubbo:provider/>
|
||||
List<ModuleModel> moduleModels = applicationModel.getPubModuleModels();
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
Stream<ProviderConfig> providerConfigStream = moduleModels.stream()
|
||||
.map(ModuleModel::getConfigManager)
|
||||
|
|
@ -145,22 +146,10 @@ public class InternalServiceConfigBuilder<T> {
|
|||
}
|
||||
})
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> !UNACCEPTABLE_PROTOCOL.contains(p))
|
||||
.filter(p -> ACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
// <dubbo:protocol/>
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
Collection<ProtocolConfig> protocols = applicationModel.getApplicationConfigManager().getProtocols();
|
||||
if (CollectionUtils.isNotEmpty(protocols)) {
|
||||
protocol = protocols.stream()
|
||||
.map(ProtocolConfig::getName)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> !UNACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
}
|
||||
// <dubbo:application/>
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
protocol = getApplicationConfig().getProtocol();
|
||||
|
|
@ -171,7 +160,18 @@ public class InternalServiceConfigBuilder<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
return StringUtils.isNotEmpty(protocol) && !UNACCEPTABLE_PROTOCOL.contains(protocol) ? protocol : DUBBO_PROTOCOL;
|
||||
// <dubbo:consumer/>
|
||||
protocol = moduleModels.stream()
|
||||
.map(ModuleModel::getConfigManager)
|
||||
.map(ModuleConfigManager::getConsumers)
|
||||
.filter(CollectionUtils::isNotEmpty)
|
||||
.flatMap(Collection::stream)
|
||||
.map(ConsumerConfig::getProtocol)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> ACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
return StringUtils.isNotEmpty(protocol) && ACCEPTABLE_PROTOCOL.contains(protocol) ? protocol : DUBBO_PROTOCOL;
|
||||
}
|
||||
|
||||
public InternalServiceConfigBuilder<T> protocol(String protocol) {
|
||||
|
|
@ -254,7 +254,11 @@ public class InternalServiceConfigBuilder<T> {
|
|||
logger.info("Using " + this.protocol + " protocol to export "+interfaceClass.getName()+" service on port " + protocolConfig.getPort());
|
||||
|
||||
applicationModel.getApplicationConfigManager().getProtocol(this.protocol)
|
||||
.ifPresent(protocolConfig::mergeProtocol);
|
||||
.ifPresent(p -> {
|
||||
protocolConfig.mergeProtocol(p);
|
||||
// clear extra protocols possibly merged from global ProtocolConfig
|
||||
protocolConfig.setExtProtocol(null);
|
||||
});
|
||||
|
||||
ApplicationConfig applicationConfig = getApplicationConfig();
|
||||
|
||||
|
|
|
|||
|
|
@ -183,13 +183,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
|
||||
/**
|
||||
* Close registration of instance for pure Consumer process by setting registerConsumer to 'false'
|
||||
* by default is true.
|
||||
* Enable registration of instance for pure Consumer process by setting registerConsumer to 'true'
|
||||
* by default is false.
|
||||
*/
|
||||
private boolean isRegisterConsumerInstance() {
|
||||
Boolean registerConsumer = getApplication().getRegisterConsumer();
|
||||
if (registerConsumer == null) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return Boolean.TRUE.equals(registerConsumer);
|
||||
}
|
||||
|
|
@ -746,7 +746,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
|
||||
@Override
|
||||
public void prepareApplicationInstance() {
|
||||
public void prepareApplicationInstance(ModuleModel moduleModel) {
|
||||
if (hasPreparedApplicationInstance.get()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -754,8 +754,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
// export MetricsService
|
||||
exportMetricsService();
|
||||
|
||||
if (isRegisterConsumerInstance()) {
|
||||
exportMetadataService();
|
||||
if (isRegisterConsumerInstance() || moduleModel.getDeployer().hasRegistryInteraction()) {
|
||||
if (hasPreparedApplicationInstance.compareAndSet(false, true)) {
|
||||
// register the local ServiceInstance if required
|
||||
registerServiceInstance();
|
||||
|
|
@ -763,6 +762,11 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void exportMetadataService() {
|
||||
doExportMetadataService();
|
||||
}
|
||||
|
||||
public void prepareInternalModule() {
|
||||
if (hasPreparedInternalModule) {
|
||||
return;
|
||||
|
|
@ -1081,7 +1085,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
public void checkState(ModuleModel moduleModel, DeployState moduleState) {
|
||||
synchronized (stateLock) {
|
||||
if (!moduleModel.isInternal() && moduleState == DeployState.STARTED) {
|
||||
prepareApplicationInstance();
|
||||
prepareApplicationInstance(moduleModel);
|
||||
}
|
||||
DeployState newState = calculateState();
|
||||
switch (newState) {
|
||||
|
|
@ -1183,8 +1187,8 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
}
|
||||
|
||||
private void exportMetadataService() {
|
||||
if (!isStarting()) {
|
||||
private void doExportMetadataService() {
|
||||
if (!isStarting() && !isStarted()) {
|
||||
return;
|
||||
}
|
||||
for (DeployListener<ApplicationModel> listener : listeners) {
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
private Boolean background;
|
||||
private Boolean exportAsync;
|
||||
private Boolean referAsync;
|
||||
|
||||
private boolean registryInteracted;
|
||||
|
||||
private CompletableFuture<?> exportFuture;
|
||||
private CompletableFuture<?> referFuture;
|
||||
|
||||
|
|
@ -439,6 +442,10 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
exportedServices.add(sc);
|
||||
}
|
||||
}
|
||||
|
||||
if (serviceConfig.hasRegistrySpecified()) {
|
||||
registryInteracted = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void registerServiceInternal(ServiceConfigBase sc) {
|
||||
|
|
@ -578,4 +585,13 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
this.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRegistryInteraction() {
|
||||
return registryInteracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationDeployer getApplicationDeployer() {
|
||||
return applicationDeployer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SE
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CLASS_NOT_FOUND;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_PARAMETER_FORMAT_ERROR;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_REGISTER_MODE_ALL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_REGISTER_MODE_INSTANCE;
|
||||
|
|
@ -464,7 +463,7 @@ public class ConfigValidationUtils {
|
|||
try {
|
||||
ClassUtils.forName("org.apache.dubbo.qos.protocol.QosProtocolWrapper");
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.warn(COMMON_CLASS_NOT_FOUND, "", "", "No QosProtocolWrapper class was found. Please check the dependency of dubbo-qos whether was imported correctly.", e);
|
||||
logger.info("QosProtocolWrapper not found, qos will not be enabled, please check if 'dubbo-qos' dependency was imported correctly.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import org.apache.dubbo.rpc.Protocol;
|
|||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
import org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder;
|
||||
import org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareClusterInvoker;
|
||||
//import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterInvoker;
|
||||
import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
|
@ -1041,6 +1040,7 @@ class ReferenceConfigTest {
|
|||
referenceConfig1.setRegistry(new RegistryConfig(zkUrl1));
|
||||
referenceConfig1.setScopeModel(moduleModel);
|
||||
referenceConfig1.setScope("remote");
|
||||
referenceConfig1.setTimeout(30000);
|
||||
Object object1 = referenceConfig1.get();
|
||||
|
||||
java.lang.reflect.Method callBean1 = object1.getClass().getDeclaredMethod("call", requestClazzOrigin);
|
||||
|
|
|
|||
|
|
@ -186,8 +186,9 @@ class ServiceConfigTest {
|
|||
assertThat(url.getParameters(), hasKey(METHODS_KEY));
|
||||
assertThat(url.getParameters().get(METHODS_KEY), containsString("echo"));
|
||||
assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
|
||||
// export MetadataService and DemoService in "mockprotocol2" protocol.
|
||||
Mockito.verify(protocolDelegate, times(2)).export(Mockito.any(Invoker.class));
|
||||
// export DemoService in "mockprotocol2" protocol.
|
||||
Mockito.verify(protocolDelegate, times(1)).export(Mockito.any(Invoker.class));
|
||||
// MetadataService will be exported on either dubbo or triple (the only two default acceptable protocol)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -351,8 +352,8 @@ class ServiceConfigTest {
|
|||
assertThat(url.getParameters(), hasKey(METHODS_KEY));
|
||||
assertThat(url.getParameters().get(METHODS_KEY), containsString("echo"));
|
||||
assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
|
||||
// export MetadataService and DemoService in "mockprotocol2" protocol.
|
||||
Mockito.verify(protocolDelegate, times(2)).export(Mockito.any(Invoker.class));
|
||||
// export DemoService in "mockprotocol2" protocol (MetadataService will be not exported if no registry specified)
|
||||
Mockito.verify(protocolDelegate, times(1)).export(Mockito.any(Invoker.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
|
||||
|
||||
|
|
@ -159,13 +158,9 @@ class MultipleRegistryCenterExportMetadataIntegrationTest implements Integration
|
|||
// 1. Metadata Service exporter with Injvm protocol
|
||||
// 2. MultipleRegistryCenterExportMetadataService exporter with Injvm protocol
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 2);
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters()
|
||||
.stream()
|
||||
.filter(
|
||||
exporter -> PROTOCOL_NAME.equalsIgnoreCase(exporter.getInvoker().getUrl().getProtocol())
|
||||
).collect(Collectors.toList());
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters();
|
||||
// Make sure there two injvmExporters
|
||||
Assertions.assertEquals(injvmExporters.size(), 2);
|
||||
Assertions.assertEquals(2, injvmExporters.size());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
|
@ -178,4 +173,4 @@ class MultipleRegistryCenterExportMetadataIntegrationTest implements Integration
|
|||
serviceListener = null;
|
||||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
|
||||
|
||||
|
|
@ -155,13 +154,9 @@ class SingleRegistryCenterExportMetadataIntegrationTest implements IntegrationTe
|
|||
// 1. Metadata Service exporter with Injvm protocol
|
||||
// 2. SingleRegistryCenterExportMetadataService exporter with Injvm protocol
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 2);
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters()
|
||||
.stream()
|
||||
.filter(
|
||||
exporter -> PROTOCOL_NAME.equalsIgnoreCase(exporter.getInvoker().getUrl().getProtocol())
|
||||
).collect(Collectors.toList());
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters();
|
||||
// Make sure there are 2 injvmExporters
|
||||
Assertions.assertEquals(injvmExporters.size(), 2);
|
||||
Assertions.assertEquals(2, injvmExporters.size());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
|
@ -174,4 +169,4 @@ class SingleRegistryCenterExportMetadataIntegrationTest implements IntegrationTe
|
|||
serviceListener = null;
|
||||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class MetadataServiceURLParamsMetadataCustomizerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
void test() throws InterruptedException {
|
||||
DubboBootstrap providerBootstrap = DubboBootstrap.newInstance();
|
||||
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>();
|
||||
serviceConfig.setInterface(DemoService.class);
|
||||
|
|
@ -90,8 +90,10 @@ class MetadataServiceURLParamsMetadataCustomizerTest {
|
|||
|
||||
ApplicationModel applicationModel = providerBootstrap.getApplicationModel();
|
||||
MetadataServiceURLParamsMetadataCustomizer customizer = new MetadataServiceURLParamsMetadataCustomizer();
|
||||
customizer.customize(instance, applicationModel);
|
||||
|
||||
Thread.sleep(5000);// wait for service delay export
|
||||
|
||||
customizer.customize(instance, applicationModel);
|
||||
String val = instance.getMetadata().get(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME);
|
||||
Assertions.assertNotNull(val);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,8 @@ import java.lang.reflect.Field;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CLASS_NOT_FOUND;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
|
@ -109,7 +108,7 @@ class ConfigValidationUtilsTest {
|
|||
|
||||
config.setQosEnable(true);
|
||||
mock.validateApplicationConfig(config);
|
||||
verify(loggerMock).warn(eq(COMMON_CLASS_NOT_FOUND), eq(""), eq(""), eq("No QosProtocolWrapper class was found. Please check the dependency of dubbo-qos whether was imported correctly."), any());
|
||||
verify(loggerMock).info(anyString());
|
||||
}
|
||||
|
||||
private void injectField(Field field, Object newValue) throws Exception {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
<modules>
|
||||
<module>dubbo-config-api</module>
|
||||
<module>dubbo-config-spring</module>
|
||||
<module>dubbo-config-spring6</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
@ -49,4 +48,18 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>spring6</id>
|
||||
<activation>
|
||||
<jdk>[17,)</jdk>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>dubbo-config-api</module>
|
||||
<module>dubbo-config-spring</module>
|
||||
<module>dubbo-config-spring6</module>
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DOT_SEPARATOR;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.IS_EXTRA;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
|
||||
import static org.apache.dubbo.metadata.RevisionResolver.EMPTY_REVISION;
|
||||
|
|
@ -240,7 +241,12 @@ public class MetadataInfo implements Serializable {
|
|||
}
|
||||
Set<ServiceInfo> subServices = subscribedServices.get(serviceKeyWithoutProtocol);
|
||||
if (CollectionUtils.isNotEmpty(subServices)) {
|
||||
return subServices.iterator().next();
|
||||
List<ServiceInfo> validServices = subServices.stream().filter(serviceInfo -> StringUtils.isEmpty(serviceInfo.getParameter(IS_EXTRA))).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(validServices)) {
|
||||
return validServices.iterator().next();
|
||||
} else {
|
||||
return subServices.iterator().next();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
|
|||
return factory.getServiceDiscovery(registryURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldRegister(URL providerURL) {
|
||||
|
||||
String side = providerURL.getSide();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.apache.dubbo.common.utils.Assert;
|
|||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.metadata.MetadataInfo;
|
||||
import org.apache.dubbo.registry.AddressListener;
|
||||
import org.apache.dubbo.registry.Constants;
|
||||
|
|
@ -70,6 +71,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INSTANCE_REGISTER_MODE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.IS_EXTRA;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_DESTROY_INVOKER;
|
||||
|
|
@ -389,6 +391,14 @@ public class ServiceDiscoveryRegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
.getMatchedServiceInfos(consumerProtocolServiceKey)
|
||||
.stream()
|
||||
.filter(serviceInfo -> serviceInfo.getPort() <= 0 || serviceInfo.getPort() == port)
|
||||
// special filter for extra protocols.
|
||||
.filter(serviceInfo -> {
|
||||
if (StringUtils.isNotEmpty(consumerProtocolServiceKey.getProtocol())) {// if consumer side protocol is specified, use all the protocols we got in hand now directly
|
||||
return true;
|
||||
} else {// if consumer side protocol is not specified, remove all extra protocols
|
||||
return StringUtils.isEmpty(serviceInfo.getParameter(IS_EXTRA));
|
||||
}
|
||||
})
|
||||
.map(MetadataInfo.ServiceInfo::getProtocolServiceKey)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.constants.RegistryConstants;
|
|||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.JsonUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.metadata.MetadataInfo;
|
||||
|
|
@ -203,19 +204,21 @@ public class ServiceInstanceMetadataUtils {
|
|||
}
|
||||
|
||||
public static void registerMetadataAndInstance(ApplicationModel applicationModel) {
|
||||
LOGGER.info("Start registering instance address to registry.");
|
||||
RegistryManager registryManager = applicationModel.getBeanFactory().getBean(RegistryManager.class);
|
||||
// register service instance
|
||||
List<ServiceDiscovery> serviceDiscoveries = registryManager.getServiceDiscoveries();
|
||||
for (ServiceDiscovery serviceDiscovery : serviceDiscoveries) {
|
||||
MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel,
|
||||
Collections.singletonList(getServiceDiscoveryName(serviceDiscovery))),
|
||||
() -> {
|
||||
// register service instance
|
||||
serviceDiscoveries.forEach(ServiceDiscovery::register);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
if (CollectionUtils.isNotEmpty(registryManager.getServiceDiscoveries())) {
|
||||
LOGGER.info("Start registering instance address to registry.");
|
||||
List<ServiceDiscovery> serviceDiscoveries = registryManager.getServiceDiscoveries();
|
||||
for (ServiceDiscovery serviceDiscovery : serviceDiscoveries) {
|
||||
MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel,
|
||||
Collections.singletonList(getServiceDiscoveryName(serviceDiscovery))),
|
||||
() -> {
|
||||
// register service instance
|
||||
serviceDiscoveries.forEach(ServiceDiscovery::register);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,10 +61,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_REGISTER_MODE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_FAILED_INIT_SERIALIZATION_OPTIMIZER;
|
||||
|
|
@ -413,6 +415,11 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
}
|
||||
|
||||
URL url = mergeUrl(providerUrl);
|
||||
// get the effective protocol that this consumer should consume based on consumer side protocol configuration and available protocols in address pool.
|
||||
String effectiveProtocol = getEffectiveProtocol(queryProtocols, url);
|
||||
if (!effectiveProtocol.equals(url.getProtocol())) {
|
||||
url = url.setProtocol(effectiveProtocol);
|
||||
}
|
||||
|
||||
// Cache key is url that does not merge with consumer side parameters,
|
||||
// regardless of how the consumer combines parameters,
|
||||
|
|
@ -453,6 +460,36 @@ public class RegistryDirectory<T> extends DynamicDirectory<T> {
|
|||
return newUrlInvokerMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the protocol to consume by matching the consumer acceptable protocols and the available provider protocols.
|
||||
* <p>
|
||||
* Only one protocol will be used if consumer set to accept multiple protocols, for example, dubbo.consumer.protocol='tri,rest'.
|
||||
*
|
||||
* @param queryProtocols consumer side protocols.
|
||||
* @param url provider url that have extra protocols specified.
|
||||
* @return the protocol to consume.
|
||||
*/
|
||||
private String getEffectiveProtocol(String queryProtocols, URL url) {
|
||||
String protocol = url.getProtocol();
|
||||
if (StringUtils.isNotEmpty(queryProtocols)) {
|
||||
String[] acceptProtocols = queryProtocols.split(COMMA_SEPARATOR);
|
||||
String acceptedProtocol = acceptProtocols[0];
|
||||
if (!acceptedProtocol.equals(url.getProtocol())) {
|
||||
String extProtocols = url.getParameter(EXT_PROTOCOL);
|
||||
if (StringUtils.isNotEmpty(extProtocols)) {
|
||||
String[] extProtocolsArr = extProtocols.split(COMMA_SEPARATOR);
|
||||
for (String p : extProtocolsArr) {
|
||||
if (p.equalsIgnoreCase(acceptedProtocol)) {
|
||||
protocol = acceptedProtocol;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return protocol;
|
||||
}
|
||||
|
||||
private boolean checkProtocolValid(String queryProtocols, URL providerUrl) {
|
||||
// If protocol is configured at the reference side, only the matching protocol is selected
|
||||
if (queryProtocols != null && queryProtocols.length() > 0) {
|
||||
|
|
|
|||
|
|
@ -36,8 +36,9 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_NOTIFY_EVENT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.IS_EXTRA;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_FAILED_NOTIFY_EVENT;
|
||||
import static org.apache.dubbo.registry.Constants.DEFAULT_REGISTRY_RETRY_PERIOD;
|
||||
import static org.apache.dubbo.registry.Constants.REGISTRY_RETRY_PERIOD_KEY;
|
||||
|
||||
|
|
@ -195,8 +196,7 @@ public abstract class FailbackRegistry extends AbstractRegistry {
|
|||
|
||||
@Override
|
||||
public void register(URL url) {
|
||||
if (!acceptable(url)) {
|
||||
logger.info("URL " + url + " will not be registered to Registry. Registry " + this.getUrl() + " does not accept service of this protocol type.");
|
||||
if (!shouldRegister(url)) {
|
||||
return;
|
||||
}
|
||||
super.register(url);
|
||||
|
|
@ -227,6 +227,18 @@ public abstract class FailbackRegistry extends AbstractRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
protected boolean shouldRegister(URL providerURL) {
|
||||
// extra protocol url must not be registered for interface based service discovery
|
||||
if (providerURL.getParameter(IS_EXTRA, false)) {
|
||||
return false;
|
||||
}
|
||||
if (!acceptable(providerURL)) {
|
||||
logger.info("URL " + providerURL + " will not be registered to Registry. Registry " + this.getUrl() + " does not accept service of this protocol type.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reExportRegister(URL url) {
|
||||
if (!acceptable(url)) {
|
||||
|
|
|
|||
|
|
@ -17,15 +17,22 @@
|
|||
package org.apache.dubbo.remoting.api.pu;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.remoting.ChannelHandler;
|
||||
import org.apache.dubbo.remoting.RemotingException;
|
||||
import org.apache.dubbo.remoting.api.WireProtocol;
|
||||
import org.apache.dubbo.remoting.transport.AbstractServer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;
|
||||
|
||||
public abstract class AbstractPortUnificationServer extends AbstractServer {
|
||||
private final List<WireProtocol> protocols;
|
||||
|
||||
|
|
@ -44,7 +51,18 @@ public abstract class AbstractPortUnificationServer extends AbstractServer {
|
|||
|
||||
public AbstractPortUnificationServer(URL url, ChannelHandler handler) throws RemotingException {
|
||||
super(url, handler);
|
||||
this.protocols = url.getOrDefaultFrameworkModel().getExtensionLoader(WireProtocol.class).getActivateExtension(url, new String[0]);
|
||||
ExtensionLoader<WireProtocol> loader = url.getOrDefaultFrameworkModel().getExtensionLoader(WireProtocol.class);
|
||||
List<WireProtocol> extProtocols = new ArrayList<>();
|
||||
// load main protocol
|
||||
extProtocols.add(loader.getExtension(url.getProtocol()));
|
||||
// load extra protocols
|
||||
String extraProtocols = url.getParameter(EXT_PROTOCOL);
|
||||
if (StringUtils.isNotEmpty(extraProtocols)) {
|
||||
Arrays.stream(extraProtocols.split(COMMA_SEPARATOR)).forEach(p -> {
|
||||
extProtocols.add(loader.getExtension(p));
|
||||
});
|
||||
}
|
||||
this.protocols = extProtocols;
|
||||
}
|
||||
|
||||
public List<WireProtocol> getProtocols() {
|
||||
|
|
|
|||
|
|
@ -18,25 +18,43 @@ package org.apache.dubbo.remoting.transport.netty4;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.ExtensionDirector;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.threadpool.manager.DefaultExecutorRepository;
|
||||
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.context.ModuleConfigManager;
|
||||
import org.apache.dubbo.remoting.Channel;
|
||||
import org.apache.dubbo.remoting.RemotingException;
|
||||
import org.apache.dubbo.remoting.api.ProtocolDetector;
|
||||
import org.apache.dubbo.remoting.api.WireProtocol;
|
||||
import org.apache.dubbo.remoting.api.pu.AbstractPortUnificationServer;
|
||||
import org.apache.dubbo.remoting.api.pu.ChannelOperator;
|
||||
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
||||
|
||||
import org.apache.dubbo.remoting.api.ssl.ContextOperator;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_DEFAULT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;
|
||||
|
||||
class PortUnificationServerTest {
|
||||
|
||||
@Test
|
||||
void testBind() throws RemotingException {
|
||||
int port = NetUtils.getAvailablePort();
|
||||
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar&" + EXT_PROTOCOL + "=tri");
|
||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig("provider-app");
|
||||
applicationConfig.setExecutorManagementMode(EXECUTOR_MANAGEMENT_MODE_DEFAULT);
|
||||
|
|
@ -52,6 +70,7 @@ class PortUnificationServerTest {
|
|||
final NettyPortUnificationServer server = new NettyPortUnificationServer(url, new DefaultPuHandler());
|
||||
server.bind();
|
||||
Assertions.assertTrue(server.isBound());
|
||||
Assertions.assertEquals(2, server.getProtocols().size());
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@
|
|||
<artifactId>dubbo-config-spring</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-config-spring6</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.apache.dubbo</groupId>-->
|
||||
<!-- <artifactId>dubbo-config-spring6</artifactId>-->
|
||||
<!-- <version>${project.version}</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- config-center -->
|
||||
<dependency>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ class FileTest {
|
|||
ignoredModules.add(Pattern.compile("dubbo-parent"));
|
||||
ignoredModules.add(Pattern.compile("dubbo-core-spi"));
|
||||
ignoredModules.add(Pattern.compile("dubbo-demo.*"));
|
||||
ignoredModules.add(Pattern.compile("dubbo-annotation-processor"));
|
||||
ignoredModules.add(Pattern.compile("dubbo-config-spring6"));
|
||||
|
||||
ignoredArtifacts.add(Pattern.compile("dubbo-demo.*"));
|
||||
ignoredArtifacts.add(Pattern.compile("dubbo-test.*"));
|
||||
|
|
|
|||
Loading…
Reference in New Issue