blob: fae8e668fcdaa7db1b8a30ebde24ec1af79bae0c [file] [log] [blame]
/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed 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 com.alibaba.dubbo.common.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
public class UrlUtils {
public static URL parseURL(String address, Map<String, String> defaults) {
if (address == null || address.length() == 0) {
return null;
}
String url;
if (address.indexOf("://") >= 0) {
url = address;
} else {
String[] addresses = Constants.COMMA_SPLIT_PATTERN.split(address);
url = addresses[0];
if (addresses.length > 1) {
StringBuilder backup = new StringBuilder();
for (int i = 1; i < addresses.length; i++) {
if (i > 1) {
backup.append(",");
}
backup.append(NetUtils.filterLocalHost(addresses[i]));
}
url += "?" + Constants.BACKUP_KEY + "=" + backup.toString();
}
}
String defaultProtocol = defaults == null ? null : defaults.get("protocol");
if (defaultProtocol == null || defaultProtocol.length() == 0) {
defaultProtocol = "dubbo";
}
String defaultUsername = defaults == null ? null : defaults.get("username");
String defaultPassword = defaults == null ? null : defaults.get("password");
int defaultPort = StringUtils.parseInteger(defaults == null ? null : defaults.get("port"));
String defaultPath = defaults == null ? null : defaults.get("path");
Map<String, String> defaultParameters = defaults == null ? null : new HashMap<String, String>(defaults);
if (defaultParameters != null) {
defaultParameters.remove("protocol");
defaultParameters.remove("username");
defaultParameters.remove("password");
defaultParameters.remove("host");
defaultParameters.remove("port");
defaultParameters.remove("path");
}
URL u = URL.valueOf(url);
boolean changed = false;
String protocol = u.getProtocol();
String username = u.getUsername();
String password = u.getPassword();
String host = u.getHost();
int port = u.getPort();
String path = u.getPath();
Map<String, String> parameters = new HashMap<String, String>(u.getParameters());
if ((protocol == null || protocol.length() == 0) && defaultProtocol != null && defaultProtocol.length() > 0) {
changed = true;
protocol = defaultProtocol;
}
if ((username == null || username.length() == 0) && defaultUsername != null && defaultUsername.length() > 0) {
changed = true;
username = defaultUsername;
}
if ((password == null || password.length() == 0) && defaultPassword != null && defaultPassword.length() > 0) {
changed = true;
password = defaultPassword;
}
if (u.isAnyHost() || u.isLocalHost()) {
changed = true;
host = NetUtils.getLocalHost();
}
if (port <= 0) {
if (defaultPort > 0) {
changed = true;
port = defaultPort;
} else {
changed = true;
port = 9090;
}
}
if (path == null || path.length() == 0) {
if (defaultPath != null && defaultPath.length() > 0) {
changed = true;
path = defaultPath;
}
}
if (defaultParameters != null && defaultParameters.size() > 0) {
for (Map.Entry<String, String> entry : defaultParameters.entrySet()) {
String key = entry.getKey();
String defaultValue = entry.getValue();
if (defaultValue != null && defaultValue.length() > 0) {
String value = parameters.get(key);
if (value == null || value.length() == 0) {
changed = true;
parameters.put(key, defaultValue);
}
}
}
}
if (changed) {
u = new URL(protocol, username, password, host, port, path, parameters);
}
return u;
}
public static List<URL> parseURLs(String address, Map<String, String> defaults) {
if (address == null || address.length() == 0) {
return null;
}
String[] addresses = Constants.REGISTRY_SPLIT_PATTERN.split(address);
if (addresses == null || addresses.length == 0) {
return null; //here won't be empty
}
List<URL> registries = new ArrayList<URL>();
for (String addr : addresses) {
registries.add(parseURL(addr, defaults));
}
return registries;
}
public static Map<String, Map<String, String>> convertRegister(Map<String, Map<String, String>> register) {
Map<String, Map<String, String>> newRegister = new HashMap<String, Map<String, String>>();
for (Map.Entry<String, Map<String, String>> entry : register.entrySet()) {
String serviceName = entry.getKey();
Map<String, String> serviceUrls = entry.getValue();
if (!serviceName.contains(":") && !serviceName.contains("/")) {
for (Map.Entry<String, String> entry2 : serviceUrls.entrySet()) {
String serviceUrl = entry2.getKey();
String serviceQuery = entry2.getValue();
Map<String, String> params = StringUtils.parseQueryString(serviceQuery);
String group = params.get("group");
String version = params.get("version");
//params.remove("group");
//params.remove("version");
String name = serviceName;
if (group != null && group.length() > 0) {
name = group + "/" + name;
}
if (version != null && version.length() > 0) {
name = name + ":" + version;
}
Map<String, String> newUrls = newRegister.get(name);
if (newUrls == null) {
newUrls = new HashMap<String, String>();
newRegister.put(name, newUrls);
}
newUrls.put(serviceUrl, StringUtils.toQueryString(params));
}
} else {
newRegister.put(serviceName, serviceUrls);
}
}
return newRegister;
}
public static Map<String, String> convertSubscribe(Map<String, String> subscribe) {
Map<String, String> newSubscribe = new HashMap<String, String>();
for (Map.Entry<String, String> entry : subscribe.entrySet()) {
String serviceName = entry.getKey();
String serviceQuery = entry.getValue();
if (!serviceName.contains(":") && !serviceName.contains("/")) {
Map<String, String> params = StringUtils.parseQueryString(serviceQuery);
String group = params.get("group");
String version = params.get("version");
//params.remove("group");
//params.remove("version");
String name = serviceName;
if (group != null && group.length() > 0) {
name = group + "/" + name;
}
if (version != null && version.length() > 0) {
name = name + ":" + version;
}
newSubscribe.put(name, StringUtils.toQueryString(params));
} else {
newSubscribe.put(serviceName, serviceQuery);
}
}
return newSubscribe;
}
public static Map<String, Map<String, String>> revertRegister(Map<String, Map<String, String>> register) {
Map<String, Map<String, String>> newRegister = new HashMap<String, Map<String, String>>();
for (Map.Entry<String, Map<String, String>> entry : register.entrySet()) {
String serviceName = entry.getKey();
Map<String, String> serviceUrls = entry.getValue();
if (serviceName.contains(":") || serviceName.contains("/")) {
for (Map.Entry<String, String> entry2 : serviceUrls.entrySet()) {
String serviceUrl = entry2.getKey();
String serviceQuery = entry2.getValue();
Map<String, String> params = StringUtils.parseQueryString(serviceQuery);
String name = serviceName;
int i = name.indexOf('/');
if (i >= 0) {
params.put("group", name.substring(0, i));
name = name.substring(i + 1);
}
i = name.lastIndexOf(':');
if (i >= 0) {
params.put("version", name.substring(i + 1));
name = name.substring(0, i);
}
Map<String, String> newUrls = newRegister.get(name);
if (newUrls == null) {
newUrls = new HashMap<String, String>();
newRegister.put(name, newUrls);
}
newUrls.put(serviceUrl, StringUtils.toQueryString(params));
}
} else {
newRegister.put(serviceName, serviceUrls);
}
}
return newRegister;
}
public static Map<String, String> revertSubscribe(Map<String, String> subscribe) {
Map<String, String> newSubscribe = new HashMap<String, String>();
for (Map.Entry<String, String> entry : subscribe.entrySet()) {
String serviceName = entry.getKey();
String serviceQuery = entry.getValue();
if (serviceName.contains(":") || serviceName.contains("/")) {
Map<String, String> params = StringUtils.parseQueryString(serviceQuery);
String name = serviceName;
int i = name.indexOf('/');
if (i >= 0) {
params.put("group", name.substring(0, i));
name = name.substring(i + 1);
}
i = name.lastIndexOf(':');
if (i >= 0) {
params.put("version", name.substring(i + 1));
name = name.substring(0, i);
}
newSubscribe.put(name, StringUtils.toQueryString(params));
} else {
newSubscribe.put(serviceName, serviceQuery);
}
}
return newSubscribe;
}
public static Map<String, Map<String, String>> revertNotify(Map<String, Map<String, String>> notify) {
if (notify != null && notify.size() > 0) {
Map<String, Map<String, String>> newNotify = new HashMap<String, Map<String, String>>();
for (Map.Entry<String, Map<String, String>> entry : notify.entrySet()) {
String serviceName = entry.getKey();
Map<String, String> serviceUrls = entry.getValue();
if (!serviceName.contains(":") && !serviceName.contains("/")) {
if (serviceUrls != null && serviceUrls.size() > 0) {
for (Map.Entry<String, String> entry2 : serviceUrls.entrySet()) {
String url = entry2.getKey();
String query = entry2.getValue();
Map<String, String> params = StringUtils.parseQueryString(query);
String group = params.get("group");
String version = params.get("version");
// params.remove("group");
// params.remove("version");
String name = serviceName;
if (group != null && group.length() > 0) {
name = group + "/" + name;
}
if (version != null && version.length() > 0) {
name = name + ":" + version;
}
Map<String, String> newUrls = newNotify.get(name);
if (newUrls == null) {
newUrls = new HashMap<String, String>();
newNotify.put(name, newUrls);
}
newUrls.put(url, StringUtils.toQueryString(params));
}
}
} else {
newNotify.put(serviceName, serviceUrls);
}
}
return newNotify;
}
return notify;
}
//compatible for dubbo-2.0.0
public static List<String> revertForbid(List<String> forbid, Set<URL> subscribed) {
if (forbid != null && forbid.size() > 0) {
List<String> newForbid = new ArrayList<String>();
for (String serviceName : forbid) {
if (! serviceName.contains(":") && ! serviceName.contains("/")) {
for (URL url : subscribed) {
if (serviceName.equals(url.getServiceInterface())) {
newForbid.add(url.getServiceKey());
break;
}
}
} else {
newForbid.add(serviceName);
}
}
return newForbid;
}
return forbid;
}
public static URL getEmptyUrl(String service, String category) {
String group = null;
String version = null;
int i = service.indexOf('/');
if (i > 0) {
group = service.substring(0, i);
service = service.substring(i + 1);
}
i = service.lastIndexOf(':');
if (i > 0) {
version = service.substring(i + 1);
service = service.substring(0, i);
}
return URL.valueOf(Constants.EMPTY_PROTOCOL + "://0.0.0.0/" + service + "?"
+ Constants.CATEGORY_KEY + "=" + category
+ (group == null ? "" : "&" + Constants.GROUP_KEY + "=" + group)
+ (version == null ? "" : "&" + Constants.VERSION_KEY + "=" + version));
}
public static boolean isMatchCategory(String category, String categories) {
if (categories == null || categories.length() == 0) {
return Constants.DEFAULT_CATEGORY.equals(category);
} else if (categories.contains(Constants.ANY_VALUE)) {
return true;
} else if (categories.contains(Constants.REMOVE_VALUE_PREFIX)) {
return ! categories.contains(Constants.REMOVE_VALUE_PREFIX + category);
} else {
return categories.contains(category);
}
}
public static boolean isMatch(URL consumerUrl, URL providerUrl) {
String consumerInterface = consumerUrl.getServiceInterface();
String providerInterface = providerUrl.getServiceInterface();
if( ! (Constants.ANY_VALUE.equals(consumerInterface) || StringUtils.isEquals(consumerInterface, providerInterface)) ) return false;
if (! isMatchCategory(providerUrl.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY),
consumerUrl.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY))) {
return false;
}
if (! providerUrl.getParameter(Constants.ENABLED_KEY, true)
&& ! Constants.ANY_VALUE.equals(consumerUrl.getParameter(Constants.ENABLED_KEY))) {
return false;
}
String consumerGroup = consumerUrl.getParameter(Constants.GROUP_KEY);
String consumerVersion = consumerUrl.getParameter(Constants.VERSION_KEY);
String consumerClassifier = consumerUrl.getParameter(Constants.CLASSIFIER_KEY, Constants.ANY_VALUE);
String providerGroup = providerUrl.getParameter(Constants.GROUP_KEY);
String providerVersion = providerUrl.getParameter(Constants.VERSION_KEY);
String providerClassifier = providerUrl.getParameter(Constants.CLASSIFIER_KEY, Constants.ANY_VALUE);
return (Constants.ANY_VALUE.equals(consumerGroup) || StringUtils.isEquals(consumerGroup, providerGroup) || StringUtils.isContains(consumerGroup, providerGroup))
&& (Constants.ANY_VALUE.equals(consumerVersion) || StringUtils.isEquals(consumerVersion, providerVersion))
&& (consumerClassifier == null || Constants.ANY_VALUE.equals(consumerClassifier) || StringUtils.isEquals(consumerClassifier, providerClassifier));
}
public static boolean isMatchGlobPattern(String pattern, String value, URL param) {
if (param != null && pattern.startsWith("$")) {
pattern = param.getRawParameter(pattern.substring(1));
}
return isMatchGlobPattern(pattern, value);
}
public static boolean isMatchGlobPattern(String pattern, String value) {
if ("*".equals(pattern))
return true;
if((pattern == null || pattern.length() == 0)
&& (value == null || value.length() == 0))
return true;
if((pattern == null || pattern.length() == 0)
|| (value == null || value.length() == 0))
return false;
int i = pattern.lastIndexOf('*');
// 没有找到星号
if(i == -1) {
return value.equals(pattern);
}
// 星号在末尾
else if (i == pattern.length() - 1) {
return value.startsWith(pattern.substring(0, i));
}
// 星号的开头
else if (i == 0) {
return value.endsWith(pattern.substring(i + 1));
}
// 星号的字符串的中间
else {
String prefix = pattern.substring(0, i);
String suffix = pattern.substring(i + 1);
return value.startsWith(prefix) && value.endsWith(suffix);
}
}
}