Split DefaultConfigValidator to SPI implements (#12948)
* * Simplify responsibilities of ConfigValidationUtils * * Update validators * * Bug fix * * Bug fix * Add ut * * Add license * * Rename folder * * Fix pom & name * * Code style fix * * Bug fix * * Bug fix * * Update validator init process * * Refactor ConfigValidateFacade init method * * Bug fix * Add license * * Fix test * * Fix ut * * Update ConfigValidateFacade init process * * Bug fix * * Bug fix * * Bug fix * * Doc fix * * Bug fix * * Bug fix * * Bug fix * * Bug fix * * Bug fix * * Test fix * * refactor validator mapping * * Code style fix * * Fix conflict * * Fix conflict * * Remove default instance of ConfigValidateFacade * * Remove default instance of ConfigValidateFacade * * Add license
This commit is contained in:
parent
a6a6d57dd7
commit
98e7313e71
|
|
@ -337,6 +337,8 @@ public interface CommonConstants {
|
|||
|
||||
String REGISTRY_PROTOCOL_LISTENER_KEY = "registry.protocol.listener";
|
||||
|
||||
String REGISTRY_SERVICE_CLASS_NAME = "org.apache.dubbo.registry.RegistryService";
|
||||
|
||||
String DUBBO_VERSION_KEY = "dubbo";
|
||||
|
||||
String TAG_KEY = "dubbo.tag";
|
||||
|
|
|
|||
|
|
@ -172,6 +172,13 @@ public abstract class AbstractConfig implements Serializable {
|
|||
appendParameters0(parameters, config, prefix, false);
|
||||
}
|
||||
|
||||
public boolean validate() {
|
||||
if(scopeModel == null || scopeModel.getBeanFactory() == null || scopeModel.getBeanFactory().isDestroyed()){
|
||||
return ConfigValidateFacade.getDefaultInstance().validate(this);
|
||||
}
|
||||
return scopeModel.getBeanFactory().getOrRegisterBean(ConfigValidateFacade.class,clz -> new ConfigValidateFacade(scopeModel)).validate(this);
|
||||
}
|
||||
|
||||
private static void appendParameters0(Map<String, String> parameters, Object config, String prefix, boolean asParameters) {
|
||||
if (config == null) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.exception.ConfigValidationException;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class ConfigValidateFacade implements ConfigValidator{
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getErrorTypeAwareLogger(ConfigValidateFacade.class);
|
||||
|
||||
private final List<ConfigValidator> validators;
|
||||
|
||||
/**
|
||||
* For test
|
||||
*/
|
||||
private static boolean enableValidate = true;
|
||||
|
||||
public ConfigValidateFacade(ScopeModel scopeModel) {
|
||||
if(scopeModel != null) {
|
||||
ExtensionLoader<ConfigValidator> extensionLoader = scopeModel.getExtensionLoader(ConfigValidator.class);
|
||||
if (extensionLoader != null) {
|
||||
this.validators = extensionLoader.getActivateExtensions();
|
||||
this.validators.forEach(scopeModel.getBeanFactory()::registerBean);
|
||||
} else {
|
||||
this.validators = Collections.emptyList();
|
||||
}
|
||||
}else {
|
||||
this.validators = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<ConfigValidator> getValidators() {
|
||||
return validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto choose a appropriate validator to validate config.
|
||||
*
|
||||
* @param config the config to validate
|
||||
* @return TRUE if pass the validation.
|
||||
* FALSE if no ConfigValidator found for this config,
|
||||
* or one of the supported {@link ConfigValidator#validate(AbstractConfig)} returns FALSE.
|
||||
*/
|
||||
@Override
|
||||
public boolean validate(AbstractConfig config) throws ConfigValidationException{
|
||||
if(!enableValidate){
|
||||
return true;
|
||||
}
|
||||
if (config == null) {
|
||||
return false;
|
||||
}
|
||||
boolean validated = false;
|
||||
try {
|
||||
for (ConfigValidator validator : validators) {
|
||||
if (validator.isSupport(config.getClass())) {
|
||||
validated = true;
|
||||
if(!validator.validate(config)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (Throwable t){
|
||||
throw new ConfigValidationException(config.getClass().getSimpleName()+" validation failed: "+t.getMessage(),t);
|
||||
}
|
||||
if (!validated) {
|
||||
LOGGER.info(config.getClass().getSimpleName()+" is not validated. This may caused by you did not imported the relevant module.");
|
||||
}
|
||||
return validated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class configClass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* For test
|
||||
*/
|
||||
@Deprecated
|
||||
public static ConfigValidateFacade getDefaultInstance() {
|
||||
return ApplicationModel.defaultModel().getBeanFactory().getOrRegisterBean(ConfigValidateFacade.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* For test
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setEnableValidate(boolean enable){
|
||||
enableValidate = enable;
|
||||
}
|
||||
}
|
||||
|
|
@ -31,6 +31,7 @@ import org.apache.dubbo.common.utils.StringUtils;
|
|||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ConfigKeys;
|
||||
import org.apache.dubbo.config.ConfigValidateFacade;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.ModuleConfig;
|
||||
|
|
@ -585,10 +586,8 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
|
||||
// validate configs
|
||||
Collection<T> configs = this.getConfigs(configType);
|
||||
if (getConfigValidator() != null) {
|
||||
for (T config : configs) {
|
||||
getConfigValidator().validate(config);
|
||||
}
|
||||
for (T config : configs) {
|
||||
getConfigValidator().validate(config);
|
||||
}
|
||||
|
||||
// check required default
|
||||
|
|
@ -611,11 +610,11 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
|
|||
return true;
|
||||
}
|
||||
|
||||
private ConfigValidator getConfigValidator() {
|
||||
private ConfigValidateFacade getConfigValidator() {
|
||||
if (configValidator == null) {
|
||||
configValidator = applicationModel.getBeanFactory().getBean(ConfigValidator.class);
|
||||
configValidator = applicationModel.getBeanFactory().getOrRegisterBean(ConfigValidateFacade.class, clz -> new ConfigValidateFacade(scopeModel));
|
||||
}
|
||||
return configValidator;
|
||||
return (ConfigValidateFacade) configValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -16,10 +16,26 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.context;
|
||||
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.exception.ConfigValidationException;
|
||||
|
||||
public interface ConfigValidator {
|
||||
/**
|
||||
* ConfigValidator. Allow provides an optional validation logic for a {@link AbstractConfig} impl.
|
||||
* @param <T> type of {@link AbstractConfig} implement
|
||||
*/
|
||||
@SPI
|
||||
public interface ConfigValidator<T extends AbstractConfig> {
|
||||
|
||||
void validate(AbstractConfig config);
|
||||
/**
|
||||
* Validate a config.
|
||||
* If the config does not pass validation, returns false or throws exception, depends on implementation.
|
||||
*
|
||||
* @param config the config to validate
|
||||
* @return TRUE if pass validation
|
||||
*/
|
||||
boolean validate(T config) throws ConfigValidationException;
|
||||
|
||||
boolean isSupport(Class<?> configClass);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.exception;
|
||||
|
||||
/**
|
||||
* Config validation exception
|
||||
*/
|
||||
public class ConfigValidationException extends RuntimeException {
|
||||
|
||||
public ConfigValidationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ConfigValidationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ConfigValidationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ConfigValidationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* 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.utils;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.URLBuilder;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.AbstractInterfaceConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.registry.Constants;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_SERVICE_CLASS_NAME;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REMOVE_VALUE_PREFIX;
|
||||
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;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_REGISTER_MODE_INTERFACE;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DUBBO_REGISTER_MODE_DEFAULT_KEY;
|
||||
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
|
||||
import static org.apache.dubbo.config.Constants.IGNORE_CHECK_KEYS;
|
||||
import static org.apache.dubbo.config.Constants.REGISTER_KEY;
|
||||
|
||||
public class ConfigValidationUtils {
|
||||
public static final String IPV6_START_MARK = "[";
|
||||
public static final String IPV6_END_MARK = "]";
|
||||
/**
|
||||
* The maximum length of a <b>parameter's value</b>
|
||||
*/
|
||||
private static final int MAX_LENGTH = 200;
|
||||
/**
|
||||
* The maximum length of a <b>path</b>
|
||||
*/
|
||||
private static final int MAX_PATH_LENGTH = 200;
|
||||
/**
|
||||
* The rule qualification for <b>name</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_NAME = Pattern.compile("[\\-._0-9a-zA-Z]+");
|
||||
/**
|
||||
* The rule qualification for <b>multiply name</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_MULTI_NAME = Pattern.compile("[,\\-._0-9a-zA-Z]+");
|
||||
/**
|
||||
* The rule qualification for <b>method names</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_METHOD_NAME = Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
|
||||
/**
|
||||
* The rule qualification for <b>path</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_PATH = Pattern.compile("[/\\-$._0-9a-zA-Z]+");
|
||||
/**
|
||||
* The pattern matches a value who has a symbol
|
||||
*/
|
||||
private static final Pattern PATTERN_NAME_HAS_SYMBOL = Pattern.compile("[:*,\\s/\\-._0-9a-zA-Z]+");
|
||||
/**
|
||||
* The pattern matches a property key
|
||||
*/
|
||||
private static final Pattern PATTERN_KEY = Pattern.compile("[*,\\-._0-9a-zA-Z]+");
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ConfigValidationUtils.class);
|
||||
|
||||
public static List<URL> loadRegistries(AbstractInterfaceConfig interfaceConfig, boolean provider) {
|
||||
// check && override if necessary
|
||||
List<URL> registryList = new ArrayList<>();
|
||||
ApplicationConfig application = interfaceConfig.getApplication();
|
||||
List<RegistryConfig> registries = interfaceConfig.getRegistries();
|
||||
if (CollectionUtils.isNotEmpty(registries)) {
|
||||
for (RegistryConfig config : registries) {
|
||||
// try to refresh registry in case it is set directly by user using config.setRegistries()
|
||||
if (!config.isRefreshed()) {
|
||||
config.refresh();
|
||||
}
|
||||
String address = config.getAddress();
|
||||
if (StringUtils.isEmpty(address)) {
|
||||
address = ANYHOST_VALUE;
|
||||
}
|
||||
if (!RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
AbstractConfig.appendParameters(map, application);
|
||||
AbstractConfig.appendParameters(map, config);
|
||||
map.put(PATH_KEY,REGISTRY_SERVICE_CLASS_NAME);
|
||||
AbstractInterfaceConfig.appendRuntimeParameters(map);
|
||||
if (!map.containsKey(PROTOCOL_KEY)) {
|
||||
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
|
||||
}
|
||||
List<URL> urls = UrlUtils.parseURLs(address, map);
|
||||
|
||||
for (URL url : urls) {
|
||||
url = URLBuilder.from(url)
|
||||
.addParameter(REGISTRY_KEY, url.getProtocol())
|
||||
.setProtocol(extractRegistryType(url))
|
||||
.setScopeModel(interfaceConfig.getScopeModel())
|
||||
.build();
|
||||
// provider delay register state will be checked in RegistryProtocol#export
|
||||
if (provider && url.getParameter(REGISTER_KEY, true)) {
|
||||
registryList.add(url);
|
||||
}
|
||||
if (!provider && url.getParameter(Constants.SUBSCRIBE_KEY, true)) {
|
||||
registryList.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return genCompatibleRegistries(interfaceConfig.getScopeModel(), registryList, provider);
|
||||
}
|
||||
|
||||
private static List<URL> genCompatibleRegistries(ScopeModel scopeModel, List<URL> registryList, boolean provider) {
|
||||
List<URL> result = new ArrayList<>(registryList.size());
|
||||
registryList.forEach(registryURL -> {
|
||||
if (provider) {
|
||||
// for registries enabled service discovery, automatically register interface compatible addresses.
|
||||
String registerMode;
|
||||
if (SERVICE_REGISTRY_PROTOCOL.equals(registryURL.getProtocol())) {
|
||||
registerMode = registryURL.getParameter(REGISTER_MODE_KEY, ConfigurationUtils.getCachedDynamicProperty(scopeModel, DUBBO_REGISTER_MODE_DEFAULT_KEY, DEFAULT_REGISTER_MODE_INSTANCE));
|
||||
if (!isValidRegisterMode(registerMode)) {
|
||||
registerMode = DEFAULT_REGISTER_MODE_INSTANCE;
|
||||
}
|
||||
result.add(registryURL);
|
||||
if (DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode)
|
||||
&& registryNotExists(registryURL, registryList, REGISTRY_PROTOCOL)) {
|
||||
URL interfaceCompatibleRegistryURL = URLBuilder.from(registryURL)
|
||||
.setProtocol(REGISTRY_PROTOCOL)
|
||||
.removeParameter(REGISTRY_TYPE_KEY)
|
||||
.build();
|
||||
result.add(interfaceCompatibleRegistryURL);
|
||||
}
|
||||
} else {
|
||||
registerMode = registryURL.getParameter(REGISTER_MODE_KEY, ConfigurationUtils.getCachedDynamicProperty(scopeModel, DUBBO_REGISTER_MODE_DEFAULT_KEY, DEFAULT_REGISTER_MODE_ALL));
|
||||
if (!isValidRegisterMode(registerMode)) {
|
||||
registerMode = DEFAULT_REGISTER_MODE_INTERFACE;
|
||||
}
|
||||
if ((DEFAULT_REGISTER_MODE_INSTANCE.equalsIgnoreCase(registerMode) || DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode))
|
||||
&& registryNotExists(registryURL, registryList, SERVICE_REGISTRY_PROTOCOL)) {
|
||||
URL serviceDiscoveryRegistryURL = URLBuilder.from(registryURL)
|
||||
.setProtocol(SERVICE_REGISTRY_PROTOCOL)
|
||||
.removeParameter(REGISTRY_TYPE_KEY)
|
||||
.build();
|
||||
result.add(serviceDiscoveryRegistryURL);
|
||||
}
|
||||
|
||||
if (DEFAULT_REGISTER_MODE_INTERFACE.equalsIgnoreCase(registerMode) || DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode)) {
|
||||
result.add(registryURL);
|
||||
}
|
||||
}
|
||||
|
||||
FrameworkStatusReportService reportService = ScopeModelUtil.getApplicationModel(scopeModel).getBeanFactory().getBean(FrameworkStatusReportService.class);
|
||||
reportService.reportRegistrationStatus(reportService.createRegistrationReport(registerMode));
|
||||
} else {
|
||||
result.add(registryURL);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isValidRegisterMode(String mode) {
|
||||
return isNotEmpty(mode)
|
||||
&& (DEFAULT_REGISTER_MODE_INTERFACE.equalsIgnoreCase(mode)
|
||||
|| DEFAULT_REGISTER_MODE_INSTANCE.equalsIgnoreCase(mode)
|
||||
|| DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(mode)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean registryNotExists(URL registryURL, List<URL> registryList, String registryType) {
|
||||
return registryList.stream().noneMatch(
|
||||
url -> registryType.equals(url.getProtocol()) && registryURL.getBackupAddress().equals(url.getBackupAddress())
|
||||
);
|
||||
}
|
||||
|
||||
private static String extractRegistryType(URL url) {
|
||||
return UrlUtils.hasServiceDiscoveryRegistryTypeKey(url) ? SERVICE_REGISTRY_PROTOCOL : getRegistryProtocolType(url);
|
||||
}
|
||||
|
||||
private static String getRegistryProtocolType(URL url) {
|
||||
String registryProtocol = url.getParameter("registry-protocol-type");
|
||||
return isNotEmpty(registryProtocol) ? registryProtocol : REGISTRY_PROTOCOL;
|
||||
}
|
||||
|
||||
public static void checkExtension(ScopeModel scopeModel, Class<?> type, String property, String value) {
|
||||
checkName(property, value);
|
||||
if (isNotEmpty(value)
|
||||
&& !scopeModel.getExtensionLoader(type).hasExtension(value)) {
|
||||
throw new IllegalStateException("No such extension " + value + " for " + property + "/" + type.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is a <code>Extension</code> who's name (property) is <code>value</code> (special treatment is
|
||||
* required)
|
||||
*
|
||||
* @param type The Extension type
|
||||
* @param property The extension key
|
||||
* @param value The Extension name
|
||||
*/
|
||||
public static void checkMultiExtension(ScopeModel scopeModel, Class<?> type, String property, String value) {
|
||||
checkMultiExtension(scopeModel, Collections.singletonList(type), property, value);
|
||||
}
|
||||
|
||||
public static void checkMultiExtension(ScopeModel scopeModel, List<Class<?>> types, String property, String value) {
|
||||
checkMultiName(property, value);
|
||||
if (isNotEmpty(value)) {
|
||||
String[] values = value.split("\\s*[,]+\\s*");
|
||||
for (String v : values) {
|
||||
v = StringUtils.trim(v);
|
||||
if (v.startsWith(REMOVE_VALUE_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
if (DEFAULT_KEY.equals(v)) {
|
||||
continue;
|
||||
}
|
||||
boolean match = false;
|
||||
for (Class<?> type : types) {
|
||||
if (scopeModel.getExtensionLoader(type).hasExtension(v)) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
throw new IllegalStateException("No such extension " + v + " for " + property + "/" +
|
||||
types.stream().map(Class::getName).collect(Collectors.joining(",")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkLength(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, null);
|
||||
}
|
||||
|
||||
public static void checkPathLength(String property, String value) {
|
||||
checkProperty(property, value, MAX_PATH_LENGTH, null);
|
||||
}
|
||||
|
||||
public static void checkName(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_NAME);
|
||||
}
|
||||
|
||||
public static void checkHost(String property, String value) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
if (value.startsWith(IPV6_START_MARK) && value.endsWith(IPV6_END_MARK)) {
|
||||
// if the value start with "[" and end with "]", check whether it is IPV6
|
||||
try {
|
||||
InetAddress.getByName(value);
|
||||
return;
|
||||
} catch (UnknownHostException e) {
|
||||
// not a IPv6 string, do nothing, go on to checkName
|
||||
}
|
||||
}
|
||||
checkName(property, value);
|
||||
}
|
||||
|
||||
public static void checkNameHasSymbol(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_NAME_HAS_SYMBOL);
|
||||
}
|
||||
|
||||
public static void checkKey(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_KEY);
|
||||
}
|
||||
|
||||
public static void checkMultiName(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_MULTI_NAME);
|
||||
}
|
||||
|
||||
public static void checkPathName(String property, String value) {
|
||||
checkProperty(property, value, MAX_PATH_LENGTH, PATTERN_PATH);
|
||||
}
|
||||
|
||||
public static void checkMethodName(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_METHOD_NAME);
|
||||
}
|
||||
|
||||
public static void checkParameterName(Map<String, String> parameters) {
|
||||
if (CollectionUtils.isEmptyMap(parameters)) {
|
||||
return;
|
||||
}
|
||||
List<String> ignoreCheckKeys = new ArrayList<>();
|
||||
ignoreCheckKeys.add(BACKUP_KEY);
|
||||
String ignoreCheckKeysStr = parameters.get(IGNORE_CHECK_KEYS);
|
||||
if (!StringUtils.isBlank(ignoreCheckKeysStr)) {
|
||||
ignoreCheckKeys.addAll(Arrays.asList(ignoreCheckKeysStr.split(",")));
|
||||
}
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
if (!ignoreCheckKeys.contains(entry.getKey())) {
|
||||
checkNameHasSymbol(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkProperty(String property, String value, int maxlength, Pattern pattern) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
if (value.length() > maxlength) {
|
||||
logger.error(CONFIG_PARAMETER_FORMAT_ERROR, "the value content is too long", "", "Parameter value format error. Invalid " +
|
||||
property + "=\"" + value + "\" is longer than " + maxlength);
|
||||
}
|
||||
if (pattern != null) {
|
||||
Matcher matcher = pattern.matcher(value);
|
||||
if (!matcher.matches()) {
|
||||
logger.error(CONFIG_PARAMETER_FORMAT_ERROR, "the value content is illegal character", "", "Parameter value format error. Invalid " +
|
||||
property + "=\"" + value + "\" contains illegal " +
|
||||
"character, only digit, letter, '-', '_' or '.' is legal.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.config.PropertiesConfiguration;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.exception.ConfigValidationException;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CLASS_NOT_FOUND;
|
||||
import static org.apache.dubbo.config.Constants.ARCHITECTURE;
|
||||
import static org.apache.dubbo.config.Constants.ENVIRONMENT;
|
||||
import static org.apache.dubbo.config.Constants.NAME;
|
||||
import static org.apache.dubbo.config.Constants.ORGANIZATION;
|
||||
import static org.apache.dubbo.config.Constants.OWNER;
|
||||
|
||||
@Activate
|
||||
public class ApplicationConfigValidator implements ConfigValidator<ApplicationConfig> {
|
||||
|
||||
private static ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ApplicationConfigValidator.class);
|
||||
|
||||
public static void validateApplicationConfig(ApplicationConfig config) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.isValid()) {
|
||||
throw new ConfigValidationException("No application config found or it's not a valid config! " +
|
||||
"Please add <dubbo:application name=\"...\" /> to your spring config.");
|
||||
}
|
||||
|
||||
// backward compatibility
|
||||
ScopeModel scopeModel = ScopeModelUtil.getOrDefaultApplicationModel(config.getScopeModel());
|
||||
PropertiesConfiguration configuration = scopeModel.modelEnvironment().getPropertiesConfiguration();
|
||||
String wait = configuration.getProperty(SHUTDOWN_WAIT_KEY);
|
||||
if (wait != null && wait.trim().length() > 0) {
|
||||
System.setProperty(SHUTDOWN_WAIT_KEY, wait.trim());
|
||||
} else {
|
||||
wait = configuration.getProperty(SHUTDOWN_WAIT_SECONDS_KEY);
|
||||
if (wait != null && wait.trim().length() > 0) {
|
||||
System.setProperty(SHUTDOWN_WAIT_SECONDS_KEY, wait.trim());
|
||||
}
|
||||
}
|
||||
|
||||
ConfigValidationUtils.checkName(NAME, config.getName());
|
||||
ConfigValidationUtils.checkMultiName(OWNER, config.getOwner());
|
||||
ConfigValidationUtils.checkName(ORGANIZATION, config.getOrganization());
|
||||
ConfigValidationUtils.checkName(ARCHITECTURE, config.getArchitecture());
|
||||
ConfigValidationUtils.checkName(ENVIRONMENT, config.getEnvironment());
|
||||
ConfigValidationUtils.checkParameterName(config.getParameters());
|
||||
checkQosDependency(config);
|
||||
}
|
||||
|
||||
public static void checkQosDependency(ApplicationConfig config) {
|
||||
if (!Boolean.FALSE.equals(config.getQosEnable())) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(ApplicationConfig config) {
|
||||
validateApplicationConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ApplicationConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.ModuleConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
|
||||
import static org.apache.dubbo.config.Constants.NAME;
|
||||
import static org.apache.dubbo.config.Constants.ORGANIZATION;
|
||||
import static org.apache.dubbo.config.Constants.OWNER;
|
||||
|
||||
@Activate
|
||||
public class ModuleConfigValidator implements ConfigValidator<ModuleConfig> {
|
||||
|
||||
@Override
|
||||
public boolean validate(ModuleConfig config) {
|
||||
validateModuleConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void validateModuleConfig(ModuleConfig config) {
|
||||
if (config != null) {
|
||||
ConfigValidationUtils.checkName(NAME, config.getName());
|
||||
ConfigValidationUtils.checkName(OWNER, config.getOwner());
|
||||
ConfigValidationUtils.checkName(ORGANIZATION, config.getOrganization());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ModuleConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
application=org.apache.dubbo.config.validator.ApplicationConfigValidator
|
||||
module=org.apache.dubbo.config.validator.ModuleConfigValidator
|
||||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.config.context;
|
|||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ConfigCenterConfig;
|
||||
import org.apache.dubbo.config.ConfigValidateFacade;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.ModuleConfig;
|
||||
|
|
@ -64,6 +65,7 @@ class ConfigManagerTest {
|
|||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||
configManager = applicationModel.getApplicationConfigManager();
|
||||
moduleConfigManager = applicationModel.getDefaultModule().getConfigManager();
|
||||
ConfigValidateFacade.setEnableValidate(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import org.apache.dubbo.common.deploy.ModuleDeployer;
|
|||
import org.apache.dubbo.config.deploy.DefaultApplicationDeployer;
|
||||
import org.apache.dubbo.config.deploy.DefaultModuleDeployer;
|
||||
import org.apache.dubbo.config.deploy.FrameworkModelCleaner;
|
||||
import org.apache.dubbo.config.utils.DefaultConfigValidator;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
|
@ -38,11 +37,9 @@ public class ConfigScopeModelInitializer implements ScopeModelInitializer {
|
|||
@Override
|
||||
public void initializeApplicationModel(ApplicationModel applicationModel) {
|
||||
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
|
||||
beanFactory.registerBean(DefaultConfigValidator.class);
|
||||
// applicationDeployer
|
||||
ApplicationDeployer applicationDeployer = beanFactory.registerBean(DefaultApplicationDeployer.class);
|
||||
applicationModel.setDeployer(applicationDeployer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
|
|||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.apache.dubbo.rpc.stub.StubSuppliers;
|
||||
import org.apache.dubbo.rpc.support.ProtocolUtils;
|
||||
import org.apache.dubbo.util.MonitorUrlUtil;
|
||||
|
||||
import java.beans.Transient;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -179,7 +180,6 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
@Override
|
||||
protected void postProcessAfterScopeModelChanged(ScopeModel oldScopeModel, ScopeModel newScopeModel) {
|
||||
super.postProcessAfterScopeModelChanged(oldScopeModel, newScopeModel);
|
||||
|
||||
protocolSPI = this.getExtensionLoader(Protocol.class).getAdaptiveExtension();
|
||||
proxyFactory = this.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
|
||||
}
|
||||
|
|
@ -579,7 +579,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
List<URL> us = ConfigValidationUtils.loadRegistries(this, false);
|
||||
if (CollectionUtils.isNotEmpty(us)) {
|
||||
for (URL u : us) {
|
||||
URL monitorUrl = ConfigValidationUtils.loadMonitor(this, u);
|
||||
URL monitorUrl = MonitorUrlUtil.loadMonitor(this, u);
|
||||
if (monitorUrl != null) {
|
||||
u = u.putAttribute(MONITOR_KEY, monitorUrl);
|
||||
}
|
||||
|
|
@ -746,7 +746,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
}
|
||||
|
||||
resolveFile();
|
||||
ConfigValidationUtils.validateReferenceConfig(this);
|
||||
validate();
|
||||
postProcessConfig();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import org.apache.dubbo.rpc.model.ProviderModel;
|
|||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ServiceDescriptor;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.apache.dubbo.util.MonitorUrlUtil;
|
||||
|
||||
import java.beans.Transient;
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -468,7 +469,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
}
|
||||
checkStubAndLocal(interfaceClass);
|
||||
ConfigValidationUtils.validateServiceConfig(this);
|
||||
validate();
|
||||
postProcessConfig();
|
||||
}
|
||||
|
||||
|
|
@ -805,7 +806,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
|
||||
url = url.addParameterIfAbsent(DYNAMIC_KEY, registryURL.getParameter(DYNAMIC_KEY));
|
||||
URL monitorUrl = ConfigValidationUtils.loadMonitor(this, registryURL);
|
||||
URL monitorUrl = MonitorUrlUtil.loadMonitor(this, registryURL);
|
||||
if (monitorUrl != null) {
|
||||
url = url.putAttribute(MONITOR_KEY, monitorUrl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.deploy.lifecycle.application;
|
||||
|
||||
import org.apache.dubbo.common.deploy.ApplicationDeployListener;
|
||||
import org.apache.dubbo.common.deploy.DeployState;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
import org.apache.dubbo.config.deploy.context.ApplicationContext;
|
||||
|
|
@ -27,6 +28,8 @@ import org.apache.dubbo.rpc.model.ModuleModel;
|
|||
* <br>
|
||||
* Used in an application Lifecycle managing procedure, and dubbo packages
|
||||
* can implement this interface to define what to do when application status changes.
|
||||
* <p>
|
||||
* Note: If you want to auto registry some extensions to BeanFactory, use {@link ApplicationDeployListener} instead.
|
||||
* <br>
|
||||
*/
|
||||
@SPI
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import org.apache.dubbo.config.ConfigCenterConfig;
|
|||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.deploy.context.ApplicationContext;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.metrics.config.event.ConfigCenterEvent;
|
||||
import org.apache.dubbo.metrics.event.MetricsEventBus;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
|
@ -85,7 +84,7 @@ public class ConfigCenterApplicationLifecycle implements ApplicationLifecycle {
|
|||
ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
|
||||
configCenterConfig.setScopeModel(applicationModel);
|
||||
configCenterConfig.refresh();
|
||||
ConfigValidationUtils.validateConfigCenterConfig(configCenterConfig);
|
||||
configCenterConfig.validate();
|
||||
if (configCenterConfig.isValid()) {
|
||||
configManager.addConfigCenter(configCenterConfig);
|
||||
configCenters = configManager.getConfigCenters();
|
||||
|
|
@ -93,7 +92,7 @@ public class ConfigCenterApplicationLifecycle implements ApplicationLifecycle {
|
|||
} else {
|
||||
for (ConfigCenterConfig configCenterConfig : configCenters) {
|
||||
configCenterConfig.refresh();
|
||||
ConfigValidationUtils.validateConfigCenterConfig(configCenterConfig);
|
||||
configCenterConfig.validate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import org.apache.dubbo.config.MetadataReportConfig;
|
|||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.deploy.context.ApplicationContext;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.metadata.report.MetadataReportFactory;
|
||||
import org.apache.dubbo.metadata.report.MetadataReportInstance;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
|
@ -91,8 +90,7 @@ public class MetadataInitializeLifecycle implements ApplicationLifecycle {
|
|||
List<MetadataReportConfig> validMetadataReportConfigs = new ArrayList<>(metadataReportConfigs.size());
|
||||
|
||||
for (MetadataReportConfig metadataReportConfig : metadataReportConfigs) {
|
||||
if (ConfigValidationUtils.isValidMetadataConfig(metadataReportConfig)) {
|
||||
ConfigValidationUtils.validateMetadataConfig(metadataReportConfig);
|
||||
if (metadataReportConfig.validate()) {
|
||||
validMetadataReportConfigs.add(metadataReportConfig);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.deploy.lifecycle.application;
|
||||
|
||||
import org.apache.dubbo.common.deploy.ApplicationDeployListener;
|
||||
import org.apache.dubbo.config.ConfigValidateFacade;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
public class ValidatorRegistryDeployListener implements ApplicationDeployListener {
|
||||
|
||||
@Override
|
||||
public void onStarting(ApplicationModel scopeModel) {
|
||||
ConfigValidateFacade validateFacade = new ConfigValidateFacade(scopeModel);
|
||||
scopeModel.getBeanFactory().registerBean(validateFacade);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize(ApplicationModel scopeModel) {}
|
||||
@Override
|
||||
public void onStarted(ApplicationModel scopeModel) {}
|
||||
@Override
|
||||
public void onStopping(ApplicationModel scopeModel) {}
|
||||
@Override
|
||||
public void onStopped(ApplicationModel scopeModel) {}
|
||||
@Override
|
||||
public void onFailure(ApplicationModel scopeModel, Throwable cause) {}
|
||||
}
|
||||
|
|
@ -1,741 +0,0 @@
|
|||
/*
|
||||
* 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.utils;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.URLBuilder;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.config.PropertiesConfiguration;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.serialize.Serialization;
|
||||
import org.apache.dubbo.common.status.StatusChecker;
|
||||
import org.apache.dubbo.common.status.reporter.FrameworkStatusReportService;
|
||||
import org.apache.dubbo.common.threadpool.ThreadPool;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.AbstractInterfaceConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ConfigCenterConfig;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.MethodConfig;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.ModuleConfig;
|
||||
import org.apache.dubbo.config.MonitorConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.monitor.MonitorFactory;
|
||||
import org.apache.dubbo.monitor.MonitorService;
|
||||
import org.apache.dubbo.registry.RegistryService;
|
||||
import org.apache.dubbo.remoting.Codec2;
|
||||
import org.apache.dubbo.remoting.Dispatcher;
|
||||
import org.apache.dubbo.remoting.Transporter;
|
||||
import org.apache.dubbo.remoting.exchange.Exchanger;
|
||||
import org.apache.dubbo.remoting.telnet.TelnetHandler;
|
||||
import org.apache.dubbo.rpc.ExporterListener;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.InvokerListener;
|
||||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
import org.apache.dubbo.rpc.cluster.Cluster;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_MONITOR_ADDRESS;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.FILE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.FILTER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REMOVE_VALUE_PREFIX;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
|
||||
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;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_REGISTER_MODE_INTERFACE;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DUBBO_REGISTER_MODE_DEFAULT_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
|
||||
import static org.apache.dubbo.config.Constants.ARCHITECTURE;
|
||||
import static org.apache.dubbo.config.Constants.CONTEXTPATH_KEY;
|
||||
import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
|
||||
import static org.apache.dubbo.config.Constants.ENVIRONMENT;
|
||||
import static org.apache.dubbo.config.Constants.IGNORE_CHECK_KEYS;
|
||||
import static org.apache.dubbo.config.Constants.LAYER_KEY;
|
||||
import static org.apache.dubbo.config.Constants.NAME;
|
||||
import static org.apache.dubbo.config.Constants.ORGANIZATION;
|
||||
import static org.apache.dubbo.config.Constants.OWNER;
|
||||
import static org.apache.dubbo.config.Constants.REGISTER_KEY;
|
||||
import static org.apache.dubbo.config.Constants.STATUS_KEY;
|
||||
import static org.apache.dubbo.monitor.Constants.LOGSTAT_PROTOCOL;
|
||||
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
|
||||
import static org.apache.dubbo.registry.Constants.SUBSCRIBE_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.DISPATCHER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.TELNET_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.TRANSPORTER_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.FAIL_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.FORCE_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.PROXY_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
|
||||
|
||||
public class ConfigValidationUtils {
|
||||
private static ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ConfigValidationUtils.class);
|
||||
/**
|
||||
* The maximum length of a <b>parameter's value</b>
|
||||
*/
|
||||
private static final int MAX_LENGTH = 200;
|
||||
|
||||
/**
|
||||
* The maximum length of a <b>path</b>
|
||||
*/
|
||||
private static final int MAX_PATH_LENGTH = 200;
|
||||
|
||||
/**
|
||||
* The rule qualification for <b>name</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_NAME = Pattern.compile("[\\-._0-9a-zA-Z]+");
|
||||
|
||||
/**
|
||||
* The rule qualification for <b>multiply name</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_MULTI_NAME = Pattern.compile("[,\\-._0-9a-zA-Z]+");
|
||||
|
||||
/**
|
||||
* The rule qualification for <b>method names</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_METHOD_NAME = Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
|
||||
|
||||
/**
|
||||
* The rule qualification for <b>path</b>
|
||||
*/
|
||||
private static final Pattern PATTERN_PATH = Pattern.compile("[/\\-$._0-9a-zA-Z]+");
|
||||
|
||||
/**
|
||||
* The pattern matches a value who has a symbol
|
||||
*/
|
||||
private static final Pattern PATTERN_NAME_HAS_SYMBOL = Pattern.compile("[:*,\\s/\\-._0-9a-zA-Z]+");
|
||||
|
||||
/**
|
||||
* The pattern matches a property key
|
||||
*/
|
||||
private static final Pattern PATTERN_KEY = Pattern.compile("[*,\\-._0-9a-zA-Z]+");
|
||||
|
||||
public static final String IPV6_START_MARK = "[";
|
||||
|
||||
public static final String IPV6_END_MARK = "]";
|
||||
|
||||
public static List<URL> loadRegistries(AbstractInterfaceConfig interfaceConfig, boolean provider) {
|
||||
// check && override if necessary
|
||||
List<URL> registryList = new ArrayList<>();
|
||||
ApplicationConfig application = interfaceConfig.getApplication();
|
||||
List<RegistryConfig> registries = interfaceConfig.getRegistries();
|
||||
if (CollectionUtils.isNotEmpty(registries)) {
|
||||
for (RegistryConfig config : registries) {
|
||||
// try to refresh registry in case it is set directly by user using config.setRegistries()
|
||||
if (!config.isRefreshed()) {
|
||||
config.refresh();
|
||||
}
|
||||
String address = config.getAddress();
|
||||
if (StringUtils.isEmpty(address)) {
|
||||
address = ANYHOST_VALUE;
|
||||
}
|
||||
if (!RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
AbstractConfig.appendParameters(map, application);
|
||||
AbstractConfig.appendParameters(map, config);
|
||||
map.put(PATH_KEY, RegistryService.class.getName());
|
||||
AbstractInterfaceConfig.appendRuntimeParameters(map);
|
||||
if (!map.containsKey(PROTOCOL_KEY)) {
|
||||
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
|
||||
}
|
||||
List<URL> urls = UrlUtils.parseURLs(address, map);
|
||||
|
||||
for (URL url : urls) {
|
||||
url = URLBuilder.from(url)
|
||||
.addParameter(REGISTRY_KEY, url.getProtocol())
|
||||
.setProtocol(extractRegistryType(url))
|
||||
.setScopeModel(interfaceConfig.getScopeModel())
|
||||
.build();
|
||||
// provider delay register state will be checked in RegistryProtocol#export
|
||||
if (provider && url.getParameter(REGISTER_KEY, true)) {
|
||||
registryList.add(url);
|
||||
}
|
||||
if (!provider && url.getParameter(SUBSCRIBE_KEY, true)) {
|
||||
registryList.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return genCompatibleRegistries(interfaceConfig.getScopeModel(), registryList, provider);
|
||||
}
|
||||
|
||||
private static List<URL> genCompatibleRegistries(ScopeModel scopeModel, List<URL> registryList, boolean provider) {
|
||||
List<URL> result = new ArrayList<>(registryList.size());
|
||||
registryList.forEach(registryURL -> {
|
||||
if (provider) {
|
||||
// for registries enabled service discovery, automatically register interface compatible addresses.
|
||||
String registerMode;
|
||||
if (SERVICE_REGISTRY_PROTOCOL.equals(registryURL.getProtocol())) {
|
||||
registerMode = registryURL.getParameter(REGISTER_MODE_KEY, ConfigurationUtils.getCachedDynamicProperty(scopeModel, DUBBO_REGISTER_MODE_DEFAULT_KEY, DEFAULT_REGISTER_MODE_INSTANCE));
|
||||
if (!isValidRegisterMode(registerMode)) {
|
||||
registerMode = DEFAULT_REGISTER_MODE_INSTANCE;
|
||||
}
|
||||
result.add(registryURL);
|
||||
if (DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode)
|
||||
&& registryNotExists(registryURL, registryList, REGISTRY_PROTOCOL)) {
|
||||
URL interfaceCompatibleRegistryURL = URLBuilder.from(registryURL)
|
||||
.setProtocol(REGISTRY_PROTOCOL)
|
||||
.removeParameter(REGISTRY_TYPE_KEY)
|
||||
.build();
|
||||
result.add(interfaceCompatibleRegistryURL);
|
||||
}
|
||||
} else {
|
||||
registerMode = registryURL.getParameter(REGISTER_MODE_KEY, ConfigurationUtils.getCachedDynamicProperty(scopeModel, DUBBO_REGISTER_MODE_DEFAULT_KEY, DEFAULT_REGISTER_MODE_ALL));
|
||||
if (!isValidRegisterMode(registerMode)) {
|
||||
registerMode = DEFAULT_REGISTER_MODE_INTERFACE;
|
||||
}
|
||||
if ((DEFAULT_REGISTER_MODE_INSTANCE.equalsIgnoreCase(registerMode) || DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode))
|
||||
&& registryNotExists(registryURL, registryList, SERVICE_REGISTRY_PROTOCOL)) {
|
||||
URL serviceDiscoveryRegistryURL = URLBuilder.from(registryURL)
|
||||
.setProtocol(SERVICE_REGISTRY_PROTOCOL)
|
||||
.removeParameter(REGISTRY_TYPE_KEY)
|
||||
.build();
|
||||
result.add(serviceDiscoveryRegistryURL);
|
||||
}
|
||||
|
||||
if (DEFAULT_REGISTER_MODE_INTERFACE.equalsIgnoreCase(registerMode) || DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(registerMode)) {
|
||||
result.add(registryURL);
|
||||
}
|
||||
}
|
||||
|
||||
FrameworkStatusReportService reportService = ScopeModelUtil.getApplicationModel(scopeModel).getBeanFactory().getBean(FrameworkStatusReportService.class);
|
||||
reportService.reportRegistrationStatus(reportService.createRegistrationReport(registerMode));
|
||||
} else {
|
||||
result.add(registryURL);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isValidRegisterMode(String mode) {
|
||||
return isNotEmpty(mode)
|
||||
&& (DEFAULT_REGISTER_MODE_INTERFACE.equalsIgnoreCase(mode)
|
||||
|| DEFAULT_REGISTER_MODE_INSTANCE.equalsIgnoreCase(mode)
|
||||
|| DEFAULT_REGISTER_MODE_ALL.equalsIgnoreCase(mode)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean registryNotExists(URL registryURL, List<URL> registryList, String registryType) {
|
||||
return registryList.stream().noneMatch(
|
||||
url -> registryType.equals(url.getProtocol()) && registryURL.getBackupAddress().equals(url.getBackupAddress())
|
||||
);
|
||||
}
|
||||
|
||||
public static URL loadMonitor(AbstractInterfaceConfig interfaceConfig, URL registryURL) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put(INTERFACE_KEY, MonitorService.class.getName());
|
||||
AbstractInterfaceConfig.appendRuntimeParameters(map);
|
||||
//set ip
|
||||
String hostToRegistry = ConfigUtils.getSystemProperty(DUBBO_IP_TO_REGISTRY);
|
||||
if (StringUtils.isEmpty(hostToRegistry)) {
|
||||
hostToRegistry = NetUtils.getLocalHost();
|
||||
} else if (NetUtils.isInvalidLocalHost(hostToRegistry)) {
|
||||
throw new IllegalArgumentException("Specified invalid registry ip from property:" +
|
||||
DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
|
||||
}
|
||||
map.put(REGISTER_IP_KEY, hostToRegistry);
|
||||
|
||||
MonitorConfig monitor = interfaceConfig.getMonitor();
|
||||
ApplicationConfig application = interfaceConfig.getApplication();
|
||||
AbstractConfig.appendParameters(map, monitor);
|
||||
AbstractConfig.appendParameters(map, application);
|
||||
String address = null;
|
||||
String sysAddress = System.getProperty(DUBBO_MONITOR_ADDRESS);
|
||||
if (sysAddress != null && sysAddress.length() > 0) {
|
||||
address = sysAddress;
|
||||
} else if (monitor != null) {
|
||||
address = monitor.getAddress();
|
||||
}
|
||||
String protocol = monitor == null ? null : monitor.getProtocol();
|
||||
if (monitor != null &&
|
||||
(REGISTRY_PROTOCOL.equals(protocol) || SERVICE_REGISTRY_PROTOCOL.equals(protocol))
|
||||
&& registryURL != null) {
|
||||
return URLBuilder.from(registryURL)
|
||||
.setProtocol(DUBBO_PROTOCOL)
|
||||
.addParameter(PROTOCOL_KEY, protocol)
|
||||
.putAttribute(REFER_KEY, map)
|
||||
.build();
|
||||
} else if (ConfigUtils.isNotEmpty(address) || ConfigUtils.isNotEmpty(protocol)) {
|
||||
if (!map.containsKey(PROTOCOL_KEY)) {
|
||||
if (interfaceConfig.getScopeModel().getExtensionLoader(MonitorFactory.class).hasExtension(LOGSTAT_PROTOCOL)) {
|
||||
map.put(PROTOCOL_KEY, LOGSTAT_PROTOCOL);
|
||||
} else if (ConfigUtils.isNotEmpty(protocol)) {
|
||||
map.put(PROTOCOL_KEY, protocol);
|
||||
} else {
|
||||
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
|
||||
}
|
||||
}
|
||||
if (ConfigUtils.isEmpty(address)) {
|
||||
address = LOCALHOST_VALUE;
|
||||
}
|
||||
return UrlUtils.parseURL(address, map);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void validateAbstractInterfaceConfig(AbstractInterfaceConfig config) {
|
||||
checkName(LOCAL_KEY, config.getLocal());
|
||||
checkName("stub", config.getStub());
|
||||
checkMultiName("owner", config.getOwner());
|
||||
|
||||
checkExtension(config.getScopeModel(), ProxyFactory.class, PROXY_KEY, config.getProxy());
|
||||
checkExtension(config.getScopeModel(), Cluster.class, CLUSTER_KEY, config.getCluster());
|
||||
checkMultiExtension(config.getScopeModel(), Arrays.asList(Filter.class, ClusterFilter.class), FILTER_KEY, config.getFilter());
|
||||
checkNameHasSymbol(LAYER_KEY, config.getLayer());
|
||||
|
||||
List<MethodConfig> methods = config.getMethods();
|
||||
if (CollectionUtils.isNotEmpty(methods)) {
|
||||
methods.forEach(ConfigValidationUtils::validateMethodConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateServiceConfig(ServiceConfig config) {
|
||||
checkKey(VERSION_KEY, config.getVersion());
|
||||
checkKey(GROUP_KEY, config.getGroup());
|
||||
checkName(TOKEN_KEY, config.getToken());
|
||||
checkPathName(PATH_KEY, config.getPath());
|
||||
|
||||
checkMultiExtension(config.getScopeModel(), ExporterListener.class, "listener", config.getListener());
|
||||
|
||||
validateAbstractInterfaceConfig(config);
|
||||
|
||||
List<RegistryConfig> registries = config.getRegistries();
|
||||
if (registries != null) {
|
||||
for (RegistryConfig registry : registries) {
|
||||
validateRegistryConfig(registry);
|
||||
}
|
||||
}
|
||||
|
||||
List<ProtocolConfig> protocols = config.getProtocols();
|
||||
if (protocols != null) {
|
||||
for (ProtocolConfig protocol : protocols) {
|
||||
validateProtocolConfig(protocol);
|
||||
}
|
||||
}
|
||||
|
||||
ProviderConfig providerConfig = config.getProvider();
|
||||
if (providerConfig != null) {
|
||||
validateProviderConfig(providerConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateReferenceConfig(ReferenceConfig config) {
|
||||
checkMultiExtension(config.getScopeModel(), InvokerListener.class, "listener", config.getListener());
|
||||
checkKey(VERSION_KEY, config.getVersion());
|
||||
checkKey(GROUP_KEY, config.getGroup());
|
||||
checkName(CLIENT_KEY, config.getClient());
|
||||
|
||||
validateAbstractInterfaceConfig(config);
|
||||
|
||||
List<RegistryConfig> registries = config.getRegistries();
|
||||
if (registries != null) {
|
||||
for (RegistryConfig registry : registries) {
|
||||
validateRegistryConfig(registry);
|
||||
}
|
||||
}
|
||||
|
||||
ConsumerConfig consumerConfig = config.getConsumer();
|
||||
if (consumerConfig != null) {
|
||||
validateConsumerConfig(consumerConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateConfigCenterConfig(ConfigCenterConfig config) {
|
||||
if (config != null) {
|
||||
checkParameterName(config.getParameters());
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateApplicationConfig(ApplicationConfig config) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.isValid()) {
|
||||
throw new IllegalStateException("No application config found or it's not a valid config! " +
|
||||
"Please add <dubbo:application name=\"...\" /> to your spring config.");
|
||||
}
|
||||
|
||||
// backward compatibility
|
||||
ScopeModel scopeModel = ScopeModelUtil.getOrDefaultApplicationModel(config.getScopeModel());
|
||||
PropertiesConfiguration configuration = scopeModel.modelEnvironment().getPropertiesConfiguration();
|
||||
String wait = configuration.getProperty(SHUTDOWN_WAIT_KEY);
|
||||
if (wait != null && wait.trim().length() > 0) {
|
||||
System.setProperty(SHUTDOWN_WAIT_KEY, wait.trim());
|
||||
} else {
|
||||
wait = configuration.getProperty(SHUTDOWN_WAIT_SECONDS_KEY);
|
||||
if (wait != null && wait.trim().length() > 0) {
|
||||
System.setProperty(SHUTDOWN_WAIT_SECONDS_KEY, wait.trim());
|
||||
}
|
||||
}
|
||||
|
||||
checkName(NAME, config.getName());
|
||||
checkMultiName(OWNER, config.getOwner());
|
||||
checkName(ORGANIZATION, config.getOrganization());
|
||||
checkName(ARCHITECTURE, config.getArchitecture());
|
||||
checkName(ENVIRONMENT, config.getEnvironment());
|
||||
checkParameterName(config.getParameters());
|
||||
checkQosDependency(config);
|
||||
}
|
||||
|
||||
private static void checkQosDependency(ApplicationConfig config) {
|
||||
if (!Boolean.FALSE.equals(config.getQosEnable())) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateModuleConfig(ModuleConfig config) {
|
||||
if (config != null) {
|
||||
checkName(NAME, config.getName());
|
||||
checkName(OWNER, config.getOwner());
|
||||
checkName(ORGANIZATION, config.getOrganization());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isValidMetadataConfig(MetadataReportConfig metadataReportConfig) {
|
||||
if (metadataReportConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Boolean.FALSE.equals(metadataReportConfig.getReportMetadata()) &&
|
||||
Boolean.FALSE.equals(metadataReportConfig.getReportDefinition())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !isEmpty(metadataReportConfig.getAddress());
|
||||
}
|
||||
|
||||
public static void validateMetadataConfig(MetadataReportConfig metadataReportConfig) {
|
||||
if (!isValidMetadataConfig(metadataReportConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String address = metadataReportConfig.getAddress();
|
||||
String protocol = metadataReportConfig.getProtocol();
|
||||
|
||||
if ((isEmpty(address) || !address.contains("://")) && isEmpty(protocol)) {
|
||||
throw new IllegalArgumentException("Please specify valid protocol or address for metadata report " + address);
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateMetricsConfig(MetricsConfig metricsConfig) {
|
||||
if (metricsConfig == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateTracingConfig(TracingConfig tracingConfig) {
|
||||
if (tracingConfig == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateSslConfig(SslConfig sslConfig) {
|
||||
if (sslConfig == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateMonitorConfig(MonitorConfig config) {
|
||||
if (config != null) {
|
||||
if (!config.isValid()) {
|
||||
logger.info("There's no valid monitor config found, if you want to open monitor statistics for Dubbo, " +
|
||||
"please make sure your monitor is configured properly.");
|
||||
}
|
||||
|
||||
checkParameterName(config.getParameters());
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateProtocolConfig(ProtocolConfig config) {
|
||||
if (config != null) {
|
||||
String name = config.getName();
|
||||
checkName("name", name);
|
||||
checkHost(HOST_KEY, config.getHost());
|
||||
checkPathName("contextpath", config.getContextpath());
|
||||
|
||||
|
||||
if (DUBBO_PROTOCOL.equals(name)) {
|
||||
checkMultiExtension(config.getScopeModel(), Codec2.class, CODEC_KEY, config.getCodec());
|
||||
checkMultiExtension(config.getScopeModel(), Serialization.class, SERIALIZATION_KEY, config.getSerialization());
|
||||
checkMultiExtension(config.getScopeModel(), Transporter.class, SERVER_KEY, config.getServer());
|
||||
checkMultiExtension(config.getScopeModel(), Transporter.class, CLIENT_KEY, config.getClient());
|
||||
}
|
||||
|
||||
checkMultiExtension(config.getScopeModel(), TelnetHandler.class, TELNET_KEY, config.getTelnet());
|
||||
checkMultiExtension(config.getScopeModel(), StatusChecker.class, "status", config.getStatus());
|
||||
checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
|
||||
checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
|
||||
checkExtension(config.getScopeModel(), Dispatcher.class, DISPATCHER_KEY, config.getDispatcher());
|
||||
checkExtension(config.getScopeModel(), Dispatcher.class, "dispather", config.getDispather());
|
||||
checkExtension(config.getScopeModel(), ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateProviderConfig(ProviderConfig config) {
|
||||
checkPathName(CONTEXTPATH_KEY, config.getContextpath());
|
||||
checkExtension(config.getScopeModel(), ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
|
||||
checkMultiExtension(config.getScopeModel(), TelnetHandler.class, TELNET_KEY, config.getTelnet());
|
||||
checkMultiExtension(config.getScopeModel(), StatusChecker.class, STATUS_KEY, config.getStatus());
|
||||
checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
|
||||
checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
|
||||
}
|
||||
|
||||
public static void validateConsumerConfig(ConsumerConfig config) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateRegistryConfig(RegistryConfig config) {
|
||||
checkName(PROTOCOL_KEY, config.getProtocol());
|
||||
checkName(USERNAME_KEY, config.getUsername());
|
||||
checkLength(PASSWORD_KEY, config.getPassword());
|
||||
checkPathLength(FILE_KEY, config.getFile());
|
||||
checkName(TRANSPORTER_KEY, config.getTransporter());
|
||||
checkName(SERVER_KEY, config.getServer());
|
||||
checkName(CLIENT_KEY, config.getClient());
|
||||
checkParameterName(config.getParameters());
|
||||
}
|
||||
|
||||
public static void validateMethodConfig(MethodConfig config) {
|
||||
checkExtension(config.getScopeModel(), LoadBalance.class, LOADBALANCE_KEY, config.getLoadbalance());
|
||||
checkParameterName(config.getParameters());
|
||||
checkMethodName("name", config.getName());
|
||||
|
||||
String mock = config.getMock();
|
||||
if (isNotEmpty(mock)) {
|
||||
if (mock.startsWith(RETURN_PREFIX) || mock.startsWith(THROW_PREFIX + " ")) {
|
||||
checkLength(MOCK_KEY, mock);
|
||||
} else if (mock.startsWith(FAIL_PREFIX) || mock.startsWith(FORCE_PREFIX)) {
|
||||
checkNameHasSymbol(MOCK_KEY, mock);
|
||||
} else {
|
||||
checkName(MOCK_KEY, mock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractRegistryType(URL url) {
|
||||
return UrlUtils.hasServiceDiscoveryRegistryTypeKey(url) ? SERVICE_REGISTRY_PROTOCOL : getRegistryProtocolType(url);
|
||||
}
|
||||
|
||||
private static String getRegistryProtocolType(URL url) {
|
||||
String registryProtocol = url.getParameter("registry-protocol-type");
|
||||
return isNotEmpty(registryProtocol) ? registryProtocol : REGISTRY_PROTOCOL;
|
||||
}
|
||||
|
||||
public static void checkExtension(ScopeModel scopeModel, Class<?> type, String property, String value) {
|
||||
checkName(property, value);
|
||||
if (isNotEmpty(value)
|
||||
&& !scopeModel.getExtensionLoader(type).hasExtension(value)) {
|
||||
throw new IllegalStateException("No such extension " + value + " for " + property + "/" + type.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is a <code>Extension</code> who's name (property) is <code>value</code> (special treatment is
|
||||
* required)
|
||||
*
|
||||
* @param type The Extension type
|
||||
* @param property The extension key
|
||||
* @param value The Extension name
|
||||
*/
|
||||
public static void checkMultiExtension(ScopeModel scopeModel, Class<?> type, String property, String value) {
|
||||
checkMultiExtension(scopeModel, Collections.singletonList(type), property, value);
|
||||
}
|
||||
|
||||
public static void checkMultiExtension(ScopeModel scopeModel, List<Class<?>> types, String property, String value) {
|
||||
checkMultiName(property, value);
|
||||
if (isNotEmpty(value)) {
|
||||
String[] values = value.split("\\s*[,]+\\s*");
|
||||
for (String v : values) {
|
||||
v = StringUtils.trim(v);
|
||||
if (v.startsWith(REMOVE_VALUE_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
if (DEFAULT_KEY.equals(v)) {
|
||||
continue;
|
||||
}
|
||||
boolean match = false;
|
||||
for (Class<?> type : types) {
|
||||
if (scopeModel.getExtensionLoader(type).hasExtension(v)) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
throw new IllegalStateException("No such extension " + v + " for " + property + "/" +
|
||||
types.stream().map(Class::getName).collect(Collectors.joining(",")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkLength(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, null);
|
||||
}
|
||||
|
||||
public static void checkPathLength(String property, String value) {
|
||||
checkProperty(property, value, MAX_PATH_LENGTH, null);
|
||||
}
|
||||
|
||||
public static void checkName(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_NAME);
|
||||
}
|
||||
|
||||
public static void checkHost(String property, String value) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
if (value.startsWith(IPV6_START_MARK) && value.endsWith(IPV6_END_MARK)) {
|
||||
// if the value start with "[" and end with "]", check whether it is IPV6
|
||||
try {
|
||||
InetAddress.getByName(value);
|
||||
return;
|
||||
} catch (UnknownHostException e) {
|
||||
// not a IPv6 string, do nothing, go on to checkName
|
||||
}
|
||||
}
|
||||
checkName(property, value);
|
||||
}
|
||||
|
||||
public static void checkNameHasSymbol(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_NAME_HAS_SYMBOL);
|
||||
}
|
||||
|
||||
public static void checkKey(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_KEY);
|
||||
}
|
||||
|
||||
public static void checkMultiName(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_MULTI_NAME);
|
||||
}
|
||||
|
||||
public static void checkPathName(String property, String value) {
|
||||
checkProperty(property, value, MAX_PATH_LENGTH, PATTERN_PATH);
|
||||
}
|
||||
|
||||
public static void checkMethodName(String property, String value) {
|
||||
checkProperty(property, value, MAX_LENGTH, PATTERN_METHOD_NAME);
|
||||
}
|
||||
|
||||
public static void checkParameterName(Map<String, String> parameters) {
|
||||
if (CollectionUtils.isEmptyMap(parameters)) {
|
||||
return;
|
||||
}
|
||||
List<String> ignoreCheckKeys = new ArrayList<>();
|
||||
ignoreCheckKeys.add(BACKUP_KEY);
|
||||
String ignoreCheckKeysStr = parameters.get(IGNORE_CHECK_KEYS);
|
||||
if (!StringUtils.isBlank(ignoreCheckKeysStr)) {
|
||||
ignoreCheckKeys.addAll(Arrays.asList(ignoreCheckKeysStr.split(",")));
|
||||
}
|
||||
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||
if (!ignoreCheckKeys.contains(entry.getKey())) {
|
||||
checkNameHasSymbol(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkProperty(String property, String value, int maxlength, Pattern pattern) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
if (value.length() > maxlength) {
|
||||
logger.error(CONFIG_PARAMETER_FORMAT_ERROR, "the value content is too long", "", "Parameter value format error. Invalid " +
|
||||
property + "=\"" + value + "\" is longer than " + maxlength);
|
||||
}
|
||||
if (pattern != null) {
|
||||
Matcher matcher = pattern.matcher(value);
|
||||
if (!matcher.matches()) {
|
||||
logger.error(CONFIG_PARAMETER_FORMAT_ERROR, "the value content is illegal character", "", "Parameter value format error. Invalid " +
|
||||
property + "=\"" + value + "\" contains illegal " +
|
||||
"character, only digit, letter, '-', '_' or '.' is legal.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* 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.utils;
|
||||
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.ModuleConfig;
|
||||
import org.apache.dubbo.config.MonitorConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
|
||||
public class DefaultConfigValidator implements ConfigValidator {
|
||||
|
||||
@Override
|
||||
public void validate(AbstractConfig config) {
|
||||
if (config instanceof ProtocolConfig) {
|
||||
ConfigValidationUtils.validateProtocolConfig((ProtocolConfig) config);
|
||||
} else if (config instanceof RegistryConfig) {
|
||||
ConfigValidationUtils.validateRegistryConfig((RegistryConfig) config);
|
||||
} else if (config instanceof MetadataReportConfig) {
|
||||
ConfigValidationUtils.validateMetadataConfig((MetadataReportConfig) config);
|
||||
} else if (config instanceof ProviderConfig) {
|
||||
ConfigValidationUtils.validateProviderConfig((ProviderConfig) config);
|
||||
} else if (config instanceof ConsumerConfig) {
|
||||
ConfigValidationUtils.validateConsumerConfig((ConsumerConfig) config);
|
||||
} else if (config instanceof ApplicationConfig) {
|
||||
ConfigValidationUtils.validateApplicationConfig((ApplicationConfig) config);
|
||||
} else if (config instanceof MonitorConfig) {
|
||||
ConfigValidationUtils.validateMonitorConfig((MonitorConfig) config);
|
||||
} else if (config instanceof ModuleConfig) {
|
||||
ConfigValidationUtils.validateModuleConfig((ModuleConfig) config);
|
||||
} else if (config instanceof MetricsConfig) {
|
||||
ConfigValidationUtils.validateMetricsConfig((MetricsConfig) config);
|
||||
} else if (config instanceof TracingConfig) {
|
||||
ConfigValidationUtils.validateTracingConfig((TracingConfig) config);
|
||||
} else if (config instanceof SslConfig) {
|
||||
ConfigValidationUtils.validateSslConfig((SslConfig) config);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.ConfigCenterConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
|
||||
//TODO: Move to configcenter-api
|
||||
@Activate
|
||||
public class ConfigCenterConfigValidator implements ConfigValidator<ConfigCenterConfig> {
|
||||
|
||||
public static void validateConfigCenterConfig(ConfigCenterConfig config) {
|
||||
if (config != null) {
|
||||
ConfigValidationUtils.checkParameterName(config.getParameters());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(ConfigCenterConfig config) {
|
||||
validateConfigCenterConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ConfigCenterConfig.class.equals(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
|
||||
@Activate
|
||||
public class ConsumerConfigValidator implements ConfigValidator<ConsumerConfig> {
|
||||
|
||||
public static void validateConsumerConfig(ConsumerConfig config) {
|
||||
//TODO
|
||||
if (config == null) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(ConsumerConfig config) {
|
||||
validateConsumerConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ConsumerConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.config.AbstractInterfaceConfig;
|
||||
import org.apache.dubbo.config.MethodConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
import org.apache.dubbo.rpc.cluster.Cluster;
|
||||
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.FILTER_KEY;
|
||||
import static org.apache.dubbo.config.Constants.LAYER_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.PROXY_KEY;
|
||||
|
||||
@Activate
|
||||
public class InterfaceConfigValidator implements ConfigValidator<AbstractInterfaceConfig> {
|
||||
|
||||
public static void validateAbstractInterfaceConfig(AbstractInterfaceConfig config) {
|
||||
ConfigValidationUtils.checkName(LOCAL_KEY, config.getLocal());
|
||||
ConfigValidationUtils.checkName("stub", config.getStub());
|
||||
ConfigValidationUtils.checkMultiName("owner", config.getOwner());
|
||||
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), ProxyFactory.class, PROXY_KEY, config.getProxy());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Cluster.class, CLUSTER_KEY, config.getCluster());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), Arrays.asList(Filter.class, ClusterFilter.class), FILTER_KEY, config.getFilter());
|
||||
ConfigValidationUtils.checkNameHasSymbol(LAYER_KEY, config.getLayer());
|
||||
|
||||
List<MethodConfig> methods = config.getMethods();
|
||||
if (CollectionUtils.isNotEmpty(methods)) {
|
||||
methods.forEach(MethodConfig::validate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(AbstractInterfaceConfig config) {
|
||||
validateAbstractInterfaceConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return AbstractInterfaceConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.MethodConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
|
||||
import static org.apache.dubbo.rpc.Constants.FAIL_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.FORCE_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
|
||||
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
|
||||
|
||||
@Activate
|
||||
public class MethodConfigValidator implements ConfigValidator<MethodConfig> {
|
||||
|
||||
public static void validateMethodConfig(MethodConfig config) {
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), LoadBalance.class, LOADBALANCE_KEY, config.getLoadbalance());
|
||||
ConfigValidationUtils.checkParameterName(config.getParameters());
|
||||
ConfigValidationUtils.checkMethodName("name", config.getName());
|
||||
|
||||
String mock = config.getMock();
|
||||
if (isNotEmpty(mock)) {
|
||||
if (mock.startsWith(RETURN_PREFIX) || mock.startsWith(THROW_PREFIX + " ")) {
|
||||
ConfigValidationUtils.checkLength(MOCK_KEY, mock);
|
||||
} else if (mock.startsWith(FAIL_PREFIX) || mock.startsWith(FORCE_PREFIX)) {
|
||||
ConfigValidationUtils.checkNameHasSymbol(MOCK_KEY, mock);
|
||||
} else {
|
||||
ConfigValidationUtils.checkName(MOCK_KEY, mock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(MethodConfig config) {
|
||||
validateMethodConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return MethodConfig.class.equals(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.status.StatusChecker;
|
||||
import org.apache.dubbo.common.threadpool.ThreadPool;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.remoting.Transporter;
|
||||
import org.apache.dubbo.remoting.exchange.Exchanger;
|
||||
import org.apache.dubbo.remoting.telnet.TelnetHandler;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
|
||||
import static org.apache.dubbo.config.Constants.CONTEXTPATH_KEY;
|
||||
import static org.apache.dubbo.config.Constants.STATUS_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.TELNET_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.TRANSPORTER_KEY;
|
||||
|
||||
@Activate
|
||||
public class ProviderConfigValidator implements ConfigValidator<ProviderConfig> {
|
||||
|
||||
@Override
|
||||
public boolean validate(ProviderConfig config) {
|
||||
validateProviderConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void validateProviderConfig(ProviderConfig config) {
|
||||
ConfigValidationUtils.checkPathName(CONTEXTPATH_KEY, config.getContextpath());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), TelnetHandler.class, TELNET_KEY, config.getTelnet());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), StatusChecker.class, STATUS_KEY, config.getStatus());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ProviderConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.InvokerListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
|
||||
|
||||
@Activate
|
||||
public class ReferenceConfigValidator implements ConfigValidator<ReferenceConfig<?>> {
|
||||
|
||||
@Override
|
||||
public boolean validate(ReferenceConfig<?> config) {
|
||||
validateReferenceConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void validateReferenceConfig(ReferenceConfig<?> config) {
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), InvokerListener.class, "listener", config.getListener());
|
||||
ConfigValidationUtils.checkKey(VERSION_KEY, config.getVersion());
|
||||
ConfigValidationUtils.checkKey(GROUP_KEY, config.getGroup());
|
||||
ConfigValidationUtils.checkName(CLIENT_KEY, config.getClient());
|
||||
|
||||
List<RegistryConfig> registries = config.getRegistries();
|
||||
if (registries != null) {
|
||||
for (RegistryConfig registry : registries) {
|
||||
registry.validate();
|
||||
}
|
||||
}
|
||||
|
||||
ConsumerConfig consumerConfig = config.getConsumer();
|
||||
if (consumerConfig != null) {
|
||||
consumerConfig.validate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ReferenceConfig.class.equals(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.ExporterListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
|
||||
|
||||
@Activate
|
||||
public class ServiceConfigValidator implements ConfigValidator<ServiceConfig<?>> {
|
||||
|
||||
public static void validateServiceConfig(ServiceConfig<?> config) {
|
||||
|
||||
ConfigValidationUtils.checkKey(VERSION_KEY, config.getVersion());
|
||||
ConfigValidationUtils.checkKey(GROUP_KEY, config.getGroup());
|
||||
ConfigValidationUtils.checkName(TOKEN_KEY, config.getToken());
|
||||
ConfigValidationUtils.checkPathName(PATH_KEY, config.getPath());
|
||||
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), ExporterListener.class, "listener", config.getListener());
|
||||
|
||||
List<RegistryConfig> registries = config.getRegistries();
|
||||
if (registries != null) {
|
||||
for (RegistryConfig registry : registries) {
|
||||
registry.validate();
|
||||
}
|
||||
}
|
||||
|
||||
List<ProtocolConfig> protocols = config.getProtocols();
|
||||
if (protocols != null) {
|
||||
for (ProtocolConfig protocol : protocols) {
|
||||
protocol.validate();
|
||||
}
|
||||
}
|
||||
|
||||
ProviderConfig providerConfig = config.getProvider();
|
||||
if (providerConfig != null) {
|
||||
providerConfig.validate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(ServiceConfig<?> config) {
|
||||
validateServiceConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ServiceConfig.class.equals(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
config-center=org.apache.dubbo.config.validator.ConfigCenterConfigValidator
|
||||
consumer=org.apache.dubbo.config.validator.ConsumerConfigValidator
|
||||
interface=org.apache.dubbo.config.validator.InterfaceConfigValidator
|
||||
method=org.apache.dubbo.config.validator.MethodConfigValidator
|
||||
provider=org.apache.dubbo.config.validator.ProviderConfigValidator
|
||||
reference=org.apache.dubbo.config.validator.ReferenceConfigValidator
|
||||
service=org.apache.dubbo.config.validator.ServiceConfigValidator
|
||||
|
||||
|
|
@ -3,3 +3,4 @@ config-post-handle=org.apache.dubbo.config.deploy.lifecycle.application.Applicat
|
|||
module-initialize=org.apache.dubbo.config.deploy.lifecycle.application.ModuleInitializeLifecycle
|
||||
post-offline=org.apache.dubbo.config.deploy.lifecycle.application.ApplicationPostOfflineLifecycle
|
||||
app-prepare=org.apache.dubbo.config.deploy.lifecycle.application.ApplicationPrepareLifecycle
|
||||
validator-registry=org.apache.dubbo.config.deploy.lifecycle.application.ValidatorRegistryDeployListener
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class AbstractConfigTest {
|
|||
protocolConfig.setCodec("exchange");
|
||||
protocolConfig.setName("test");
|
||||
protocolConfig.setHost("host");
|
||||
ConfigValidationUtils.validateProtocolConfig(protocolConfig);
|
||||
protocolConfig.validate();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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.config.validator.ConsumerConfigValidator;
|
||||
import org.apache.dubbo.config.validator.InterfaceConfigValidator;
|
||||
import org.apache.dubbo.config.validator.MethodConfigValidator;
|
||||
import org.apache.dubbo.config.validator.ProviderConfigValidator;
|
||||
import org.apache.dubbo.config.validator.ReferenceConfigValidator;
|
||||
import org.apache.dubbo.config.validator.ServiceConfigValidator;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
|
||||
|
||||
public class ConfigValidatorExistTest {
|
||||
|
||||
ConfigValidateFacade validateFacade;
|
||||
|
||||
@Test
|
||||
void testConfigValidatorExist(){
|
||||
FrameworkModel frameworkModel = FrameworkModel.defaultModel();
|
||||
ApplicationModel applicationModel = frameworkModel.newApplication();
|
||||
|
||||
validateFacade = new ConfigValidateFacade(applicationModel);
|
||||
Assertions.assertNotNull(validateFacade);
|
||||
Assertions.assertTrue(validateFacade.getValidators().size() >= 7);
|
||||
|
||||
try(
|
||||
MockedStatic<ConsumerConfigValidator> configValidatorMockedStatic = Mockito.mockStatic(ConsumerConfigValidator.class);
|
||||
MockedStatic<InterfaceConfigValidator> interfaceConfigValidatorMockedStatic = Mockito.mockStatic(InterfaceConfigValidator.class);
|
||||
MockedStatic<MethodConfigValidator> methodConfigValidatorMockedStatic = Mockito.mockStatic(MethodConfigValidator.class);
|
||||
MockedStatic<ProviderConfigValidator> providerConfigValidatorMockedStatic = Mockito.mockStatic(ProviderConfigValidator.class);
|
||||
MockedStatic<ReferenceConfigValidator> referenceConfigValidatorMockedStatic = Mockito.mockStatic(ReferenceConfigValidator.class);
|
||||
MockedStatic<ServiceConfigValidator> serviceConfigValidatorMockedStatic = Mockito.mockStatic(ServiceConfigValidator.class);
|
||||
){
|
||||
configValidatorMockedStatic.when(()-> ConsumerConfigValidator.validateConsumerConfig(any())).thenCallRealMethod();
|
||||
interfaceConfigValidatorMockedStatic.when(()-> InterfaceConfigValidator.validateAbstractInterfaceConfig(any())).thenCallRealMethod();
|
||||
methodConfigValidatorMockedStatic.when(()-> MethodConfigValidator.validateMethodConfig(any())).thenCallRealMethod();
|
||||
providerConfigValidatorMockedStatic.when(()-> ProviderConfigValidator.validateProviderConfig(any())).thenCallRealMethod();
|
||||
referenceConfigValidatorMockedStatic.when(()-> ReferenceConfigValidator.validateReferenceConfig(any())).thenCallRealMethod();
|
||||
serviceConfigValidatorMockedStatic.when(()->ServiceConfigValidator.validateServiceConfig(any())).thenCallRealMethod();
|
||||
triggerValidate(new ConsumerConfig());
|
||||
triggerValidate(new AbstractInterfaceConfig() {
|
||||
@Override
|
||||
public List<URL> getExportedUrls() {
|
||||
return super.getExportedUrls();
|
||||
}
|
||||
});
|
||||
triggerValidate(new MethodConfig());
|
||||
triggerValidate(new ProviderConfig());
|
||||
triggerValidate(new ReferenceConfig<>());
|
||||
triggerValidate(new ServiceConfig<>());
|
||||
|
||||
configValidatorMockedStatic.verify(()-> ConsumerConfigValidator.validateConsumerConfig(any()),atLeastOnce());
|
||||
interfaceConfigValidatorMockedStatic.verify(()-> InterfaceConfigValidator.validateAbstractInterfaceConfig(any()),atLeastOnce());
|
||||
methodConfigValidatorMockedStatic.verify(()->MethodConfigValidator.validateMethodConfig(any()),atLeastOnce());
|
||||
providerConfigValidatorMockedStatic.verify(()->ProviderConfigValidator.validateProviderConfig(any()),atLeastOnce());
|
||||
referenceConfigValidatorMockedStatic.verify(()->ReferenceConfigValidator.validateReferenceConfig(any()),atLeastOnce());
|
||||
serviceConfigValidatorMockedStatic.verify(()-> ServiceConfigValidator.validateServiceConfig(any()),atLeastOnce());
|
||||
}
|
||||
}
|
||||
|
||||
void triggerValidate(AbstractConfig config){
|
||||
try {
|
||||
validateFacade.validate(config);
|
||||
}catch (Throwable ignored){};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@ import org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter;
|
|||
import org.apache.dubbo.config.metadata.ExporterDeployListener;
|
||||
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.config.validator.ApplicationConfigValidator;
|
||||
import org.apache.dubbo.metadata.MetadataService;
|
||||
import org.apache.dubbo.monitor.MonitorService;
|
||||
import org.apache.dubbo.registry.RegistryService;
|
||||
|
|
@ -42,6 +43,7 @@ import org.apache.dubbo.rpc.Exporter;
|
|||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
|
||||
import org.apache.dubbo.test.check.registrycenter.config.ZookeeperRegistryCenterConfig;
|
||||
import org.apache.dubbo.util.MonitorUrlUtil;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
|
@ -114,13 +116,13 @@ class DubboBootstrapTest {
|
|||
|
||||
writeDubboProperties(SHUTDOWN_WAIT_KEY, "100");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo"));
|
||||
ApplicationConfigValidator.validateApplicationConfig(new ApplicationConfig("demo"));
|
||||
Assertions.assertEquals("100", System.getProperty(SHUTDOWN_WAIT_KEY));
|
||||
|
||||
System.clearProperty(SHUTDOWN_WAIT_KEY);
|
||||
writeDubboProperties(SHUTDOWN_WAIT_SECONDS_KEY, "1000");
|
||||
ApplicationModel.defaultModel().modelEnvironment().getPropertiesConfiguration().refresh();
|
||||
ConfigValidationUtils.validateApplicationConfig(new ApplicationConfig("demo"));
|
||||
ApplicationConfigValidator.validateApplicationConfig(new ApplicationConfig("demo"));
|
||||
Assertions.assertEquals("1000", System.getProperty(SHUTDOWN_WAIT_SECONDS_KEY));
|
||||
} finally {
|
||||
System.clearProperty("dubbo.application.name");
|
||||
|
|
@ -162,7 +164,7 @@ class DubboBootstrapTest {
|
|||
void testLoadUserMonitor_address_only() {
|
||||
// -Ddubbo.monitor.address=monitor-addr:12080
|
||||
SysProps.setProperty(DUBBO_MONITOR_ADDRESS, "monitor-addr:12080");
|
||||
URL url = ConfigValidationUtils.loadMonitor(getTestInterfaceConfig(new MonitorConfig()), new ServiceConfigURL("dubbo", "addr1", 9090));
|
||||
URL url = MonitorUrlUtil.loadMonitor(getTestInterfaceConfig(new MonitorConfig()), new ServiceConfigURL("dubbo", "addr1", 9090));
|
||||
Assertions.assertEquals("monitor-addr:12080", url.getAddress());
|
||||
Assertions.assertEquals(MonitorService.class.getName(), url.getParameter("interface"));
|
||||
Assertions.assertNotNull(url.getParameter("dubbo"));
|
||||
|
|
@ -176,7 +178,7 @@ class DubboBootstrapTest {
|
|||
MonitorConfig monitorConfig = new MonitorConfig();
|
||||
monitorConfig.setProtocol("registry");
|
||||
|
||||
URL url = ConfigValidationUtils.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
URL url = MonitorUrlUtil.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
Assertions.assertEquals("dubbo", url.getProtocol());
|
||||
Assertions.assertEquals("registry", url.getParameter("protocol"));
|
||||
}
|
||||
|
|
@ -187,14 +189,14 @@ class DubboBootstrapTest {
|
|||
MonitorConfig monitorConfig = new MonitorConfig();
|
||||
monitorConfig.setProtocol("service-discovery-registry");
|
||||
|
||||
URL url = ConfigValidationUtils.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
URL url = MonitorUrlUtil.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
Assertions.assertEquals("dubbo", url.getProtocol());
|
||||
Assertions.assertEquals("service-discovery-registry", url.getParameter("protocol"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoadUserMonitor_no_monitor() {
|
||||
URL url = ConfigValidationUtils.loadMonitor(getTestInterfaceConfig(null), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
URL url = MonitorUrlUtil.loadMonitor(getTestInterfaceConfig(null), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
Assertions.assertNull(url);
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +206,7 @@ class DubboBootstrapTest {
|
|||
MonitorConfig monitorConfig = new MonitorConfig();
|
||||
monitorConfig.setProtocol("user");
|
||||
|
||||
URL url = ConfigValidationUtils.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
URL url = MonitorUrlUtil.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
Assertions.assertEquals("user", url.getProtocol());
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +215,7 @@ class DubboBootstrapTest {
|
|||
// dubbo.monitor.address=user://1.2.3.4:5678?k=v
|
||||
MonitorConfig monitorConfig = new MonitorConfig();
|
||||
monitorConfig.setAddress("user://1.2.3.4:5678?param1=value1");
|
||||
URL url = ConfigValidationUtils.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
URL url = MonitorUrlUtil.loadMonitor(getTestInterfaceConfig(monitorConfig), URL.valueOf(ZookeeperRegistryCenterConfig.getConnectionAddress()));
|
||||
Assertions.assertEquals("user", url.getProtocol());
|
||||
Assertions.assertEquals("1.2.3.4:5678", url.getAddress());
|
||||
Assertions.assertEquals("value1", url.getParameter("param1"));
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
|||
import org.apache.dubbo.config.AbstractInterfaceConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
|
||||
import org.apache.dubbo.config.exception.ConfigValidationException;
|
||||
import org.apache.dubbo.config.validator.ApplicationConfigValidator;
|
||||
import org.apache.dubbo.config.validator.MetadataConfigValidator;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
|
@ -29,9 +31,12 @@ import org.mockito.Mockito;
|
|||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CLASS_NOT_FOUND;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
|
@ -45,7 +50,7 @@ class ConfigValidationUtilsTest {
|
|||
MetadataReportConfig config = new MetadataReportConfig();
|
||||
config.setAddress("protocol://ip:host");
|
||||
try {
|
||||
ConfigValidationUtils.validateMetadataConfig(config);
|
||||
MetadataConfigValidator.validateMetadataConfig(config);
|
||||
} catch (Exception e) {
|
||||
Assertions.fail("valid config expected.");
|
||||
}
|
||||
|
|
@ -53,7 +58,7 @@ class ConfigValidationUtilsTest {
|
|||
config.setAddress("ip:host");
|
||||
config.setProtocol("protocol");
|
||||
try {
|
||||
ConfigValidationUtils.validateMetadataConfig(config);
|
||||
MetadataConfigValidator.validateMetadataConfig(config);
|
||||
} catch (Exception e) {
|
||||
Assertions.fail("valid config expected.");
|
||||
}
|
||||
|
|
@ -61,17 +66,18 @@ class ConfigValidationUtilsTest {
|
|||
config.setAddress("ip:host");
|
||||
config.setProtocol(null);
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> {
|
||||
ConfigValidationUtils.validateMetadataConfig(config);
|
||||
MetadataConfigValidator.validateMetadataConfig(config);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateApplicationConfig() throws Exception {
|
||||
try (MockedStatic<ConfigValidationUtils> mockedStatic = Mockito.mockStatic(ConfigValidationUtils.class);) {
|
||||
mockedStatic.when(() -> ConfigValidationUtils.validateApplicationConfig(any())).thenCallRealMethod();
|
||||
try (MockedStatic<ApplicationConfigValidator> mockedStatic = Mockito.mockStatic(ApplicationConfigValidator.class);
|
||||
MockedStatic<ConfigValidationUtils> configValidationUtilsMockedStatic = Mockito.mockStatic(ConfigValidationUtils.class);) {
|
||||
mockedStatic.when(() -> ApplicationConfigValidator.validateApplicationConfig(any())).thenCallRealMethod();
|
||||
ApplicationConfig config = new ApplicationConfig();
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
ConfigValidationUtils.validateApplicationConfig(config);
|
||||
Assertions.assertThrows(ConfigValidationException.class, () -> {
|
||||
ApplicationConfigValidator.validateApplicationConfig(config);
|
||||
});
|
||||
|
||||
config.setName("testName");
|
||||
|
|
@ -83,14 +89,19 @@ class ConfigValidationUtilsTest {
|
|||
map.put("k1", "v1");
|
||||
map.put("k2", "v2");
|
||||
config.setParameters(map);
|
||||
ConfigValidationUtils.validateApplicationConfig(config);
|
||||
mockedStatic.verify(() -> {
|
||||
ApplicationConfigValidator.validateApplicationConfig(config);
|
||||
|
||||
configValidationUtilsMockedStatic.when(()-> ConfigValidationUtils.checkName(anyString(),anyString())).thenCallRealMethod();
|
||||
configValidationUtilsMockedStatic.when(()-> ConfigValidationUtils.checkMultiName(anyString(),anyString())).thenCallRealMethod();
|
||||
configValidationUtilsMockedStatic.when(()-> ConfigValidationUtils.checkParameterName(any())).thenCallRealMethod();
|
||||
configValidationUtilsMockedStatic.when(()-> ConfigValidationUtils.checkProperty(anyString(),anyString(),anyInt(),any(Pattern.class))).thenCallRealMethod();
|
||||
configValidationUtilsMockedStatic.verify(() -> {
|
||||
ConfigValidationUtils.checkName(any(), any());
|
||||
}, times(4));
|
||||
mockedStatic.verify(() -> {
|
||||
configValidationUtilsMockedStatic.verify(() -> {
|
||||
ConfigValidationUtils.checkMultiName(any(), any());
|
||||
}, times(1));
|
||||
mockedStatic.verify(() -> {
|
||||
configValidationUtilsMockedStatic.verify(() -> {
|
||||
ConfigValidationUtils.checkParameterName(any());
|
||||
}, times(1));
|
||||
}
|
||||
|
|
@ -98,13 +109,13 @@ class ConfigValidationUtilsTest {
|
|||
|
||||
@Test
|
||||
void testCheckQosInApplicationConfig() throws Exception {
|
||||
ConfigValidationUtils mock = Mockito.mock(ConfigValidationUtils.class);
|
||||
ApplicationConfigValidator mock = Mockito.mock(ApplicationConfigValidator.class);
|
||||
ErrorTypeAwareLogger loggerMock = Mockito.mock(ErrorTypeAwareLogger.class);
|
||||
injectField(mock.getClass().getDeclaredField("logger"), loggerMock);
|
||||
ApplicationConfig config = new ApplicationConfig();
|
||||
config.setName("testName");
|
||||
config.setQosEnable(false);
|
||||
mock.validateApplicationConfig(config);
|
||||
ApplicationConfigValidator.validateApplicationConfig(config);
|
||||
verify(loggerMock, never()).warn(any(), any(Throwable.class));
|
||||
|
||||
config.setQosEnable(true);
|
||||
|
|
|
|||
|
|
@ -1590,6 +1590,13 @@
|
|||
META-INF/dubbo/internal/org.apache.dubbo.config.CommonConfigPostProcessor
|
||||
</resource>
|
||||
</transformer>
|
||||
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>
|
||||
META-INF/dubbo/internal/org.apache.dubbo.config.context.ConfigValidator
|
||||
</resource>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
|
||||
|
||||
@Activate
|
||||
public class MetadataConfigValidator implements ConfigValidator<MetadataReportConfig> {
|
||||
|
||||
@Override
|
||||
public boolean validate(MetadataReportConfig config) {
|
||||
return validateMetadataConfig(config);
|
||||
}
|
||||
|
||||
public static boolean validateMetadataConfig(MetadataReportConfig metadataReportConfig) {
|
||||
if (!isValidMetadataConfig(metadataReportConfig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String address = metadataReportConfig.getAddress();
|
||||
String protocol = metadataReportConfig.getProtocol();
|
||||
|
||||
if ((isEmpty(address) || !address.contains("://")) && isEmpty(protocol)) {
|
||||
throw new IllegalArgumentException("Please specify valid protocol or address for metadata report " + address);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isValidMetadataConfig(MetadataReportConfig metadataReportConfig) {
|
||||
if (metadataReportConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Boolean.FALSE.equals(metadataReportConfig.getReportMetadata()) &&
|
||||
Boolean.FALSE.equals(metadataReportConfig.getReportDefinition())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !isEmpty(metadataReportConfig.getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return MetadataReportConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
metadata=org.apache.dubbo.config.validator.MetadataConfigValidator
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
|
||||
@Activate
|
||||
public class MetricsConfigValidator implements ConfigValidator<MetricsConfig> {
|
||||
|
||||
public static void validateMetricsConfig(MetricsConfig metricsConfig) {
|
||||
//TODO
|
||||
if (metricsConfig == null) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(MetricsConfig config) {
|
||||
validateMetricsConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return MetricsConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
metrics=org.apache.dubbo.config.validator.MetricsConfigValidator
|
||||
|
|
@ -33,7 +33,6 @@ import org.apache.dubbo.metrics.model.key.MetricsKey;
|
|||
import org.apache.dubbo.metrics.model.key.MetricsKeyWrapper;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsLevel;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsPlaceValue;
|
||||
import org.apache.dubbo.metrics.model.key.TypeWrapper;
|
||||
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
|
|
@ -45,7 +44,6 @@ import org.apache.dubbo.rpc.RpcException;
|
|||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
@ -157,7 +155,8 @@ class DefaultCollectorTest {
|
|||
// push finish rt +1
|
||||
List<MetricSample> metricSamples = collector.collect();
|
||||
//num(total+success+processing) + rt(5) + error code = 9
|
||||
Assertions.assertEquals(metricSamples.size(),9);
|
||||
Assertions.assertEquals(9, metricSamples.size());
|
||||
|
||||
List<String> metricsNames = metricSamples.stream().map(MetricSample::getName).collect(Collectors.toList());
|
||||
// No error will contain total+success+processing
|
||||
String REQUESTS = new MetricsKeyWrapper(METRIC_REQUESTS, MetricsPlaceValue.of(side, MetricsLevel.SERVICE)).targetKey();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
|
||||
@Activate
|
||||
public class TracingConfigValidator implements ConfigValidator<TracingConfig> {
|
||||
|
||||
public static void validateTracingConfig(TracingConfig tracingConfig) {
|
||||
// TODO
|
||||
if (tracingConfig == null) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(TracingConfig config) {
|
||||
validateTracingConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return TracingConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
tracing=org.apache.dubbo.config.validator.TracingConfigValidator
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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.util;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.URLBuilder;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.AbstractInterfaceConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.MonitorConfig;
|
||||
import org.apache.dubbo.monitor.Constants;
|
||||
import org.apache.dubbo.monitor.MonitorFactory;
|
||||
import org.apache.dubbo.monitor.MonitorService;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_MONITOR_ADDRESS;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
|
||||
import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
|
||||
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
|
||||
|
||||
public class MonitorUrlUtil {
|
||||
|
||||
public static URL loadMonitor(AbstractInterfaceConfig interfaceConfig, URL registryURL) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put(INTERFACE_KEY, MonitorService.class.getName());
|
||||
AbstractInterfaceConfig.appendRuntimeParameters(map);
|
||||
//set ip
|
||||
String hostToRegistry = ConfigUtils.getSystemProperty(DUBBO_IP_TO_REGISTRY);
|
||||
if (StringUtils.isEmpty(hostToRegistry)) {
|
||||
hostToRegistry = NetUtils.getLocalHost();
|
||||
} else if (NetUtils.isInvalidLocalHost(hostToRegistry)) {
|
||||
throw new IllegalArgumentException("Specified invalid registry ip from property:" +
|
||||
DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
|
||||
}
|
||||
map.put(REGISTER_IP_KEY, hostToRegistry);
|
||||
|
||||
MonitorConfig monitor = interfaceConfig.getMonitor();
|
||||
ApplicationConfig application = interfaceConfig.getApplication();
|
||||
AbstractConfig.appendParameters(map, monitor);
|
||||
AbstractConfig.appendParameters(map, application);
|
||||
String address = null;
|
||||
String sysAddress = System.getProperty(DUBBO_MONITOR_ADDRESS);
|
||||
if (sysAddress != null && sysAddress.length() > 0) {
|
||||
address = sysAddress;
|
||||
} else if (monitor != null) {
|
||||
address = monitor.getAddress();
|
||||
}
|
||||
String protocol = monitor == null ? null : monitor.getProtocol();
|
||||
if (monitor != null &&
|
||||
(REGISTRY_PROTOCOL.equals(protocol) || SERVICE_REGISTRY_PROTOCOL.equals(protocol))
|
||||
&& registryURL != null) {
|
||||
return URLBuilder.from(registryURL)
|
||||
.setProtocol(DUBBO_PROTOCOL)
|
||||
.addParameter(PROTOCOL_KEY, protocol)
|
||||
.putAttribute(REFER_KEY, map)
|
||||
.build();
|
||||
|
||||
} else if (ConfigUtils.isNotEmpty(address) || ConfigUtils.isNotEmpty(protocol)) {
|
||||
if (!map.containsKey(PROTOCOL_KEY)) {
|
||||
if (interfaceConfig.getScopeModel().getExtensionLoader(MonitorFactory.class).hasExtension(Constants.LOGSTAT_PROTOCOL)) {
|
||||
map.put(PROTOCOL_KEY, Constants.LOGSTAT_PROTOCOL);
|
||||
} else if (ConfigUtils.isNotEmpty(protocol)) {
|
||||
map.put(PROTOCOL_KEY, protocol);
|
||||
} else {
|
||||
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
|
||||
}
|
||||
}
|
||||
if (ConfigUtils.isEmpty(address)) {
|
||||
address = LOCALHOST_VALUE;
|
||||
}
|
||||
return UrlUtils.parseURL(address, map);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.config.MonitorConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
|
||||
|
||||
@Activate
|
||||
public class MonitorConfigValidator implements ConfigValidator<MonitorConfig> {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MonitorConfigValidator.class);
|
||||
|
||||
public static boolean validateMonitorConfig(MonitorConfig config) {
|
||||
if (config != null) {
|
||||
if (!config.isValid()) {
|
||||
logger.info("There's no valid monitor config found, if you want to open monitor statistics for Dubbo, " +
|
||||
"please make sure your monitor is configured properly.");
|
||||
return false;
|
||||
}
|
||||
ConfigValidationUtils.checkParameterName(config.getParameters());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(MonitorConfig config) {
|
||||
return validateMonitorConfig(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return MonitorConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
monitor=org.apache.dubbo.config.validator.MonitorConfigValidator
|
||||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.deploy.ApplicationDeployer;
|
|||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.config.exception.ConfigValidationException;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ class CertDeployerListenerTest {
|
|||
applicationModel.getApplicationConfigManager().addMetadataReport(new MetadataReportConfig("absent"));
|
||||
|
||||
ApplicationDeployer deployer = applicationModel.getDeployer();
|
||||
Assertions.assertThrows(IllegalArgumentException.class, deployer::start);
|
||||
Assertions.assertThrows(ConfigValidationException.class, deployer::start);
|
||||
Mockito.verify(reference.get(), Mockito.times(1))
|
||||
.connect(Mockito.any());
|
||||
Mockito.verify(reference.get(), Mockito.atLeast(1))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.validate;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.FILE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.TRANSPORTER_KEY;
|
||||
|
||||
@Activate
|
||||
public class RegistryConfigValidator implements ConfigValidator<RegistryConfig> {
|
||||
|
||||
@Override
|
||||
public boolean validate(RegistryConfig config) {
|
||||
validateRegistryConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void validateRegistryConfig(RegistryConfig config) {
|
||||
ConfigValidationUtils.checkName(PROTOCOL_KEY, config.getProtocol());
|
||||
ConfigValidationUtils.checkName(USERNAME_KEY, config.getUsername());
|
||||
ConfigValidationUtils.checkLength(PASSWORD_KEY, config.getPassword());
|
||||
ConfigValidationUtils.checkPathLength(FILE_KEY, config.getFile());
|
||||
ConfigValidationUtils.checkName(TRANSPORTER_KEY, config.getTransporter());
|
||||
ConfigValidationUtils.checkName(SERVER_KEY, config.getServer());
|
||||
ConfigValidationUtils.checkName(CLIENT_KEY, config.getClient());
|
||||
ConfigValidationUtils.checkParameterName(config.getParameters());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return RegistryConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
|
||||
@Activate
|
||||
public class SslConfigValidator implements ConfigValidator<SslConfig> {
|
||||
|
||||
public static void validateSslConfig(SslConfig sslConfig) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(SslConfig config) {
|
||||
validateSslConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return SslConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
ssl=org.apache.dubbo.config.validator.SslConfigValidator
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.validator;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.common.serialize.Serialization;
|
||||
import org.apache.dubbo.common.status.StatusChecker;
|
||||
import org.apache.dubbo.common.threadpool.ThreadPool;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.context.ConfigValidator;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.remoting.Codec2;
|
||||
import org.apache.dubbo.remoting.Dispatcher;
|
||||
import org.apache.dubbo.remoting.Transporter;
|
||||
import org.apache.dubbo.remoting.exchange.Exchanger;
|
||||
import org.apache.dubbo.remoting.telnet.TelnetHandler;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.DISPATCHER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.TELNET_KEY;
|
||||
import static org.apache.dubbo.remoting.Constants.TRANSPORTER_KEY;
|
||||
|
||||
@Activate
|
||||
public class ProtocolConfigValidator implements ConfigValidator<ProtocolConfig> {
|
||||
|
||||
@Override
|
||||
public boolean validate(ProtocolConfig config) {
|
||||
validateProtocolConfig(config);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void validateProtocolConfig(ProtocolConfig config) {
|
||||
if (config != null) {
|
||||
String name = config.getName();
|
||||
ConfigValidationUtils.checkName("name", name);
|
||||
ConfigValidationUtils.checkHost(HOST_KEY, config.getHost());
|
||||
ConfigValidationUtils.checkPathName("contextpath", config.getContextpath());
|
||||
|
||||
|
||||
if (DUBBO_PROTOCOL.equals(name)) {
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), Codec2.class, CODEC_KEY, config.getCodec());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), Serialization.class, SERIALIZATION_KEY, config.getSerialization());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), Transporter.class, SERVER_KEY, config.getServer());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), Transporter.class, CLIENT_KEY, config.getClient());
|
||||
}
|
||||
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), TelnetHandler.class, TELNET_KEY, config.getTelnet());
|
||||
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), StatusChecker.class, "status", config.getStatus());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Transporter.class, TRANSPORTER_KEY, config.getTransporter());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Exchanger.class, EXCHANGER_KEY, config.getExchanger());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Dispatcher.class, DISPATCHER_KEY, config.getDispatcher());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), Dispatcher.class, "dispather", config.getDispather());
|
||||
ConfigValidationUtils.checkExtension(config.getScopeModel(), ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupport(Class<?> configClass) {
|
||||
return ProtocolConfig.class.isAssignableFrom(configClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
protocol=org.apache.dubbo.config.validator.ProtocolConfigValidator
|
||||
Loading…
Reference in New Issue