提交 80013ffc 编写于 作者: N nzomkxia

project refactor

上级 9df36ecb
......@@ -26,7 +26,6 @@ public class DubboAdminApplication {
public static void main(String[] args) {
ApplicationContext act = SpringApplication.run(DubboAdminApplication.class, args);
SpringUtil.setApplicationContext(act);
}
......
/*
* 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.admin;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import org.springframework.context.ApplicationContext;
public class SpringUtil {
public static final Logger logger = LoggerFactory.getLogger(SpringUtil.class);
private static ApplicationContext applicationContext = null;
public static void setApplicationContext(ApplicationContext applicationContext){
if(SpringUtil.applicationContext == null){
logger.info("set applicationcontext");
SpringUtil.applicationContext = applicationContext;
}
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
......@@ -15,60 +14,43 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.common.util;
package org.apache.dubbo.admin.web.pulltool;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.utils.StringUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
/**
* DateFormat Utility
*
*/
public class DateFormatUtil {
private static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final ThreadLocal<Map<String, DateFormat>> tl = new ThreadLocal<Map<String, DateFormat>>();
/**
* According to the specified format, Get a DateFormat
*
* @param format
* @return
*/
public static DateFormat getDateFormat(String format) {
Map<String, DateFormat> map = tl.get();
public class ConvertUtil {
private ConvertUtil() {
}
if (map == null) {
map = new HashMap<String, DateFormat>();
tl.set(map);
public static Map<String, String> serviceName2Map(String serviceName) {
String group = null;
String version = null;
int i = serviceName.indexOf("/");
if (i > 0) {
group = serviceName.substring(0, i);
serviceName = serviceName.substring(i + 1);
}
if (StringUtils.isEmpty(format)) {
format = DEFAULT_FORMAT;
i = serviceName.lastIndexOf(":");
if (i > 0) {
version = serviceName.substring(i + 1);
serviceName = serviceName.substring(0, i);
}
DateFormat ret = map.get(format);
if (ret == null) {
ret = new SimpleDateFormat(format);
map.put(format, ret);
Map<String, String> ret = new HashMap<String, String>();
if (!StringUtils.isEmpty(serviceName)) {
ret.put(Constants.INTERFACE_KEY, serviceName);
}
if (!StringUtils.isEmpty(version)) {
ret.put(Constants.VERSION_KEY, version);
}
if (!StringUtils.isEmpty(group)) {
ret.put(Constants.GROUP_KEY, group);
}
return ret;
}
/**
* Get Default DateFormat
*
* @return
*/
public static DateFormat getDateFormat() {
return getDateFormat(null);
}
}
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.admin.util;
package org.apache.dubbo.admin.common.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
......
......@@ -14,12 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.util;
package org.apache.dubbo.admin.common.util;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.registry.common.domain.LoadBalance;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.domain.Weight;
import org.apache.dubbo.admin.model.domain.LoadBalance;
import org.apache.dubbo.admin.model.domain.Override;
import org.apache.dubbo.admin.model.domain.Weight;
import java.util.ArrayList;
import java.util.Arrays;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.sync.util;
package org.apache.dubbo.admin.common.util;
import java.util.Map;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.route;
package org.apache.dubbo.admin.common.util;
import com.alibaba.dubbo.common.utils.StringUtils;
......
......@@ -14,10 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.route;
package org.apache.dubbo.admin.common.util;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.registry.common.domain.Route;
import org.apache.dubbo.admin.model.domain.Route;
import java.text.ParseException;
import java.util.*;
......
......@@ -14,15 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.sync.util;
package org.apache.dubbo.admin.common.util;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.registry.common.domain.Consumer;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import org.apache.dubbo.admin.registry.common.domain.Route;
import org.apache.dubbo.admin.model.domain.Consumer;
import org.apache.dubbo.admin.model.domain.Override;
import org.apache.dubbo.admin.model.domain.Provider;
import org.apache.dubbo.admin.model.domain.Route;
import java.util.ArrayList;
import java.util.HashMap;
......
/*
* 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.admin.common.util;
/**
* Tool
*
*/
public class Tool {
public static String getInterface(String service) {
if (service != null && service.length() > 0) {
int i = service.indexOf('/');
if (i >= 0) {
service = service.substring(i + 1);
}
i = service.lastIndexOf(':');
if (i >= 0) {
service = service.substring(0, i);
}
}
return service;
}
public static String getGroup(String service) {
if (service != null && service.length() > 0) {
int i = service.indexOf('/');
if (i >= 0) {
return service.substring(0, i);
}
}
return null;
}
public static String getVersion(String service) {
if (service != null && service.length() > 0) {
int i = service.lastIndexOf(':');
if (i >= 0) {
return service.substring(i + 1);
}
}
return null;
}
}
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.util;
package org.apache.dubbo.admin.common.util;
import java.util.Map;
import java.util.Map.Entry;
......
/*
* 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.admin.config;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class I18nConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(Locale.CHINA);
return sessionLocaleResolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.admin;
package org.apache.dubbo.admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......
......@@ -21,10 +21,10 @@ import com.alibaba.dubbo.common.logger.LoggerFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.admin.common.exception.ParamValidationException;
import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
import org.apache.dubbo.admin.dto.AccessDTO;
import org.apache.dubbo.admin.governance.service.RouteService;
import org.apache.dubbo.admin.registry.common.domain.Route;
import org.apache.dubbo.admin.registry.common.route.RouteRule;
import org.apache.dubbo.admin.model.dto.AccessDTO;
import org.apache.dubbo.admin.service.RouteService;
import org.apache.dubbo.admin.model.domain.Route;
import org.apache.dubbo.admin.common.util.RouteRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
......
......@@ -20,11 +20,11 @@ package org.apache.dubbo.admin.controller;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.admin.common.exception.ParamValidationException;
import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
import org.apache.dubbo.admin.dto.BalancingDTO;
import org.apache.dubbo.admin.governance.service.OverrideService;
import org.apache.dubbo.admin.registry.common.domain.LoadBalance;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.util.OverrideUtils;
import org.apache.dubbo.admin.model.dto.BalancingDTO;
import org.apache.dubbo.admin.service.OverrideService;
import org.apache.dubbo.admin.model.domain.LoadBalance;
import org.apache.dubbo.admin.model.domain.Override;
import org.apache.dubbo.admin.common.util.OverrideUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
......@@ -32,7 +32,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import static org.apache.dubbo.admin.registry.common.util.OverrideUtils.overrideToLoadBalance;
import static org.apache.dubbo.admin.common.util.OverrideUtils.overrideToLoadBalance;
@RestController
@RequestMapping("/api/{env}/rules/balancing")
......
......@@ -21,9 +21,9 @@ import com.alibaba.dubbo.common.URL;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.admin.common.exception.ParamValidationException;
import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
import org.apache.dubbo.admin.dto.OverrideDTO;
import org.apache.dubbo.admin.governance.service.OverrideService;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.model.dto.OverrideDTO;
import org.apache.dubbo.admin.service.OverrideService;
import org.apache.dubbo.admin.model.domain.Override;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
......
......@@ -20,9 +20,9 @@ package org.apache.dubbo.admin.controller;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.admin.common.exception.ParamValidationException;
import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
import org.apache.dubbo.admin.dto.RouteDTO;
import org.apache.dubbo.admin.governance.service.RouteService;
import org.apache.dubbo.admin.registry.common.domain.Route;
import org.apache.dubbo.admin.model.dto.RouteDTO;
import org.apache.dubbo.admin.service.RouteService;
import org.apache.dubbo.admin.model.domain.Route;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
......
......@@ -19,12 +19,12 @@ package org.apache.dubbo.admin.controller;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.dto.ServiceDTO;
import org.apache.dubbo.admin.dto.ServiceDetailDTO;
import org.apache.dubbo.admin.governance.service.ConsumerService;
import org.apache.dubbo.admin.governance.service.ProviderService;
import org.apache.dubbo.admin.registry.common.domain.Consumer;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import org.apache.dubbo.admin.model.dto.ServiceDTO;
import org.apache.dubbo.admin.model.dto.ServiceDetailDTO;
import org.apache.dubbo.admin.service.ConsumerService;
import org.apache.dubbo.admin.service.ProviderService;
import org.apache.dubbo.admin.model.domain.Consumer;
import org.apache.dubbo.admin.model.domain.Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......
......@@ -20,11 +20,11 @@ package org.apache.dubbo.admin.controller;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.admin.common.exception.ParamValidationException;
import org.apache.dubbo.admin.common.exception.ResourceNotFoundException;
import org.apache.dubbo.admin.dto.WeightDTO;
import org.apache.dubbo.admin.governance.service.OverrideService;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.domain.Weight;
import org.apache.dubbo.admin.registry.common.util.OverrideUtils;
import org.apache.dubbo.admin.model.dto.WeightDTO;
import org.apache.dubbo.admin.service.OverrideService;
import org.apache.dubbo.admin.model.domain.Override;
import org.apache.dubbo.admin.model.domain.Weight;
import org.apache.dubbo.admin.common.util.OverrideUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
......
/*
* 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.admin.filter;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.governance.service.UserService;
import org.apache.dubbo.admin.governance.util.WebConstants;
import org.apache.dubbo.admin.registry.common.domain.User;
import org.apache.dubbo.admin.registry.common.util.Coder;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//@Component
public class LoginFilter implements Filter{
private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class);
private static Pattern PARAMETER_PATTERN = Pattern.compile("(\\w+)=[\"]?([^,\"]+)[\"]?[,]?\\s*");
private static final String BASIC_CHALLENGE = "Basic";
private static final String DIGEST_CHALLENGE = "Digest";
private static final String CHALLENGE = BASIC_CHALLENGE;
private static final String REALM = User.REALM;
@Autowired
private UserService userService;
private String logout = "/logout";
private String logoutCookie = "logout";
static Map<String, String> parseParameters(String query) {
Matcher matcher = PARAMETER_PATTERN.matcher(query);
Map<String, String> map = new HashMap<String, String>();
while (matcher.find()) {
String key = matcher.group(1);
String value = matcher.group(2);
map.put(key, value);
}
return map;
}
static byte[] readToBytes(InputStream in) throws IOException {
byte[] buf = new byte[in.available()];
in.read(buf);
return buf;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse) response;
if (logger.isInfoEnabled()) {
logger.info("AuthorizationValve of uri: " + req.getRequestURI());
}
String uri = req.getRequestURI();
String contextPath = req.getContextPath();
if (contextPath != null && contextPath.length() > 0 && !"/".equals(contextPath)) {
uri = uri.substring(contextPath.length());
}
if (uri.equals(logout)) {
if (!isLogout(req)) {
setLogout(true, resp);
showLoginForm(resp);
} else {
setLogout(false, resp);
resp.sendRedirect(contextPath == null || contextPath.length() == 0 ? "/" : contextPath);
}
return;
}
User user = null;
String authType = null;
String authorization = req.getHeader("Authorization");
if (authorization != null && authorization.length() > 0) {
int i = authorization.indexOf(' ');
if (i >= 0) {
authType = authorization.substring(0, i);
String authPrincipal = authorization.substring(i + 1);
if (BASIC_CHALLENGE.equalsIgnoreCase(authType)) {
user = loginByBase(authPrincipal);
} else if (DIGEST_CHALLENGE.equalsIgnoreCase(authType)) {
user = loginByDigest(authPrincipal, req);
}
}
}
if (user == null || user.getUsername() == null || user.getUsername().length() == 0) {
showLoginForm(resp);
return;
//pipelineContext.breakPipeline(1);
}
if (user != null && StringUtils.isNotEmpty(user.getUsername())) {
req.getSession().setAttribute(WebConstants.CURRENT_USER_KEY, user);
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
private void showLoginForm(HttpServletResponse response) throws IOException {
if (DIGEST_CHALLENGE.equals(CHALLENGE)) {
response.setHeader("WWW-Authenticate", CHALLENGE + " realm=\"" + REALM + "\", qop=\"auth\", nonce=\""
+ UUID.randomUUID().toString().replace("-", "") + "\", opaque=\""
+ Coder.encodeMd5(REALM) + "\"");
} else {
response.setHeader("WWW-Authenticate", CHALLENGE + " realm=\"" + REALM + "\"");
}
response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store");
response.setHeader("Content-Type", "text/html; charset=iso-8859-1");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
private User getUser(String username) {
return userService.findUser(username);
}
private User loginByBase(String authorization) {
authorization = Coder.decodeBase64(authorization);
int i = authorization.indexOf(':');
String username = authorization.substring(0, i);
if (username != null && username.length() > 0) {
String password = authorization.substring(i + 1);
if (password != null && password.length() > 0) {
String passwordDigest = Coder.encodeMd5(username + ":" + REALM + ":" + password);
User user = getUser(username);
if (user != null) {
String pwd = user.getPassword();
if (pwd != null && pwd.length() > 0) {
if (passwordDigest.equals(pwd)) {
return user;
}
}
}
}
}
return null;
}
private User loginByDigest(String value, HttpServletRequest request) throws IOException {
Map<String, String> params = parseParameters(value);
String username = params.get("username");
if (username != null && username.length() > 0) {
String passwordDigest = params.get("response");
if (passwordDigest != null && passwordDigest.length() > 0) {
User user = getUser(username);
if (user != null) {
String pwd = user.getPassword();
// A valid user, validate password
if (pwd != null && pwd.length() > 0) {
String uri = params.get("uri");
String nonce = params.get("nonce");
String nc = params.get("nc");
String cnonce = params.get("cnonce");
String qop = params.get("qop");
String method = request.getMethod();
String a1 = pwd;
String a2 = "auth-int".equals(qop)
? Coder.encodeMd5(method + ":" + uri + ":" + Coder.encodeMd5(readToBytes(request.getInputStream())))
: Coder.encodeMd5(method + ":" + uri);
String digest = "auth".equals(qop) || "auth-int".equals(qop)
? Coder.encodeMd5(a1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + a2)
: Coder.encodeMd5(a1 + ":" + nonce + ":" + a2);
if (digest.equals(passwordDigest)) {
return user;
}
}
}
}
}
return null;
}
private boolean isLogout(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
if (cookie != null && logoutCookie.equals(cookie.getName())) {
return "true".equals(cookie.getValue());
}
}
}
return false;
}
private void setLogout(boolean logoutValue, HttpServletResponse response) {
response.addCookie(new Cookie(logoutCookie, String.valueOf(logoutValue)));
}
}
/*
* 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.admin.governance.biz.common.i18n;
public interface MessageResourceService {
public String get(String key, Object... args);
public String getMessage(String key, Object... args);
}
/*
* 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.admin.governance.biz.common.i18n.impl;
import org.apache.dubbo.admin.governance.biz.common.i18n.MessageResourceService;
import org.apache.dubbo.admin.web.mvc.common.i18n.LocaleUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.stereotype.Component;
@Component
public class MessageResourceServiceImpl implements MessageResourceService {
@Autowired
private MessageSource messageSource;
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
public String get(String key, Object... args) {
try {
if (messageSource != null) {
return messageSource.getMessage(key, args, key, LocaleUtil.getLocale());
}
return key;
} catch (NoSuchMessageException e) {
return key;
}
}
public String getMessage(String key, Object... args) {
return get(key, args);
}
}
/*
* 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.admin.governance.service;
import org.apache.dubbo.admin.registry.common.domain.User;
import java.util.List;
/**
* UserService
*
*/
public interface UserService {
List<User> findAllUsers();
User findUser(String username);
User findById(Long id);
void createUser(User user);
void updateUser(User user);
void modifyUser(User user);
boolean updatePassword(User user, String oldPassword);
void resetPassword(User user);
void enableUser(User user);
void disableUser(User user);
void deleteUser(User user);
}
///*
// * 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.admin.governance.service.impl;
//
//import org.apache.dubbo.admin.governance.service.UserService;
//import org.apache.dubbo.admin.registry.common.domain.User;
//import org.apache.dubbo.admin.registry.common.util.Coder;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Component;
//
//import java.util.List;
//import java.util.Map;
//
///**
// * IBatisUserService
// *
// */
//@Component
//public class UserServiceImpl extends AbstractService implements UserService {
//
//// @Value("${spring.root.password}")
//// private String rootPassword;
//// @Value("${spring.guest.password}")
//// private String guestPassword;
//
// public void setRootPassword(String password) {
// this.rootPassword = (password == null ? "" : password);
// }
//
// public void setGuestPassword(String password) {
// this.guestPassword = (password == null ? "" : password);
// }
//
// public User findUser(String username) {
// if ("guest".equals(username)) {
// User user = new User();
// user.setUsername(username);
// user.setPassword(Coder.encodeMd5(username + ":" + User.REALM + ":" + guestPassword));
// user.setName(username);
// user.setRole(User.GUEST);
// user.setEnabled(true);
// user.setLocale("zh");
// user.setServicePrivilege("");
// return user;
// } else if ("root".equals(username)) {
// User user = new User();
// user.setUsername(username);
// user.setPassword(Coder.encodeMd5(username + ":" + User.REALM + ":" + rootPassword));
// user.setName(username);
// user.setRole(User.ROOT);
// user.setEnabled(true);
// user.setLocale("zh");
// user.setServicePrivilege("*");
// return user;
// }
// return null;
// }
//
// public List<User> findAllUsers() {
// // TODO Auto-generated method stub
// return null;
// }
//
// public Map<String, User> findAllUsersMap() {
// // TODO Auto-generated method stub
// return null;
// }
//
// public User findById(Long id) {
// // TODO Auto-generated method stub
// return null;
// }
//
// public void createUser(User user) {
// // TODO Auto-generated method stub
//
// }
//
// public void updateUser(User user) {
// // TODO Auto-generated method stub
//
// }
//
// public void modifyUser(User user) {
// // TODO Auto-generated method stub
//
// }
//
// public boolean updatePassword(User user, String oldPassword) {
// // TODO Auto-generated method stub
// return false;
// }
//
// public void resetPassword(User user) {
// // TODO Auto-generated method stub
//
// }
//
// public void enableUser(User user) {
// // TODO Auto-generated method stub
//
// }
//
// public void disableUser(User user) {
// // TODO Auto-generated method stub
//
// }
//
// public void deleteUser(User user) {
// // TODO Auto-generated method stub
//
// }
//
// public List<User> findUsersByServiceName(String serviceName) {
// // TODO Auto-generated method stub
// return null;
// }
//
//}
/*
* 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.admin.governance.util;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.status.StatusChecker;
import org.apache.dubbo.admin.registry.common.StatusManager;
import org.springframework.beans.factory.InitializingBean;
public class GovernanceWarmup implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(GovernanceWarmup.class);
private StatusChecker memoryStatusChecker;
private StatusChecker threadPoolStatusChecker;
private StatusChecker cacheStatusChecker;
private StatusChecker databaseStatusChecker;
private StatusChecker failureStatusChecker;
private StatusChecker loadStatusChecker;
private StatusChecker SocketStatusChecker;
private StatusChecker timerStatusChecker;
private StatusChecker warmupStatusChecker;
public void afterPropertiesSet() throws Exception {
logger.info("Registry Console warn up.");
StatusManager statusManager = StatusManager.getInstance();
statusManager.addStatusHandler("memory", memoryStatusChecker);
statusManager.addStatusHandler("load", loadStatusChecker);
// statusManager.addStatusHandler("database",databaseStatusChecker);
// statusManager.addStatusHandler("cache",cacheStatusChecker);
// statusManager.addStatusHandler("threadpool",threadPoolStatusChecker);
// statusManager.addStatusHandler("failure",failureStatusChecker);
// statusManager.addStatusHandler("socket",SocketStatusChecker);
// statusManager.addStatusHandler("threadpool",threadPoolStatusChecker);
// statusManager.addStatusHandler("timer",timerStatusChecker);
// statusManager.addStatusHandler("warmup",warmupStatusChecker);
}
public void setMemoryStatusChecker(StatusChecker memoryStatusChecker) {
this.memoryStatusChecker = memoryStatusChecker;
}
public void setThreadPoolStatusChecker(StatusChecker threadPoolStatusChecker) {
this.threadPoolStatusChecker = threadPoolStatusChecker;
}
public void setCacheStatusChecker(StatusChecker cacheStatusChecker) {
this.cacheStatusChecker = cacheStatusChecker;
}
public void setDatabaseStatusChecker(StatusChecker databaseStatusChecker) {
this.databaseStatusChecker = databaseStatusChecker;
}
public void setFailureStatusChecker(StatusChecker failureStatusChecker) {
this.failureStatusChecker = failureStatusChecker;
}
public void setLoadStatusChecker(StatusChecker loadStatusChecker) {
this.loadStatusChecker = loadStatusChecker;
}
public void setSocketStatusChecker(StatusChecker socketStatusChecker) {
SocketStatusChecker = socketStatusChecker;
}
public void setTimerStatusChecker(StatusChecker timerStatusChecker) {
this.timerStatusChecker = timerStatusChecker;
}
public void setWarmupStatusChecker(StatusChecker warmupStatusChecker) {
this.warmupStatusChecker = warmupStatusChecker;
}
}
/*
* 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.admin.governance.util;
import java.io.Serializable;
/**
* TODO Comment of Paginator
*
*/
public class Paginator implements Serializable, Cloneable {
private static final long serialVersionUID = 3688506614705500726L;
// The default number of items per page; default is 10
int itemsPerPage = 10;
// Sliding window default size; default: 7
int sliderSize = 7;
// The current page.
int currentPage;
// The current page.
String path;
// total mumber of items
int totalItems;
// total number of pages
int totalPage;
/**
* The most simple paging constructor.
*
* @param currentPage
* @param totalItems
* @param path
*/
public Paginator(int currentPage, int totalItems, String path) {
initPagination(currentPage, totalItems, 0, 0, path);
}
public Paginator(String currentPage, int totalItems, String path) {
int currentPageTemp = 1;
if (!(currentPage == null || currentPage.equals(""))) {
currentPageTemp = Integer.parseInt(currentPage);
}
initPagination(currentPageTemp, totalItems, 0, 0, path);
}
/**
* Complete paging constructor.
*
* @param currentPageT
* @param totalItemsT
* @param sliderSizeT
* @param itemsPerPageT
* @param path
*/
public void initPagination(int currentPageT, int totalItemsT, int sliderSizeT, int itemsPerPageT, String path) {
this.totalItems = (totalItemsT > 0) ? totalItemsT : 0;
this.sliderSize = (sliderSizeT > 0) ? sliderSizeT : sliderSize;
this.itemsPerPage = (itemsPerPageT > 0) ? itemsPerPageT : itemsPerPage;
this.totalPage = totalItems / itemsPerPage + (totalItems % itemsPerPage == 0 ? 0 : 1);
this.currentPage = (currentPageT > 0) ? currentPageT : 1;
this.currentPage = currentPage < totalPage ? currentPage : totalPage;
this.currentPage = (currentPage == 0) ? 1 : currentPage;
this.path = path;
}
public int getItemsPerPage() {
return this.itemsPerPage;
}
/**
* Get a sliding window of fixed size, and the current page should lie in the middle of the sliding window.
* For example: a total of 13 pages, the current page is page 5, a size of 5 sliding window should consists of 3,4,5,6,7, page 5 is placed in the middle. If the current page is 12, the return page number should be 9, 10, 11, 12, 13.
*
* @return An array containing page numbers, or an empty array if the specified sliding window size is less than 1 or the total number of pages is zero.
*/
public int[] getSlider() {
int width = sliderSize;
if ((totalItems < 1)) {
return new int[0];
} else {
if (width > totalPage) {
width = totalPage;
}
int[] slider = new int[width];
int startPage = currentPage - ((width - 1) / 2);
if (startPage < 1) {
startPage = 1;
}
if (((startPage + width) - 1) > totalPage) {
startPage = totalPage - width + 1;
}
for (int i = 0; i < width; i++) {
slider[i] = startPage + i;
}
return slider;
}
}
/**
* Construction pagination toolbar
*/
public String getPaginatorBar() {
StringBuffer str = new StringBuffer("<div class=\"page\">");
str.append("<script type=\"text/javascript\">function gotoPage(page){window.location.href=\"/" + path
+ "/pages/\" + page;}</script>");
// generate flip section
// The total number of records
str.append("total items: " + this.totalItems + "&nbsp;&nbsp;");
// 2. Pages: current page / total pages
str.append("page " + this.currentPage + " of " + this.totalPage + "nbsp;&nbsp;");
// 3. Home, Previous
if (this.currentPage > 1) {
str.append("<a class=\"prev\" href=\"#\" onclick=\"gotoPage(1);\">Home</a>");
str.append("<a class=\"prev\" href=\"#\" onclick=\"gotoPage(" + (this.currentPage - 1) + ");\">Previous</a>");
} else {
str.append("<a class=\"prev\" href=\"#\">Home</a>");
str.append("<a class=\"prev\" href=\"#\">Previous</a>");
}
// 4. Activity block
int[] slider = getSlider();
for (int i = 0; i < slider.length; i++) {
if (slider[i] == this.currentPage) {
str.append("<a class=\"num current_num\" href=\"#\">");
} else {
str.append("<a class=\"num\" href=\"#\" onclick=\"gotoPage(" + slider[i] + ");\">");
}
str.append(slider[i] + "</a>");
}
// 5. Next page
if (this.currentPage < this.totalPage) {
str.append("<a class=\"prev\" href=\"#\" onclick=\"gotoPage(" + (this.currentPage + 1) + ");\">");
} else {
str.append("<a class=\"prev\" href=\"#\">");
}
str.append("Next</a>&nbsp;&nbsp;");
// 6. Jump section
str.append("jump to page ");
str.append("<SELECT size=1 onchange=\"gotoPage(this.value);\">");
for (int i = 1; i < this.totalPage + 1; i++) {
if (i == this.currentPage) {
str.append("<OPTION value=" + i + " selected>" + i + "</OPTION>");
} else {
str.append("<OPTION value=" + i + ">" + i + "</OPTION>");
}
}
str.append("</SELECT>");
// 7. Implicit conditions
str.append("</div>");
return str.toString();
}
/**
* Get the initial record
*
* @return
*/
public int getStartIndex() {
return (this.currentPage - 1) * this.itemsPerPage + 1;
}
}
/*
* 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.admin.governance.util;
import java.util.HashMap;
import java.util.Map;
/**
* Contains the constants used in the web layer
*
*/
public class WebConstants {
/**
* In the session to save the current user object's key.
*/
public static final String CURRENT_USER_KEY = "currentUser";
/**
* The current registered server address
*/
public static final String REGISTRY_ADDRESS = "registryAddress";
/**
* Service exposed address
*/
public static final String SERVICE_URL = "serviceUrl";
/**
* Service name
*/
public static final String SERVICE_NAME = "serviceName";
/**
* Service name
*/
public static final String ENTRY = "entry";
/**
* buc sso logout
*/
public static final String SSO_LOGOUT_URL = "SSO_LOGOUT_URL";
/**
* buc sso logon
*/
public static final String BUC_SSO_USERNAME = "buc_sso_username";
/**
* Operation record page The default page record shows the number of records
*/
public static final Integer OPRATION_RECORDS_PAGE_SIZE = 100;
/**
* Help Url
*/
public static final String HELP_URL="https://github.com/apache/incubator-dubbo-ops";
Map<String, Object> context;
public static final Map<String, String> mapper = new HashMap<>();
static {
mapper.put("providers", "providersController");
mapper.put("consumers", "consumersController");
mapper.put("applications", "applicationsController");
mapper.put("routes", "routesController");
mapper.put("overrides", "overridesController");
mapper.put("accesses", "accessesController");
mapper.put("loadbalances", "loadbalancesController");
mapper.put("owners", "ownersController");
mapper.put("weights", "weightsController");
mapper.put("addresses", "addressesController");
mapper.put("services", "servicesController");
}
}
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
public class Access extends Entity {
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* Specifies the applied Quality of Service Level Agreement (SLA) object.
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* Service online approval.
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* Service online / offline approval
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* Service change information object
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
public class Cluster extends Entity {
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* Config instance
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* Document
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import java.io.Serializable;
import java.util.Date;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
public class Favorite extends Entity {
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* System features
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
public class Layer extends Entity {
private static final long serialVersionUID = 6114868933223039253L;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* LoadBalance
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
/**
* Mock
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import java.util.Arrays;
import java.util.Collections;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
public class Owner extends Entity {
......
......@@ -14,11 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import org.apache.dubbo.admin.registry.common.registry.ConvertUtil;
import org.apache.dubbo.admin.common.util.ConvertUtil;
import java.util.Date;
import java.util.List;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import java.util.Date;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
......
......@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
import org.apache.dubbo.admin.registry.common.route.ParseUtils;
import org.apache.dubbo.admin.common.util.ParseUtils;
import java.util.Arrays;
import java.util.List;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.registry.common.domain;
package org.apache.dubbo.admin.model.domain;
public class Weight extends Entity {
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
import java.util.Set;
......
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
public class BalancingDTO extends BaseDTO{
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
/**
* BaseDTO
......
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
import java.util.Map;
......
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
public class RouteDTO extends BaseDTO{
private String app;
......
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
import org.apache.commons.lang3.StringUtils;
......
......@@ -15,10 +15,10 @@
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
import org.apache.dubbo.admin.registry.common.domain.Consumer;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import org.apache.dubbo.admin.model.domain.Consumer;
import org.apache.dubbo.admin.model.domain.Provider;
import java.util.List;
......
......@@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.admin.dto;
package org.apache.dubbo.admin.model.dto;
public class WeightDTO extends BaseDTO{
......
/*
* 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.admin.registry.common;
public interface ChangeListener {
/**
* Invoked when data changed
*
* @param type data type
*/
void onChanged(String type);
}
/*
* 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.admin.registry.common;
import com.alibaba.dubbo.common.status.Status;
import com.alibaba.dubbo.common.status.Status.Level;
import com.alibaba.dubbo.common.status.StatusChecker;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* StatusManager
*
*/
public class StatusManager {
private static final StatusManager INSTANCE = new StatusManager();
private final Map<String, StatusChecker> statusHandlers = new ConcurrentHashMap<String, StatusChecker>();
private StatusManager() {
}
public static StatusManager getInstance() {
return INSTANCE;
}
public static Status getStatusSummary(Map<String, Status> statusList) {
return getSummaryStatus(statusList);
}
public static Status getSummaryStatus(Map<String, Status> statuses) {
Level level = Level.OK;
StringBuilder msg = new StringBuilder();
for (Map.Entry<String, Status> entry : statuses.entrySet()) {
String key = entry.getKey();
Status status = entry.getValue();
Level l = status.getLevel();
if (Level.ERROR.equals(l)) {
level = Level.ERROR;
if (msg.length() > 0) {
msg.append(",");
}
msg.append(key);
} else if (Level.WARN.equals(l)) {
if (!Level.ERROR.equals(level)) {
level = Level.WARN;
}
if (msg.length() > 0) {
msg.append(",");
}
msg.append(key);
}
}
return new Status(level, msg.toString());
}
public void addStatusHandler(String name, StatusChecker statusHandler) {
this.statusHandlers.put(name, statusHandler);
}
public void addStatusHandlers(Map<String, StatusChecker> statusHandlers) {
this.statusHandlers.putAll(statusHandlers);
}
public void addStatusHandlers(Collection<StatusChecker> statusHandlers) {
for (StatusChecker statusChecker : statusHandlers) {
String name = statusChecker.getClass().getSimpleName();
if (name.endsWith(StatusChecker.class.getSimpleName())) {
name = name.substring(0, name.length() - StatusChecker.class.getSimpleName().length());
}
this.statusHandlers.put(name, statusChecker);
}
}
public void removeStatusHandler(String name) {
this.statusHandlers.remove(name);
}
public void clearStatusHandlers() {
this.statusHandlers.clear();
}
public Map<String, Status> getStatusList() {
return getStatusList(null);
}
/**
* Exclude items do not need to show in Summary Page
*/
public Map<String, Status> getStatusList(String[] excludes) {
Map<String, Status> statuses = new HashMap<String, Status>();
Map<String, StatusChecker> temp = new HashMap<String, StatusChecker>();
temp.putAll(statusHandlers);
if (excludes != null && excludes.length > 0) {
for (String exclude : excludes) {
temp.remove(exclude);
}
}
for (Map.Entry<String, StatusChecker> entry : temp.entrySet()) {
statuses.put(entry.getKey(), entry.getValue().check());
}
return statuses;
}
}
/*
* 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.admin.registry.common.domain;
import java.util.ArrayList;
import java.util.List;
/**
* DependItem
*
*/
public class DependItem {
private final List<Integer> recursives = new ArrayList<Integer>();
private String application;
private int index;
private int level;
private DependItem parent;
public DependItem() {
}
public DependItem(String application, int level) {
this.application = application;
this.level = level;
}
public DependItem(DependItem parent, String application, int level, int index) {
this.parent = parent;
this.application = application;
this.level = level;
this.index = index;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getApplication() {
return application;
}
public void setApplication(String application) {
this.application = application;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public DependItem getParent() {
return parent;
}
public void setParent(DependItem parent) {
this.parent = parent;
}
public List<Integer> getRecursives() {
return recursives;
}
public void addRecursive(int padding, int value) {
while (recursives.size() < padding) {
recursives.add(0);
}
recursives.add(value);
}
public String toString() {
return "DependItem [application=" + application + ", index=" + index + ", level=" + level
+ "]";
}
}
/*
* 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.admin.registry.common.domain;
import java.io.Serializable;
public class Dependency implements Serializable {
private static final long serialVersionUID = 8526869025719540547L;
private String providerApplication;
private String consumerApplication;
public String getProviderApplication() {
return providerApplication;
}
public void setProviderApplication(String providerApplication) {
this.providerApplication = providerApplication;
}
public String getConsumerApplication() {
return consumerApplication;
}
public void setConsumerApplication(String consumerApplication) {
this.consumerApplication = consumerApplication;
}
}
/*
* 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.admin.registry.common.domain;
import java.io.Serializable;
import java.util.List;
/**
* PageList
*
*/
public class PageList<T> implements Serializable {
private static final long serialVersionUID = 43869560130672722L;
private int start;
private int limit;
private int total;
private List<T> list;
public PageList() {
}
public PageList(int start, int limit, int total, List<T> list) {
this.start = start;
this.limit = limit;
this.total = total;
this.list = list;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public int getPageCount() {
int lim = limit;
if (limit < 1) {
lim = 1;
}
int page = total / lim;
if (page < 1) {
return 1;
}
int remain = total % lim;
if (remain > 0) {
page += 1;
}
return page;
}
}
/*
* 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.admin.registry.common.domain;
public class SearchHistory extends Entity {
private static final long serialVersionUID = -1281982267153430266L;
private String name;
private String type;
private String url;
public SearchHistory() {
}
public SearchHistory(Long id) {
super(id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
/*
* 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.admin.registry.common.domain;
/**
* Test
*
*/
public class Test extends Entity {
private static final long serialVersionUID = 872527738197173003L;
private String name;
private String service;
private String method;
private String parameters;
private boolean exception;
private String result;
private String username;
private boolean autoRun;
public Test() {
}
public Test(Long id) {
super(id);
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getParameters() {
return parameters;
}
public void setParameters(String parameters) {
this.parameters = parameters;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public boolean isException() {
return exception;
}
public void setException(boolean exception) {
this.exception = exception;
}
public boolean isAutoRun() {
return autoRun;
}
public void setAutoRun(boolean autoRun) {
this.autoRun = autoRun;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/*
* 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.admin.registry.common.registry;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.utils.StringUtils;
import java.util.HashMap;
import java.util.Map;
public class ConvertUtil {
private ConvertUtil() {
}
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 && !"0.0.0".equals(version)) {
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 && !"0.0.0".equals(version)) {
name = name + ":" + version;
}
newSubscribe.put(name, StringUtils.toQueryString(params));
} else {
newSubscribe.put(serviceName, serviceQuery);
}
}
return newSubscribe;
}
public static Map<String, String> serviceName2Map(String serviceName) {
String group = null;
String version = null;
int i = serviceName.indexOf("/");
if (i > 0) {
group = serviceName.substring(0, i);
serviceName = serviceName.substring(i + 1);
}
i = serviceName.lastIndexOf(":");
if (i > 0) {
version = serviceName.substring(i + 1);
serviceName = serviceName.substring(0, i);
}
Map<String, String> ret = new HashMap<String, String>();
if (!StringUtils.isEmpty(serviceName)) {
ret.put(Constants.INTERFACE_KEY, serviceName);
}
if (!StringUtils.isEmpty(version)) {
ret.put(Constants.VERSION_KEY, version);
}
if (!StringUtils.isEmpty(group)) {
ret.put(Constants.GROUP_KEY, group);
}
return ret;
}
}
/*
* 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.admin.registry.common.route;
import com.alibaba.dubbo.common.Constants;
import org.apache.dubbo.admin.registry.common.domain.Consumer;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class OverrideUtils {
public static final Comparator<Override> OVERRIDE_COMPARATOR = new Comparator<Override>() {
public int compare(Override o1, Override o2) {
if (o1 == null && o2 == null) {
return 0;
}
if (o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
int cmp = cmp(o1.getAddress(), o2.getAddress());
if (cmp != 0) {
return cmp;
}
cmp = cmp(o1.getApplication(), o2.getApplication());
if (cmp != 0) {
return cmp;
}
return cmp(o1.getService(), o2.getService());
}
private int cmp(String s1, String s2) {
if (s1 == null && s2 == null) {
return 0;
}
if (s1 == null) {
return -1;
}
if (s2 == null) {
return 1;
}
if (s1.equals(s2)) {
return 0;
}
if (isAny(s1)) {
return 1;
}
if (isAny(s2)) {
return -1;
}
return s1.compareTo(s2);
}
private boolean isAny(String s) {
return s == null || s.length() == 0 || Constants.ANY_VALUE.equals(s) || Constants.ANYHOST_VALUE.equals(s);
}
};
public static void setConsumerOverrides(Consumer consumer, List<Override> overrides) {
if (consumer == null || overrides == null) {
return;
}
List<Override> result = new ArrayList<Override>(overrides.size());
for (Override override : overrides) {
if (!override.isEnabled()) {
continue;
}
if (override.isMatch(consumer)) {
result.add(override);
}
if (override.isUniqueMatch(consumer)) {
consumer.setOverride(override);
}
}
Collections.sort(result, OverrideUtils.OVERRIDE_COMPARATOR);
consumer.setOverrides(result);
}
public static void setProviderOverrides(Provider provider, List<Override> overrides) {
if (provider == null || overrides == null) {
return;
}
List<Override> result = new ArrayList<Override>(overrides.size());
for (Override override : overrides) {
if (!override.isEnabled()) {
continue;
}
if (override.isMatch(provider)) {
result.add(override);
}
if (override.isUniqueMatch(provider)) {
provider.setOverride(override);
}
}
provider.setOverrides(overrides);
}
}
/*
* 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.admin.registry.common.route;
import com.alibaba.dubbo.common.utils.StringUtils;
import java.util.*;
import java.util.Map.Entry;
public class RouteRuleUtils {
private RouteRuleUtils() {
}
/**
* When one of the value that is bound to a specific key of a condition is expanded, it is merged into another value of a specified key.
* @param <T> generic type
* @param condition
* @param srcKeyName the key to expand
* @param destKeyName the key to merge into
* @param expandName2Set the mapping of values to values that are carried out
*/
public static <T extends Collection<String>> Map<String, RouteRule.MatchPair> expandCondition(
Map<String, RouteRule.MatchPair> condition, String srcKeyName, String destKeyName,
Map<String, T> expandName2Set) {
if (null == condition || StringUtils.isEmpty(srcKeyName) || StringUtils.isEmpty(destKeyName)) {
return condition;
}
RouteRule.MatchPair matchPair = condition.get(srcKeyName);
if (matchPair == null) {
return condition;
}
Map<String, RouteRule.MatchPair> ret = new HashMap<String, RouteRule.MatchPair>();
Iterator<Entry<String, RouteRule.MatchPair>> iterator = condition.entrySet().iterator();
for (; iterator.hasNext(); ) {
Entry<String, RouteRule.MatchPair> entry = iterator.next();
String condName = entry.getKey();
// Neither source nor destination
if (!condName.equals(srcKeyName) && !condName.equals(destKeyName)) {
RouteRule.MatchPair p = entry.getValue();
if (p != null) ret.put(condName, p);
}
// equals with source
else if (condName.equals(srcKeyName)) {
RouteRule.MatchPair from = condition.get(srcKeyName);
RouteRule.MatchPair to = condition.get(destKeyName);
// no items to Expand
if (from == null || from.getMatches().isEmpty() && from.getUnmatches().isEmpty()) {
if (to != null) ret.put(destKeyName, to);
continue;
}
Set<String> matches = new HashSet<String>();
Set<String> unmatches = new HashSet<String>();
// add items from source Expand key
for (String s : from.getMatches()) {
if (expandName2Set == null || !expandName2Set.containsKey(s)) continue;
matches.addAll(expandName2Set.get(s));
}
for (String s : from.getUnmatches()) {
if (expandName2Set == null || !expandName2Set.containsKey(s)) continue;
unmatches.addAll(expandName2Set.get(s));
}
// add the original items
if (to != null) {
matches.addAll(to.getMatches());
unmatches.addAll(to.getUnmatches());
}
ret.put(destKeyName, new RouteRule.MatchPair(matches, unmatches));
}
// else, it must be Key == destKeyName, do nothing
}
return ret;
}
/**
* Check whether the KV (key=value pair of Provider or Consumer) matches the conditions.
*
* @param condition can contains variable definition. For example, <code>{key1={matches={value1,value2,$var1},unmatches={Vx,Vy,$var2}}}</code>
* @param valueParams Set of values of interpolated variables in a condition
* @param kv key=value pair of Provider or Consumer
* @see RouteRule
*/
public static boolean isMatchCondition(Map<String, RouteRule.MatchPair> condition,
Map<String, String> valueParams, Map<String, String> kv) {
if (condition != null && condition.size() > 0) {
for (Map.Entry<String, RouteRule.MatchPair> entry : condition.entrySet()) {
String condName = entry.getKey();
RouteRule.MatchPair p = entry.getValue();
String value = kv.get(condName);
Set<String> matches = p.getMatches();
if (matches != null && matches.size() > 0
&& !ParseUtils.isMatchGlobPatternsNeedInterpolate(matches, valueParams, value)) { // if V is null, return false
// don't match matches
return false;
}
Set<String> unmatches = p.getUnmatches();
if (unmatches != null && unmatches.size() > 0
&& ParseUtils.isMatchGlobPatternsNeedInterpolate(unmatches, valueParams, value)) {
// match unmatches
return false;
}
}
}
return true;
}
/**
* Return services that can match When Condition in Route Rule, use Glob Pattern.
*/
public static Set<String> filterServiceByRule(List<String> services, RouteRule rule) {
if (null == services || services.isEmpty() || rule == null) {
return new HashSet<String>();
}
RouteRule.MatchPair p = rule.getWhenCondition().get("service");
if (p == null) {
return new HashSet<String>();
}
Set<String> filter = ParseUtils.filterByGlobPattern(p.getMatches(), services);
Set<String> set = ParseUtils.filterByGlobPattern(p.getUnmatches(), services);
filter.addAll(set);
return filter;
}
}
/*
* 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.admin.registry.common.route;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import org.apache.dubbo.admin.registry.common.domain.Route;
import org.apache.dubbo.admin.web.pulltool.Tool;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
/**
* RouteParser route rule parse tool。
*
*/
public class RouteUtils {
public static boolean matchRoute(String consumerAddress, String consumerQueryUrl, Route route, Map<String, List<String>> clusters) {
RouteRule rule = RouteRule.parseQuitely(route);
Map<String, RouteRule.MatchPair> when = RouteRuleUtils.expandCondition(
rule.getWhenCondition(), "consumer.cluster", "consumer.host", clusters);
Map<String, String> consumerSample = ParseUtils.parseQuery("consumer.", consumerQueryUrl);
final int index = consumerAddress.lastIndexOf(":");
String consumerHost = null;
if (index != -1) {
consumerHost = consumerAddress.substring(0, index);
} else {
consumerHost = consumerAddress;
}
consumerSample.put("consumer.host", consumerHost);
return RouteRuleUtils.isMatchCondition(when, consumerSample, consumerSample);
}
public static Map<String, String> previewRoute(String serviceName, String consumerAddress, String queryUrl, Map<String, String> serviceUrls,
Route route, Map<String, List<String>> clusters, List<Route> routed) {
if (null == route) {
throw new IllegalArgumentException("Route is null.");
}
List<Route> routes = new ArrayList<Route>();
routes.add(route);
return route(serviceName, consumerAddress, queryUrl, serviceUrls, routes, clusters, routed);
}
/**
* @return Map<methodName, Route>
*/
public static List<Route> findUsedRoute(String serviceName, String consumerAddress, String consumerQueryUrl,
List<Route> routes, Map<String, List<String>> clusters) {
List<Route> routed = new ArrayList<Route>();
Map<String, String> urls = new HashMap<String, String>();
urls.put("dubbo://" + consumerAddress + "/" + serviceName, consumerQueryUrl);
RouteUtils.route(serviceName, consumerAddress, consumerQueryUrl, urls, routes, clusters, routed);
return routed;
}
public static List<Provider> route(String serviceName, String consumerAddress, String consumerQueryUrl, List<Provider> providers,
List<Override> overrides, List<Route> routes, Map<String, List<String>> clusters, List<Route> routed) {
if (providers == null) {
return null;
}
Map<String, String> urls = new HashMap<String, String>();
urls.put("consumer://" + consumerAddress + "/" + serviceName, consumerQueryUrl); // not empty dummy data
for (Provider provider : providers) {
if (Tool.isProviderEnabled(provider, overrides)) {
urls.put(provider.getUrl(), provider.getParameters());
}
}
urls = RouteUtils.route(serviceName, consumerAddress, consumerQueryUrl, urls, routes, clusters, routed);
List<Provider> result = new ArrayList<Provider>();
for (Provider provider : providers) {
if (urls.containsKey(provider.getUrl())) {
result.add(provider);
}
}
return result;
}
/**
* @param serviceName e.g. {@code com.alibaba.morgan.MemberService}
* @param consumerAddress e.g. {@code 192.168.1.3:54333}
* @param consumerQueryUrl metadata of subscribe url, e.g. <code>aplication=nasdaq&dubbo=2.0.3&methods=updateItems,validateNew&revision=1.7.0</code>
* @param serviceUrls providers
* @param routes all route rules
* @param clusters all clusters
* @return route result, Map<url-body, url-params>
*/
// FIXME The combination of clusters and routes can be done in advance when clusters or routes changes
// FIXME Separating the operation of Cache from the Util method
public static Map<String, String> route(String serviceName, String consumerAddress, String consumerQueryUrl, Map<String, String> serviceUrls,
List<Route> routes, Map<String, List<String>> clusters, List<Route> routed) {
if (serviceUrls == null || serviceUrls.size() == 0) {
return serviceUrls;
}
if (routes == null || routes.isEmpty()) {
return serviceUrls;
}
Map<Long, RouteRule> rules = route2RouteRule(routes, clusters);
final Map<String, String> consumerSample = ParseUtils.parseQuery("consumer.", consumerQueryUrl);
final int index = consumerAddress.lastIndexOf(":");
final String consumerHost;
if (consumerAddress != null && index != -1) {
consumerHost = consumerAddress.substring(0, index);
} else {
consumerHost = consumerAddress;
}
consumerSample.put("consumer.host", consumerHost);
Map<String, Map<String, String>> url2ProviderSample = new HashMap<String, Map<String, String>>();
for (Map.Entry<String, String> entry : serviceUrls.entrySet()) {
URI uri;
try {
uri = new URI(entry.getKey());
} catch (URISyntaxException e) {
throw new IllegalStateException("fail to parse url(" + entry.getKey() + "):" + e.getMessage(), e);
}
Map<String, String> sample = new HashMap<String, String>();
sample.putAll(ParseUtils.parseQuery("provider.", entry.getValue()));
sample.put("provider.protocol", uri.getScheme());
sample.put("provider.host", uri.getHost());
sample.put("provider.port", String.valueOf(uri.getPort()));
url2ProviderSample.put(entry.getKey(), sample);
}
Map<String, Set<String>> url2Methods = new HashMap<String, Set<String>>();
// Consumer can specify the required methods through the consumer.methods Key
String methodsString = consumerSample.get("consumer.methods");
String[] methods = methodsString == null || methodsString.length() == 0 ? new String[]{Route.ALL_METHOD} : methodsString.split(ParseUtils.METHOD_SPLIT);
for (String method : methods) {
consumerSample.put("method", method);
// NOTE:
// <*method>only configure <no method key>
// if method1 matches <no method key> and <method = method1>, we should reduce the priority of <no method key>.
if (routes != null && routes.size() > 0) {
for (Route route : routes) {
if (isSerivceNameMatched(route.getService(), serviceName)) {
RouteRule rule = rules.get(route.getId());
// matches When Condition
if (rule != null && RouteRuleUtils.isMatchCondition(
rule.getWhenCondition(), consumerSample, consumerSample)) {
if (routed != null && !routed.contains(route)) {
routed.add(route);
}
Map<String, RouteRule.MatchPair> then = rule.getThenCondition();
if (then != null) {
Map<String, Map<String, String>> tmp = getUrlsMatchedCondition(then, consumerSample, url2ProviderSample);
// If the result of the rule is empty, the rule is invalid and all Provider is used.
if (route.isForce() || !tmp.isEmpty()) {
url2ProviderSample = tmp;
}
}
}
}
}
}
for (String url : url2ProviderSample.keySet()) {
Set<String> mts = url2Methods.get(url);
if (mts == null) {
mts = new HashSet<String>();
url2Methods.put(url, mts);
}
mts.add(method);
}
} // end of for methods
return appendMethodsToUrls(serviceUrls, url2Methods);
}
static Map<Long, RouteRule> route2RouteRule(List<Route> routes,
Map<String, List<String>> clusters) {
Map<Long, RouteRule> rules = new HashMap<Long, RouteRule>();
// route -> RouteRule
if (routes != null && routes.size() > 0) {
for (Route route : routes) {
rules.put(route.getId(), RouteRule.parseQuitely(route));
}
}
// expand the cluster parameters into conditions of routerule
if (clusters != null && clusters.size() > 0) {
Map<Long, RouteRule> rrs = new HashMap<Long, RouteRule>();
for (Map.Entry<Long, RouteRule> entry : rules.entrySet()) {
RouteRule rr = entry.getValue();
Map<String, RouteRule.MatchPair> when = RouteRuleUtils.expandCondition(
rr.getWhenCondition(), "consumer.cluster", "consumer.host", clusters);
Map<String, RouteRule.MatchPair> then = RouteRuleUtils.expandCondition(
rr.getThenCondition(), "provider.cluster", "provider.host", clusters);
rrs.put(entry.getKey(), RouteRule.createFromCondition(when, then));
}
rules = rrs;
}
return rules;
}
static Map<String, String> appendMethodsToUrls(Map<String, String> serviceUrls,
Map<String, Set<String>> url2Methods) {
// Add method parameters to URL
Map<String, String> results = new HashMap<String, String>();
for (Map.Entry<String, Set<String>> entry : url2Methods.entrySet()) {
String url = entry.getKey();
String query = serviceUrls.get(url);
Set<String> methodNames = entry.getValue();
if (methodNames != null && methodNames.size() > 0) {
String ms = StringUtils.join(methodNames.toArray(new String[0]), ParseUtils.METHOD_SPLIT);
query = ParseUtils.replaceParameter(query, "methods", ms);
}
results.put(url, query);
}
return results;
}
static Route getFirstRouteMatchedWhenConditionOfRule(String serviceName, Map<String, String> consumerSample, List<Route> routes, Map<Long, RouteRule> routeRuleMap) {
if (serviceName == null || serviceName.length() == 0) {
return null;
}
if (routes != null && routes.size() > 0) {
for (Route route : routes) {
if (isSerivceNameMatched(route.getService(), serviceName)) {
RouteRule rule = routeRuleMap.get(route.getId());
// if matches When Condition
if (rule != null && RouteRuleUtils.isMatchCondition(
rule.getWhenCondition(), consumerSample, consumerSample)) {
return route; // will return if the first condition matches
}
}
}
}
return null;
}
/**
* Check if a service name matches pattern
*
* @param servicePattern
* @param serviceName
*/
static boolean isSerivceNameMatched(String servicePattern, String serviceName) {
final int pip = servicePattern.indexOf('/');
final int pi = serviceName.indexOf('/');
if (pip != -1) { // pattern has group
if (pi == -1) return false; // servicename doesn't have group
String gp = servicePattern.substring(0, pip);
servicePattern = servicePattern.substring(pip + 1);
String g = serviceName.substring(0, pi);
if (!gp.equals(g)) return false;
}
if (pi != -1)
serviceName = serviceName.substring(pi + 1);
final int vip = servicePattern.lastIndexOf(':');
final int vi = serviceName.lastIndexOf(':');
if (vip != -1) { // pattern has group
if (vi == -1) return false;
String vp = servicePattern.substring(vip + 1);
servicePattern = servicePattern.substring(0, vip);
String v = serviceName.substring(vi + 1);
if (!vp.equals(v)) return false;
}
if (vi != -1)
serviceName = serviceName.substring(0, vi);
return ParseUtils.isMatchGlobPattern(servicePattern, serviceName);
}
static Map<String, Map<String, String>> getUrlsMatchedCondition(Map<String, RouteRule.MatchPair> condition,
Map<String, String> parameters, Map<String, Map<String, String>> url2Sample) {
Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();
for (Map.Entry<String, Map<String, String>> entry : url2Sample.entrySet()) {
Map<String, String> sample = entry.getValue();
Map<String, String> params = new HashMap<String, String>();
params.putAll(sample);
params.putAll(parameters);
if (RouteRuleUtils.isMatchCondition(condition, params, sample)) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}
}
/*
* 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.admin.registry.common.status;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.status.Status;
import com.alibaba.dubbo.common.status.StatusChecker;
import org.springframework.beans.factory.annotation.Autowired;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
/**
* DatabaseStatus
*
*/
public class DatabaseStatusChecker implements StatusChecker {
private static final Logger logger = LoggerFactory.getLogger(DatabaseStatusChecker.class);
private int version;
private String message;
@Autowired
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
check(); // init
}
public Status check() {
boolean ok;
try {
Connection connection = dataSource.getConnection();
try {
DatabaseMetaData metaData = connection.getMetaData();
ResultSet resultSet = metaData.getTypeInfo();
try {
ok = resultSet.next();
} finally {
resultSet.close();
}
if (message == null) {
message = metaData.getURL()
+ " (" + metaData.getDatabaseProductName()
+ " " + metaData.getDatabaseProductVersion()
+ ", " + getIsolation(metaData.getDefaultTransactionIsolation()) + ")";
}
if (version == 0) {
version = metaData.getDatabaseMajorVersion();
}
} finally {
connection.close();
}
} catch (Throwable e) {
logger.error(e.getMessage(), e);
ok = false;
}
return new Status(!ok ? Status.Level.ERROR : (version < 5 ? Status.Level.WARN : Status.Level.OK), message);
}
private String getIsolation(int i) {
if (i == Connection.TRANSACTION_READ_COMMITTED) {
return "READ_COMMITTED";
}
if (i == Connection.TRANSACTION_READ_UNCOMMITTED) {
return "READ_UNCOMMITTED";
}
if (i == Connection.TRANSACTION_REPEATABLE_READ) {
return "REPEATABLE_READ";
}
if (i == Connection.TRANSACTION_SERIALIZABLE) {
return "SERIALIZABLE)";
}
return "NONE";
}
}
/*
* 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.admin.registry.common.status;
import com.alibaba.dubbo.common.status.Status;
import com.alibaba.dubbo.common.status.StatusChecker;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
/**
* Load StatusController
*
*/
public class LoadStatusChecker implements StatusChecker {
public Status check() {
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
double load;
try {
Method method = OperatingSystemMXBean.class.getMethod("getSystemLoadAverage", new Class<?>[0]);
load = (Double) method.invoke(operatingSystemMXBean, new Object[0]);
} catch (Throwable e) {
load = -1;
}
int cpu = operatingSystemMXBean.getAvailableProcessors();
return new Status(load < 0 ? Status.Level.UNKNOWN : (load < cpu ? Status.Level.OK : Status.Level.WARN), "Load: " + load + " / CPU: " + cpu);
}
}
/*
* 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.admin.registry.common.status;
import com.alibaba.dubbo.common.status.Status;
import com.alibaba.dubbo.common.status.StatusChecker;
/**
* MemoryStatus
*
*/
public class MemoryStatusChecker implements StatusChecker {
public Status check() {
Runtime runtime = Runtime.getRuntime();
long freeMemory = runtime.freeMemory();
long totalMemory = runtime.totalMemory();
long maxMemory = runtime.maxMemory();
boolean ok = (maxMemory - (totalMemory - freeMemory) > 2048); // Alarm when spare memory < 2M
String msg = "Max:" + (maxMemory / 1024 / 1024) + "M, Total:"
+ (totalMemory / 1024 / 1024) + "M, Free:" + (freeMemory / 1024 / 1024)
+ "M, Use:" + ((totalMemory / 1024 / 1024) - (freeMemory / 1024 / 1024)) + "M";
return new Status(ok ? Status.Level.OK : Status.Level.WARN, msg);
}
}
/*
* 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.admin.registry.common.util;
import com.alibaba.dubbo.common.io.Bytes;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Coder {
private Coder() {
}
public static String encodeHex(byte[] bytes) {
StringBuffer buffer = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
if (((int) bytes[i] & 0xff) < 0x10)
buffer.append("0");
buffer.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buffer.toString();
}
public static String encodeMd5(String source) {
return encodeMd5(source.getBytes());
}
public static String encodeMd5(byte[] source) {
try {
return encodeHex(MessageDigest.getInstance("MD5").digest(source));
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
public static String encodeBase64(String source) {
return Bytes.bytes2base64(source.getBytes());
}
public static String decodeBase64(String source) {
return new String(Bytes.base642bytes(source));
}
}
/*
* 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.admin.registry.common.util;
/**
* <p>A hash map that uses primitive ints for the key rather than objects.</p>
* <p>
* <p>Note that this class is for internal optimization purposes only, and may
* not be supported in future releases of Apache Commons Lang. Utilities of
* this sort may be included in future releases of Apache Commons Collections.</p>
*
* @version $Revision: 181192 $
* @see java.util.HashMap
* @since 2.0
*/
class IntHashMap {
/**
* The hash table data.
*/
private transient Entry table[];
/**
* The total number of entries in the hash table.
*/
private transient int count;
/**
* The table is rehashed when its size exceeds this threshold. (The
* value of this field is (int)(capacity * loadFactor).)
*
* @serial
*/
private int threshold;
/**
* The load factor for the hashtable.
*
* @serial
*/
private float loadFactor;
/**
* <p>Constructs a new, empty hashtable with a default capacity and load
* factor, which is <code>20</code> and <code>0.75</code> respectively.</p>
*/
public IntHashMap() {
this(20, 0.75f);
}
/**
* <p>Constructs a new, empty hashtable with the specified initial capacity
* and default load factor, which is <code>0.75</code>.</p>
*
* @param initialCapacity the initial capacity of the hashtable.
* @throws IllegalArgumentException if the initial capacity is less
* than zero.
*/
public IntHashMap(int initialCapacity) {
this(initialCapacity, 0.75f);
}
/**
* <p>Constructs a new, empty hashtable with the specified initial
* capacity and the specified load factor.</p>
*
* @param initialCapacity the initial capacity of the hashtable.
* @param loadFactor the load factor of the hashtable.
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive.
*/
public IntHashMap(int initialCapacity, float loadFactor) {
super();
if (initialCapacity < 0) {
throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
}
if (loadFactor <= 0) {
throw new IllegalArgumentException("Illegal Load: " + loadFactor);
}
if (initialCapacity == 0) {
initialCapacity = 1;
}
this.loadFactor = loadFactor;
table = new Entry[initialCapacity];
threshold = (int) (initialCapacity * loadFactor);
}
/**
* <p>Returns the number of keys in this hashtable.</p>
*
* @return the number of keys in this hashtable.
*/
public int size() {
return count;
}
/**
* <p>Tests if this hashtable maps no keys to values.</p>
*
* @return <code>true</code> if this hashtable maps no keys to values;
* <code>false</code> otherwise.
*/
public boolean isEmpty() {
return count == 0;
}
/**
* <p>Tests if some key maps into the specified value in this hashtable.
* This operation is more expensive than the <code>containsKey</code>
* method.</p>
* <p>
* <p>Note that this method is identical in functionality to containsValue,
* (which is part of the Map interface in the collections framework).</p>
*
* @param value a value to search for.
* @return <code>true</code> if and only if some key maps to the
* <code>value</code> argument in this hashtable as
* determined by the <tt>equals</tt> method;
* <code>false</code> otherwise.
* @throws NullPointerException if the value is <code>null</code>.
* @see #containsKey(int)
* @see #containsValue(Object)
* @see java.util.Map
*/
public boolean contains(Object value) {
if (value == null) {
throw new NullPointerException();
}
Entry tab[] = table;
for (int i = tab.length; i-- > 0; ) {
for (Entry e = tab[i]; e != null; e = e.next) {
if (e.value.equals(value)) {
return true;
}
}
}
return false;
}
/**
* <p>Returns <code>true</code> if this HashMap maps one or more keys
* to this value.</p>
* <p>
* <p>Note that this method is identical in functionality to contains
* (which predates the Map interface).</p>
*
* @param value value whose presence in this HashMap is to be tested.
* @return boolean <code>true</code> if the value is contained
* @see java.util.Map
* @since JDK1.2
*/
public boolean containsValue(Object value) {
return contains(value);
}
/**
* <p>Tests if the specified object is a key in this hashtable.</p>
*
* @param key possible key.
* @return <code>true</code> if and only if the specified object is a
* key in this hashtable, as determined by the <tt>equals</tt>
* method; <code>false</code> otherwise.
* @see #contains(Object)
*/
public boolean containsKey(int key) {
Entry tab[] = table;
int hash = key;
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index]; e != null; e = e.next) {
if (e.hash == hash) {
return true;
}
}
return false;
}
/**
* <p>Returns the value to which the specified key is mapped in this map.</p>
*
* @param key a key in the hashtable.
* @return the value to which the key is mapped in this hashtable;
* <code>null</code> if the key is not mapped to any value in
* this hashtable.
* @see #put(int, Object)
*/
public Object get(int key) {
Entry tab[] = table;
int hash = key;
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index]; e != null; e = e.next) {
if (e.hash == hash) {
return e.value;
}
}
return null;
}
/**
* <p>Increases the capacity of and internally reorganizes this
* hashtable, in order to accommodate and access its entries more
* efficiently.</p>
* <p>
* <p>This method is called automatically when the number of keys
* in the hashtable exceeds this hashtable's capacity and load
* factor.</p>
*/
protected void rehash() {
int oldCapacity = table.length;
Entry oldMap[] = table;
int newCapacity = oldCapacity * 2 + 1;
Entry newMap[] = new Entry[newCapacity];
threshold = (int) (newCapacity * loadFactor);
table = newMap;
for (int i = oldCapacity; i-- > 0; ) {
for (Entry old = oldMap[i]; old != null; ) {
Entry e = old;
old = old.next;
int index = (e.hash & 0x7FFFFFFF) % newCapacity;
e.next = newMap[index];
newMap[index] = e;
}
}
}
/**
* <p>Maps the specified <code>key</code> to the specified
* <code>value</code> in this hashtable. The key cannot be
* <code>null</code>. </p>
* <p>
* <p>The value can be retrieved by calling the <code>get</code> method
* with a key that is equal to the original key.</p>
*
* @param key the hashtable key.
* @param value the value.
* @return the previous value of the specified key in this hashtable,
* or <code>null</code> if it did not have one.
* @throws NullPointerException if the key is <code>null</code>.
* @see #get(int)
*/
public Object put(int key, Object value) {
// Makes sure the key is not already in the hashtable.
Entry tab[] = table;
int hash = key;
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index]; e != null; e = e.next) {
if (e.hash == hash) {
Object old = e.value;
e.value = value;
return old;
}
}
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
Entry e = new Entry(hash, key, value, tab[index]);
tab[index] = e;
count++;
return null;
}
/**
* <p>Removes the key (and its corresponding value) from this
* hashtable.</p>
* <p>
* <p>This method does nothing if the key is not present in the
* hashtable.</p>
*
* @param key the key that needs to be removed.
* @return the value to which the key had been mapped in this hashtable,
* or <code>null</code> if the key did not have a mapping.
*/
public Object remove(int key) {
Entry tab[] = table;
int hash = key;
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next) {
if (e.hash == hash) {
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
Object oldValue = e.value;
e.value = null;
return oldValue;
}
}
return null;
}
/**
* <p>Clears this hashtable so that it contains no keys.</p>
*/
public synchronized void clear() {
Entry tab[] = table;
for (int index = tab.length; --index >= 0; ) {
tab[index] = null;
}
count = 0;
}
/**
* <p>Innerclass that acts as a datastructure to create a new entry in the
* table.</p>
*/
private static class Entry {
int hash;
int key;
Object value;
Entry next;
/**
* <p>Create a new entry with the given values.</p>
*
* @param hash The code used to hash the object with
* @param key The key used to enter this in the table
* @param value The value for this key
* @param next A reference to the next entry in the table
*/
protected Entry(int hash, int key, Object value, Entry next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
}
}
/*
* 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.admin.registry.common.util;
import java.util.Locale;
public class LocaleUtils {
private LocaleUtils() {
}
public static Locale getLocale(String language) {
if ("en".equalsIgnoreCase(language)) {
return Locale.ENGLISH;
} else if ("zh".equalsIgnoreCase(language)) {
return Locale.SIMPLIFIED_CHINESE;
} else if ("zh_TW".equalsIgnoreCase(language)) {
return Locale.TRADITIONAL_CHINESE;
}
return Locale.getDefault();
}
}
/*
* 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.admin.registry.common.util;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import java.text.MessageFormat;
import java.util.ResourceBundle;
/**
* MessageSource
*
*/
public class MessageSource {
private static final Logger logger = LoggerFactory.getLogger(MessageSource.class);
private final ResourceBundle resourceBundle;
private final String errorPrefix;
public MessageSource(ResourceBundle resourceBundle) {
this(resourceBundle, null);
}
public MessageSource(ResourceBundle resourceBundle, String errorPrefix) {
this.resourceBundle = resourceBundle;
this.errorPrefix = errorPrefix == null ? "" : errorPrefix + " ";
}
public String getString(String key) {
try {
return resourceBundle.getString(key);
} catch (Throwable t) {
logger.warn(errorPrefix + t.getMessage(), t);
return key;
}
}
public String getString(String key, Object... args) {
try {
return new MessageFormat(resourceBundle.getString(key)).format(args);
} catch (Throwable t) {
logger.warn(errorPrefix + t.getMessage(), t);
return key;
}
}
}
/*
* 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.admin.registry.common.util;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import java.lang.reflect.Array;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.regex.Pattern;
/**
* Tool
*
*/
public class Tool {
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
private static final Comparator<String> SIMPLE_NAME_COMPARATOR = new Comparator<String>() {
public int compare(String s1, String s2) {
if (s1 == null && s2 == null) {
return 0;
}
if (s1 == null) {
return -1;
}
if (s2 == null) {
return 1;
}
s1 = getSimpleName(s1);
s2 = getSimpleName(s2);
return s1.compareToIgnoreCase(s2);
}
};
public static boolean startWith(String value, String prefix) {
return value.startsWith(prefix);
}
public static boolean isContains(String[] values, String value) {
return StringUtils.isContains(values, value);
}
public static boolean isValidAddress(String address) {
return IP_PATTERN.matcher(address).matches();
}
public static String getHostName(String address) {
if (address != null && address.length() > 0) {
String hostname = NetUtils.getHostName(address);
if (!address.equals(hostname)) {
return hostname + "/";
}
}
return "";
}
public static String getIP(String address) {
if (address != null && address.length() > 0) {
int i = address.indexOf("://");
if (i >= 0) {
address = address.substring(i + 3);
}
i = address.indexOf('/');
if (i >= 0) {
address = address.substring(0, i);
}
i = address.indexOf('@');
if (i >= 0) {
address = address.substring(i + 1);
}
i = address.indexOf(':');
if (i >= 0) {
address = address.substring(0, i);
}
if (address.matches("[a-zA-Z]+")) {
try {
address = InetAddress.getByName(address).getHostAddress();
} catch (UnknownHostException e) {
}
}
}
return address;
}
public static String encodeUrl(String url) {
return URL.encode(url);
}
public static String decodeUrl(String url) {
return URL.decode(url);
}
public static String encodeHtml(String html) {
return StringEscapeUtils.escapeHtml(html);
}
public static String decodeHtml(String html) {
return StringEscapeUtils.unescapeHtml(html);
}
public static int countMapValues(Map<?, ?> map) {
int total = 0;
if (map != null && map.size() > 0) {
for (Object value : map.values()) {
if (value != null) {
if (value instanceof Number) {
total += ((Number) value).intValue();
} else if (value.getClass().isArray()) {
total += Array.getLength(value);
} else if (value instanceof Collection) {
total += ((Collection<?>) value).size();
} else if (value instanceof Map) {
total += ((Map<?, ?>) value).size();
} else {
total += 1;
}
}
}
}
return total;
}
public static List<String> sortSimpleName(List<String> list) {
if (list != null && list.size() > 0) {
Collections.sort(list, SIMPLE_NAME_COMPARATOR);
}
return list;
}
public static String getSimpleName(String name) {
if (name != null && name.length() > 0) {
final int ip = name.indexOf('/');
String v = ip != -1 ? name.substring(0, ip + 1) : "";
int i = name.lastIndexOf(':');
int j = (i >= 0 ? name.lastIndexOf('.', i) : name.lastIndexOf('.'));
if (j >= 0) {
name = name.substring(j + 1);
}
name = v + name;
}
return name;
}
}
......@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service;
package org.apache.dubbo.admin.service;
import org.apache.dubbo.admin.registry.common.domain.Config;
import org.apache.dubbo.admin.model.domain.Config;
import java.util.List;
import java.util.Map;
......
......@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service;
package org.apache.dubbo.admin.service;
import org.apache.dubbo.admin.registry.common.domain.Consumer;
import org.apache.dubbo.admin.model.domain.Consumer;
import java.util.List;
......
......@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service;
package org.apache.dubbo.admin.service;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.model.domain.Override;
import java.util.List;
......
......@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service;
package org.apache.dubbo.admin.service;
import org.apache.dubbo.admin.registry.common.domain.Owner;
import org.apache.dubbo.admin.model.domain.Owner;
import java.util.List;
......
......@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service;
package org.apache.dubbo.admin.service;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import org.apache.dubbo.admin.model.domain.Provider;
import java.util.List;
......
......@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.sync;
package org.apache.dubbo.admin.service;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
......@@ -24,8 +24,8 @@ import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.registry.NotifyListener;
import com.alibaba.dubbo.registry.RegistryService;
import org.apache.dubbo.admin.util.MD5Util;
import org.apache.dubbo.admin.web.pulltool.Tool;
import org.apache.dubbo.admin.common.util.MD5Util;
import org.apache.dubbo.admin.common.util.Tool;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
......
......@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service;
package org.apache.dubbo.admin.service;
import org.apache.dubbo.admin.registry.common.domain.Route;
import org.apache.dubbo.admin.model.domain.Route;
import java.util.List;
......
......@@ -14,13 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service.impl;
package org.apache.dubbo.admin.service.impl;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.registry.RegistryService;
import org.apache.dubbo.admin.governance.sync.RegistryServerSync;
import org.apache.dubbo.admin.service.RegistryServerSync;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map;
......
......@@ -14,10 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service.impl;
package org.apache.dubbo.admin.service.impl;
import org.apache.dubbo.admin.governance.service.ConfigService;
import org.apache.dubbo.admin.registry.common.domain.Config;
import org.apache.dubbo.admin.service.ConfigService;
import org.apache.dubbo.admin.model.domain.Config;
import java.util.List;
import java.util.Map;
......
......@@ -14,14 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service.impl;
package org.apache.dubbo.admin.service.impl;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import org.apache.dubbo.admin.governance.service.ConsumerService;
import org.apache.dubbo.admin.governance.sync.util.Pair;
import org.apache.dubbo.admin.governance.sync.util.SyncUtils;
import org.apache.dubbo.admin.registry.common.domain.Consumer;
import org.apache.dubbo.admin.service.ConsumerService;
import org.apache.dubbo.admin.common.util.Pair;
import org.apache.dubbo.admin.common.util.SyncUtils;
import org.apache.dubbo.admin.model.domain.Consumer;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
......
......@@ -14,14 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service.impl;
package org.apache.dubbo.admin.service.impl;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import org.apache.dubbo.admin.governance.service.OverrideService;
import org.apache.dubbo.admin.governance.sync.util.Pair;
import org.apache.dubbo.admin.governance.sync.util.SyncUtils;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.service.OverrideService;
import org.apache.dubbo.admin.common.util.Pair;
import org.apache.dubbo.admin.common.util.SyncUtils;
import org.apache.dubbo.admin.model.domain.Override;
import org.springframework.stereotype.Component;
import java.util.HashMap;
......
......@@ -14,16 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service.impl;
package org.apache.dubbo.admin.service.impl;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.governance.service.OverrideService;
import org.apache.dubbo.admin.governance.service.OwnerService;
import org.apache.dubbo.admin.governance.service.ProviderService;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.domain.Owner;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import org.apache.dubbo.admin.service.OverrideService;
import org.apache.dubbo.admin.service.OwnerService;
import org.apache.dubbo.admin.service.ProviderService;
import org.apache.dubbo.admin.model.domain.Override;
import org.apache.dubbo.admin.model.domain.Owner;
import org.apache.dubbo.admin.model.domain.Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
......
......@@ -14,18 +14,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service.impl;
package org.apache.dubbo.admin.service.impl;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.utils.StringUtils;
import org.apache.dubbo.admin.governance.service.OverrideService;
import org.apache.dubbo.admin.governance.service.ProviderService;
import org.apache.dubbo.admin.governance.sync.util.Pair;
import org.apache.dubbo.admin.governance.sync.util.SyncUtils;
import org.apache.dubbo.admin.registry.common.domain.Override;
import org.apache.dubbo.admin.registry.common.domain.Provider;
import org.apache.dubbo.admin.registry.common.route.ParseUtils;
import org.apache.dubbo.admin.service.OverrideService;
import org.apache.dubbo.admin.service.ProviderService;
import org.apache.dubbo.admin.common.util.Pair;
import org.apache.dubbo.admin.common.util.SyncUtils;
import org.apache.dubbo.admin.model.domain.Override;
import org.apache.dubbo.admin.model.domain.Provider;
import org.apache.dubbo.admin.common.util.ParseUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
......
......@@ -14,15 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.admin.governance.service.impl;
package org.apache.dubbo.admin.service.impl;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import org.apache.dubbo.admin.dto.AccessDTO;
import org.apache.dubbo.admin.governance.service.RouteService;
import org.apache.dubbo.admin.governance.sync.util.Pair;
import org.apache.dubbo.admin.governance.sync.util.SyncUtils;
import org.apache.dubbo.admin.registry.common.domain.Route;
import org.apache.dubbo.admin.model.dto.AccessDTO;
import org.apache.dubbo.admin.service.RouteService;
import org.apache.dubbo.admin.common.util.Pair;
import org.apache.dubbo.admin.common.util.SyncUtils;
import org.apache.dubbo.admin.model.domain.Route;
import org.springframework.stereotype.Component;
import java.util.HashMap;
......
/*
* 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.admin.web.mvc;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.admin.governance.biz.common.i18n.MessageResourceService;
import org.apache.dubbo.admin.governance.util.WebConstants;
import org.apache.dubbo.admin.registry.common.domain.User;
import org.apache.dubbo.admin.web.pulltool.RootContextPath;
import org.apache.dubbo.admin.web.pulltool.Tool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.regex.Pattern;
public class BaseController {
protected static final Logger logger = LoggerFactory.getLogger(BaseController.class);
protected static final Pattern SPACE_SPLIT_PATTERN = Pattern.compile("\\s+");
//FIXME, to extract these auxiliary methods
protected String role = null;
protected String operator = null;
protected User currentUser = null;
protected String operatorAddress = null;
protected String currentRegistry = null;
@Autowired
private MessageResourceService messageResourceService;
@Autowired
protected Tool tool;
public void prepare(HttpServletRequest request, HttpServletResponse response, Model model,
String methodName, String type) {
if (request.getSession().getAttribute(WebConstants.CURRENT_USER_KEY) != null) {
User user = (User) request.getSession().getAttribute(WebConstants.CURRENT_USER_KEY);
currentUser = user;
operator = user.getUsername();
role = user.getRole();
request.getSession().setAttribute(WebConstants.CURRENT_USER_KEY, user);
}
operatorAddress = request.getRemoteHost();
request.getMethod();
model.addAttribute("operator", operator);
model.addAttribute("operatorAddress", operatorAddress);
model.addAttribute("currentRegistry", currentRegistry);
model.addAttribute("rootContextPath", new RootContextPath(request.getContextPath()));
model.addAttribute("tool", tool);
model.addAttribute("_method", methodName);
model.addAttribute("helpUrl", WebConstants.HELP_URL);
model.addAttribute("_type", type);
}
public String getMessage(String key, Object... args) {
return messageResourceService.getMessage(key, args);
}
}
/*
* 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.admin.web.mvc.common.i18n;
import java.util.Locale;
public class LocaleUtil {
private static ThreadLocal<Locale> userLocale = new ThreadLocal<Locale>();
public static void cleanLocale() {
userLocale.remove();
}
public static Locale getLocale() {
return userLocale.get();
}
public static void setLocale(Locale locale) {
userLocale.set(locale);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册