diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/pom.xml b/52.Dubbo-OPS-Mointor/dubbo-admin/pom.xml new file mode 100644 index 0000000..8639254 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + com.alibaba + dubbo-admin + 0.0.1-SNAPSHOT + jar + + dubbo-admin + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.2.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.alibaba.boot + velocity-spring-boot-starter + 0.1.0 + + + + org.apache.commons + commons-lang3 + 3.7 + + + + com.alibaba + dubbo + 2.6.2 + + + + org.apache.curator + curator-framework + 2.12.0 + + + com.alibaba + fastjson + 1.2.46 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/DubboAdminApplication.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/DubboAdminApplication.java new file mode 100644 index 0000000..58ba7c3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/DubboAdminApplication.java @@ -0,0 +1,33 @@ +/* + * 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 com.alibaba.dubboadmin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; + +@SpringBootApplication +public class DubboAdminApplication { + + public static void main(String[] args) { + ApplicationContext act = SpringApplication.run(DubboAdminApplication.class, args); + SpringUtil.setApplicationContext(act); + + + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/SpringUtil.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/SpringUtil.java new file mode 100644 index 0000000..c390c09 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/SpringUtil.java @@ -0,0 +1,60 @@ +/* + * 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 com.alibaba.dubboadmin; + + +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 getBean(Class clazz){ + return getApplicationContext().getBean(clazz); + } + + //通过name,以及Clazz返回指定的Bean + public static T getBean(String name,Class clazz){ + return getApplicationContext().getBean(name, clazz); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/config/I18nConfig.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/config/I18nConfig.java new file mode 100644 index 0000000..669949d --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/config/I18nConfig.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.dubboadmin.config; + +import java.util.Locale; + +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; + + +@Configuration +@EnableAutoConfiguration +@ComponentScan +//@ImportResource({"classpath*:dubbo-admin.xml"}) +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()); + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/config/XmlConfiguration.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/config/XmlConfiguration.java new file mode 100644 index 0000000..9c94a83 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/config/XmlConfiguration.java @@ -0,0 +1,28 @@ +/* + * 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 com.alibaba.dubboadmin.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + + +@Configuration +@ImportResource({"classpath*:dubbo-admin.xml"}) +public class XmlConfiguration { + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/filter/LoginFilter.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/filter/LoginFilter.java new file mode 100644 index 0000000..fe6c3aa --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/filter/LoginFilter.java @@ -0,0 +1,232 @@ +/* + * 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 com.alibaba.dubboadmin.filter; + +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; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.UserService; +import com.alibaba.dubboadmin.governance.util.WebConstants; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.registry.common.util.Coder; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@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 parseParameters(String query) { + Matcher matcher = PARAMETER_PATTERN.matcher(query); + Map map = new HashMap(); + 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 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))); + } +} + diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/biz/common/i18n/MessageResourceService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/biz/common/i18n/MessageResourceService.java new file mode 100644 index 0000000..e70c5ce --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/biz/common/i18n/MessageResourceService.java @@ -0,0 +1,25 @@ +/* + * 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 com.alibaba.dubboadmin.governance.biz.common.i18n; + +public interface MessageResourceService { + + public String get(String key, Object... args); + + public String getMessage(String key, Object... args); + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/biz/common/i18n/impl/MessageResourceServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/biz/common/i18n/impl/MessageResourceServiceImpl.java new file mode 100644 index 0000000..c0b47b8 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/biz/common/i18n/impl/MessageResourceServiceImpl.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.governance.biz.common.i18n.impl; + + +import com.alibaba.dubboadmin.governance.biz.common.i18n.MessageResourceService; +import com.alibaba.dubboadmin.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); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ConfigService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ConfigService.java new file mode 100644 index 0000000..a3a0ee8 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ConfigService.java @@ -0,0 +1,34 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service; + +import java.util.List; +import java.util.Map; + +import com.alibaba.dubboadmin.registry.common.domain.Config; + +/** + * TODO Comment of ConfigDAO + * + */ +public interface ConfigService { + + void update(List configs); + + Map findAllConfigsMap(); + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ConsumerService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ConsumerService.java new file mode 100644 index 0000000..e980eeb --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ConsumerService.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.governance.service; + +import java.util.List; + +import com.alibaba.dubboadmin.registry.common.domain.Consumer; + +/** + * Query service for consumer info + * + */ +public interface ConsumerService { + + List findByService(String serviceName); + + Consumer findConsumer(Long id); + + List findAll(); + + /** + * query for all consumer addresses + */ + List findAddresses(); + + List findAddressesByApplication(String application); + + List findAddressesByService(String serviceName); + + List findByAddress(String consumerAddress); + + List findServicesByAddress(String consumerAddress); + + List findApplications(); + + List findApplicationsByServiceName(String serviceName); + + List findByApplication(String application); + + List findServicesByApplication(String application); + + List findServices(); + +} \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/OverrideService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/OverrideService.java new file mode 100644 index 0000000..afa2a67 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/OverrideService.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.governance.service; + +import java.util.List; + +import com.alibaba.dubboadmin.registry.common.domain.Override; + +public interface OverrideService { + + void saveOverride(Override override); + + void updateOverride(Override override); + + void deleteOverride(Long id); + + void enableOverride(Long id); + + void disableOverride(Long id); + + List findByService(String service); + + List findByAddress(String address); + + List findByServiceAndAddress(String service, String address); + + List findByApplication(String application); + + List findByServiceAndApplication(String service, String application); + + List findAll(); + + Override findById(Long id); + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/OwnerService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/OwnerService.java new file mode 100644 index 0000000..367125a --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/OwnerService.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.governance.service; + +import java.util.List; + +import com.alibaba.dubboadmin.registry.common.domain.Owner; + +public interface OwnerService { + + List findAllServiceNames(); + + List findServiceNamesByUsername(String username); + + List findUsernamesByServiceName(String serviceName); + + List findByService(String serviceName); + + List findAll(); + + Owner findById(Long id); + + void saveOwner(Owner owner); + + void deleteOwner(Owner owner); + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ProviderService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ProviderService.java new file mode 100644 index 0000000..15ba776 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/ProviderService.java @@ -0,0 +1,73 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service; + +import java.util.List; + +import com.alibaba.dubboadmin.registry.common.domain.Provider; + +/** + * ProviderService + * + */ +public interface ProviderService { + + void create(Provider provider); + + void enableProvider(Long id); + + void disableProvider(Long id); + + void doublingProvider(Long id); + + void halvingProvider(Long id); + + void deleteStaticProvider(Long id); + + void updateProvider(Provider provider); + + Provider findProvider(Long id); + + List findServices(); + + List findAddresses(); + + List findAddressesByApplication(String application); + + List findAddressesByService(String serviceName); + + List findApplicationsByServiceName(String serviceName); + + List findByService(String serviceName); + + List findAll(); + + List findByAddress(String providerAddress); + + List findServicesByAddress(String providerAddress); + + List findApplications(); + + List findByApplication(String application); + + List findServicesByApplication(String application); + + List findMethodsByService(String serviceName); + + Provider findByServiceAndAddress(String service, String address); + +} \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/RouteService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/RouteService.java new file mode 100644 index 0000000..236d881 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/RouteService.java @@ -0,0 +1,57 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service; + +import java.util.List; + +import com.alibaba.dubboadmin.registry.common.domain.Route; + +/** + * RouteService + * + */ +public interface RouteService { + + void createRoute(Route route); + + void updateRoute(Route route); + + void deleteRoute(Long id); + + void enableRoute(Long id); + + void disableRoute(Long id); + + Route findRoute(Long id); + + List findAll(); + + List findByService(String serviceName); + + List findByAddress(String address); + + List findByServiceAndAddress(String service, String address); + + List findForceRouteByService(String service); + + List findForceRouteByAddress(String address); + + List findForceRouteByServiceAndAddress(String service, String address); + + List findAllForceRoute(); + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/UserService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/UserService.java new file mode 100644 index 0000000..1869859 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/UserService.java @@ -0,0 +1,51 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service; + +import java.util.List; + +import com.alibaba.dubboadmin.registry.common.domain.User; + +/** + * UserService + * + */ +public interface UserService { + + List 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); + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/AbstractService.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/AbstractService.java new file mode 100644 index 0000000..3c01d63 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/AbstractService.java @@ -0,0 +1,46 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.Map; +import java.util.concurrent.ConcurrentMap; + +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 com.alibaba.dubboadmin.governance.sync.RegistryServerSync; + +import org.springframework.beans.factory.annotation.Autowired; + +/** + * IbatisDAO + * + */ +public class AbstractService { + + protected static final Logger logger = LoggerFactory.getLogger(AbstractService.class); + @Autowired + protected RegistryService registryService; + @Autowired + private RegistryServerSync sync; + + public ConcurrentMap>> getRegistryCache() { + return sync.getRegistryCache(); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ConfigServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ConfigServiceImpl.java new file mode 100644 index 0000000..7921ac6 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ConfigServiceImpl.java @@ -0,0 +1,46 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.List; +import java.util.Map; + +import com.alibaba.dubboadmin.governance.service.ConfigService; +import com.alibaba.dubboadmin.registry.common.domain.Config; + +/** + * TODO Comment of IbatisConfigDAO + * + */ +public class ConfigServiceImpl extends AbstractService implements ConfigService { + + /* (non-Javadoc) + * @see com.alibaba.dubbo.governance.service.ConfigService#update(java.util.List) + */ + public void update(List configs) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see com.alibaba.dubbo.governance.service.ConfigService#findAllConfigsMap() + */ + public Map findAllConfigsMap() { + // TODO Auto-generated method stub + return null; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ConsumerServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ConsumerServiceImpl.java new file mode 100644 index 0000000..bf7c3da --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ConsumerServiceImpl.java @@ -0,0 +1,223 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.sync.util.Pair; +import com.alibaba.dubboadmin.governance.sync.util.SyncUtils; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; + +import org.springframework.stereotype.Component; + +@Component +public class ConsumerServiceImpl extends AbstractService implements ConsumerService { + + public List findByService(String service) { + return SyncUtils.url2ConsumerList(findConsumerUrlByService(service)); + } + + public Consumer findConsumer(Long id) { + return SyncUtils.url2Consumer(findConsumerUrl(id)); + } + + private Pair findConsumerUrl(Long id) { + return SyncUtils.filterFromCategory(getRegistryCache(), Constants.CONSUMERS_CATEGORY, id); + } + + public List findAll() { + return SyncUtils.url2ConsumerList(findAllConsumerUrl()); + } + + private Map findAllConsumerUrl() { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY); + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findAddresses() { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + if (null == consumerUrls) return ret; + + for (Map.Entry> e1 : consumerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + String app = u.getAddress(); + if (app != null) ret.add(app); + } + } + + return ret; + } + + public List findAddressesByApplication(String application) { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + + if(consumerUrls == null) + return ret; + + for (Map.Entry> e1 : consumerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) { + String addr = u.getAddress(); + if (addr != null) ret.add(addr); + } + } + } + + return ret; + } + + public List findAddressesByService(String service) { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + if (null == consumerUrls) return ret; + + for (Map.Entry e2 : consumerUrls.get(service).entrySet()) { + URL u = e2.getValue(); + String app = u.getAddress(); + if (app != null) ret.add(app); + } + + return ret; + } + + public List findByAddress(String consumerAddress) { + return SyncUtils.url2ConsumerList(findConsumerUrlByAddress(consumerAddress)); + } + + public List findServicesByAddress(String address) { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + if (consumerUrls == null || address == null || address.length() == 0) return ret; + + for (Map.Entry> e1 : consumerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + if (address.equals(u.getAddress())) { + ret.add(e1.getKey()); + break; + } + } + } + + return ret; + } + + private Map findConsumerUrlByAddress(String address) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY); + filter.put(SyncUtils.ADDRESS_FILTER_KEY, address); + + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findApplications() { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + if (consumerUrls == null) return ret; + + for (Map.Entry> e1 : consumerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + String app = u.getParameter(Constants.APPLICATION_KEY); + if (app != null) ret.add(app); + } + } + + return ret; + } + + public List findApplicationsByServiceName(String service) { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + if (consumerUrls == null) return ret; + + Map value = consumerUrls.get(service); + if (value == null) { + return ret; + } + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + String app = u.getParameter(Constants.APPLICATION_KEY); + if (app != null) ret.add(app); + } + + return ret; + } + + public List findByApplication(String application) { + return SyncUtils.url2ConsumerList(findConsumerUrlByApplication(application)); + } + + private Map findConsumerUrlByApplication(String application) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY); + filter.put(Constants.APPLICATION_KEY, application); + + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findServicesByApplication(String application) { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + if (consumerUrls == null || application == null || application.length() == 0) return ret; + + for (Map.Entry> e1 : consumerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) { + ret.add(e1.getKey()); + break; + } + } + } + + return ret; + } + + public List findServices() { + List ret = new ArrayList(); + ConcurrentMap> consumerUrls = getRegistryCache().get(Constants.CONSUMERS_CATEGORY); + if (consumerUrls != null) ret.addAll(consumerUrls.keySet()); + return ret; + } + + public Map findConsumerUrlByService(String service) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY); + filter.put(SyncUtils.SERVICE_FILTER_KEY, service); + + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/OverrideServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/OverrideServiceImpl.java new file mode 100644 index 0000000..151bbac --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/OverrideServiceImpl.java @@ -0,0 +1,191 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.sync.util.Pair; +import com.alibaba.dubboadmin.governance.sync.util.SyncUtils; +import com.alibaba.dubboadmin.registry.common.domain.Override; + +import org.springframework.stereotype.Component; + +/** + * IbatisOverrideDAO.java + * + */ +@Component +public class OverrideServiceImpl extends AbstractService implements OverrideService { + + public void saveOverride(Override override) { + URL url = getUrlFromOverride(override); + registryService.register(url); + } + + public void updateOverride(Override override) { + Long id = override.getId(); + if (id == null) { + throw new IllegalStateException("no override id"); + } + URL oldOverride = findOverrideUrl(id); + if (oldOverride == null) { + throw new IllegalStateException("Route was changed!"); + } + URL newOverride = getUrlFromOverride(override); + + registryService.unregister(oldOverride); + registryService.register(newOverride); + + } + + public void deleteOverride(Long id) { + URL oldOverride = findOverrideUrl(id); + if (oldOverride == null) { + throw new IllegalStateException("Route was changed!"); + } + registryService.unregister(oldOverride); + } + + public void enableOverride(Long id) { + if (id == null) { + throw new IllegalStateException("no override id"); + } + + URL oldOverride = findOverrideUrl(id); + if (oldOverride == null) { + throw new IllegalStateException("Override was changed!"); + } + if (oldOverride.getParameter("enabled", true)) { + return; + } + + URL newOverride = oldOverride.addParameter("enabled", true); + registryService.unregister(oldOverride); + registryService.register(newOverride); + + } + + public void disableOverride(Long id) { + if (id == null) { + throw new IllegalStateException("no override id"); + } + + URL oldProvider = findOverrideUrl(id); + if (oldProvider == null) { + throw new IllegalStateException("Override was changed!"); + } + if (!oldProvider.getParameter("enabled", true)) { + return; + } + + URL newProvider = oldProvider.addParameter("enabled", false); + registryService.unregister(oldProvider); + registryService.register(newProvider); + + } + + private Map findOverrideUrl(String service, String address, String application) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.CONFIGURATORS_CATEGORY); + if (service != null && service.length() > 0) { + filter.put(SyncUtils.SERVICE_FILTER_KEY, service); + } + if (address != null && address.length() > 0) { + filter.put(SyncUtils.ADDRESS_FILTER_KEY, address); + } + if (application != null && application.length() > 0) { + filter.put(Constants.APPLICATION_KEY, application); + } + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findByAddress(String address) { + return SyncUtils.url2OverrideList(findOverrideUrl(null, address, null)); + } + + public List findByServiceAndAddress(String service, String address) { + return SyncUtils.url2OverrideList(findOverrideUrl(service, address, null)); + } + + public List findByApplication(String application) { + return SyncUtils.url2OverrideList(findOverrideUrl(null, null, application)); + } + + public List findByService(String service) { + return SyncUtils.url2OverrideList(findOverrideUrl(service, null, null)); + } + + public List findByServiceAndApplication(String service, String application) { + return SyncUtils.url2OverrideList(findOverrideUrl(service, null, application)); + } + + public List findAll() { + return SyncUtils.url2OverrideList(findOverrideUrl(null, null, null)); + } + + private Pair findOverrideUrlPair(Long id) { + return SyncUtils.filterFromCategory(getRegistryCache(), Constants.CONFIGURATORS_CATEGORY, id); + } + + public Override findById(Long id) { + return SyncUtils.url2Override(findOverrideUrlPair(id)); + } + + private URL getUrlFromOverride(Override override) { + return override.toUrl(); + /*Map params = ConvertUtil.serviceName2Map(override.getService()); + if(!params.containsKey(Constants.INTERFACE_KEY)) { + throw new IllegalArgumentException("No interface info"); + } + if(!params.containsKey(Constants.VERSION_KEY)) { + throw new IllegalArgumentException("No version info"); + } + + boolean enabled = override.isEnabled(); + if(!enabled) { + params.put("enabled", "false"); + } + String application = override.getApplication(); + if(!StringUtils.isEmpty(application)) { + params.put("application", application); + } + String address = override.getAddress(); + if(!StringUtils.isEmpty(address)) { + params.put("address", address); + } + + String overrideAddress = override.getOverrideAddress(); + if(StringUtils.isEmpty(overrideAddress)) { + overrideAddress = "0.0.0.0"; + } + params.put(Constants.CATEGORY_KEY, Constants.CONFIGURATORS_CATEGORY); + + URL url = new URL("override", overrideAddress, -1, params); + url = url.addParameterString(override.getParams()); + return url;*/ + } + + URL findOverrideUrl(Long id) { + return getUrlFromOverride(findById(id)); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/OwnerServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/OwnerServiceImpl.java new file mode 100644 index 0000000..4fa2613 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/OwnerServiceImpl.java @@ -0,0 +1,160 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.OwnerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Owner; +import com.alibaba.dubboadmin.registry.common.domain.Provider; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class OwnerServiceImpl extends AbstractService implements OwnerService { + + @Autowired + ProviderService providerService; + + @Autowired + OverrideService overrideService; + + public List findAllServiceNames() { + // TODO Auto-generated method stub + return null; + } + + public List findServiceNamesByUsername(String username) { + // TODO Auto-generated method stub + return null; + } + + public List findUsernamesByServiceName(String serviceName) { + // TODO Auto-generated method stub + return null; + } + + public List findByService(String serviceName) { + List pList = providerService.findByService(serviceName); + List cList = overrideService.findByServiceAndAddress(serviceName, Constants.ANYHOST_VALUE); + return toOverrideLiset(pList, cList); + } + + public List findAll() { + List pList = providerService.findAll(); + List cList = overrideService.findAll(); + return toOverrideLiset(pList, cList); + } + + public Owner findById(Long id) { + + return null; + } + + private List toOverrideLiset(List pList, List cList) { + Map oList = new HashMap(); + for (Provider p : pList) { + if (p.getUsername() != null) { + for (String username : Constants.COMMA_SPLIT_PATTERN.split(p.getUsername())) { + Owner o = new Owner(); + o.setService(p.getService()); + o.setUsername(username); + oList.put(o.getService() + "/" + o.getUsername(), o); + } + } + } + for (Override c : cList) { + Map params = StringUtils.parseQueryString(c.getParams()); + String usernames = params.get("owner"); + if (usernames != null && usernames.length() > 0) { + for (String username : Constants.COMMA_SPLIT_PATTERN.split(usernames)) { + Owner o = new Owner(); + o.setService(c.getService()); + o.setUsername(username); + oList.put(o.getService() + "/" + o.getUsername(), o); + } + } + } + return new ArrayList(oList.values()); + } + + public void saveOwner(Owner owner) { + List overrides = overrideService.findByServiceAndAddress(owner.getService(), Constants.ANYHOST_VALUE); + if (overrides == null || overrides.size() == 0) { + Override override = new Override(); + override.setAddress(Constants.ANYHOST_VALUE); + override.setService(owner.getService()); + override.setEnabled(true); + override.setParams("owner=" + owner.getUsername()); + overrideService.saveOverride(override); + } else { + for (Override override : overrides) { + Map params = StringUtils.parseQueryString(override.getParams()); + String usernames = params.get("owner"); + if (usernames == null || usernames.length() == 0) { + usernames = owner.getUsername(); + } else { + usernames = usernames + "," + owner.getUsername(); + } + params.put("owner", usernames); + override.setParams(StringUtils.toQueryString(params)); + overrideService.updateOverride(override); + } + } + } + + public void deleteOwner(Owner owner) { + List overrides = overrideService.findByServiceAndAddress(owner.getService(), Constants.ANYHOST_VALUE); + if (overrides == null || overrides.size() == 0) { + Override override = new Override(); + override.setAddress(Constants.ANYHOST_VALUE); + override.setService(owner.getService()); + override.setEnabled(true); + override.setParams("owner=" + owner.getUsername()); + overrideService.saveOverride(override); + } else { + for (Override override : overrides) { + Map params = StringUtils.parseQueryString(override.getParams()); + String usernames = params.get("owner"); + if (usernames != null && usernames.length() > 0) { + if (usernames.equals(owner.getUsername())) { + params.remove("owner"); + } else { + usernames = usernames.replace(owner.getUsername() + ",", "").replace("," + owner.getUsername(), ""); + params.put("owner", usernames); + } + if (params.size() > 0) { + override.setParams(StringUtils.toQueryString(params)); + overrideService.updateOverride(override); + } else { + overrideService.deleteOverride(override.getId()); + } + } + } + } + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ProviderServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ProviderServiceImpl.java new file mode 100644 index 0000000..8ee59e1 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/ProviderServiceImpl.java @@ -0,0 +1,461 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentMap; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.governance.sync.util.Pair; +import com.alibaba.dubboadmin.governance.sync.util.SyncUtils; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.route.ParseUtils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * IbatisProviderService + * + */ +@Component +public class ProviderServiceImpl extends AbstractService implements ProviderService { + + @Autowired + OverrideService overrideService; + + public void create(Provider provider) { + URL url = provider.toUrl(); + registryService.register(url); + } + + public void enableProvider(Long id) { + if (id == null) { + throw new IllegalStateException("no provider id"); + } + + Provider oldProvider = findProvider(id); + + if (oldProvider == null) { + throw new IllegalStateException("Provider was changed!"); + } + if (oldProvider.isDynamic()) { + // Make sure we only have one override configured disable property. + if (!oldProvider.isEnabled()) { + Override override = new Override(); + override.setAddress(oldProvider.getAddress()); + override.setService(oldProvider.getService()); + override.setEnabled(true); + override.setParams(Constants.DISABLED_KEY + "=false"); + overrideService.saveOverride(override); + return; + } + List oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress()); + + for (Override o : oList) { + Map params = StringUtils.parseQueryString(o.getParams()); + if (params.containsKey(Constants.DISABLED_KEY)) { + if (params.get(Constants.DISABLED_KEY).equals("true")) { + overrideService.deleteOverride(o.getId()); + } + } + } + } else { + oldProvider.setEnabled(true); + updateProvider(oldProvider); + } + } + + public void disableProvider(Long id) { + if (id == null) { + throw new IllegalStateException("no provider id"); + } + + Provider oldProvider = findProvider(id); + if (oldProvider == null) { + throw new IllegalStateException("Provider was changed!"); + } + + if (oldProvider.isDynamic()) { + // Make sure we only have one override configured disable property. + if (oldProvider.isEnabled()) { + Override override = new Override(); + override.setAddress(oldProvider.getAddress()); + override.setService(oldProvider.getService()); + override.setEnabled(true); + override.setParams(Constants.DISABLED_KEY + "=true"); + overrideService.saveOverride(override); + return; + } + List oList = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress()); + + for (Override o : oList) { + Map params = StringUtils.parseQueryString(o.getParams()); + if (params.containsKey(Constants.DISABLED_KEY)) { + if (params.get(Constants.DISABLED_KEY).equals("false")) { + overrideService.deleteOverride(o.getId()); + } + } + } + } else { + oldProvider.setEnabled(false); + updateProvider(oldProvider); + } + + } + + public void doublingProvider(Long id) { + setWeight(id, 2F); + } + + public void halvingProvider(Long id) { + setWeight(id, 0.5F); + } + + public void setWeight(Long id, float factor) { + if (id == null) { + throw new IllegalStateException("no provider id"); + } + Provider oldProvider = findProvider(id); + if (oldProvider == null) { + throw new IllegalStateException("Provider was changed!"); + } + Map map = StringUtils.parseQueryString(oldProvider.getParameters()); + String weight = map.get(Constants.WEIGHT_KEY); + if (oldProvider.isDynamic()) { + // Make sure we only have one override configured disable property. + List overrides = overrideService.findByServiceAndAddress(oldProvider.getService(), oldProvider.getAddress()); + if (overrides == null || overrides.size() == 0) { + int value = getWeight(weight, factor); + if (value != Constants.DEFAULT_WEIGHT) { + Override override = new Override(); + override.setAddress(oldProvider.getAddress()); + override.setService(oldProvider.getService()); + override.setEnabled(true); + override.setParams(Constants.WEIGHT_KEY + "=" + String.valueOf(value)); + overrideService.saveOverride(override); + } + } else { + for (Override override : overrides) { + Map params = StringUtils.parseQueryString(override.getParams()); + String overrideWeight = params.get(Constants.WEIGHT_KEY); + if (overrideWeight == null || overrideWeight.length() == 0) { + overrideWeight = weight; + } + int value = getWeight(overrideWeight, factor); + if (value == getWeight(weight, 1)) { + params.remove(Constants.WEIGHT_KEY); + } else { + params.put(Constants.WEIGHT_KEY, String.valueOf(value)); + } + if (params.size() > 0) { + override.setParams(StringUtils.toQueryString(params)); + overrideService.updateOverride(override); + } else { + overrideService.deleteOverride(override.getId()); + } + } + } + } else { + int value = getWeight(weight, factor); + if (value == Constants.DEFAULT_WEIGHT) { + map.remove(Constants.WEIGHT_KEY); + } else { + map.put(Constants.WEIGHT_KEY, String.valueOf(value)); + } + oldProvider.setParameters(StringUtils.toQueryString(map)); + updateProvider(oldProvider); + } + } + + private int getWeight(String value, float factor) { + int weight = 100; + if (value != null && value.length() > 0) { + weight = Integer.parseInt(value); + } + weight = (int) (weight * factor); + if (weight < 1) weight = 1; + if (weight == 2) weight = 3; + if (weight == 24) weight = 25; + return weight; + } + + public void deleteStaticProvider(Long id) { + URL oldProvider = findProviderUrl(id); + if (oldProvider == null) { + throw new IllegalStateException("Provider was changed!"); + } + registryService.unregister(oldProvider); + } + + public void updateProvider(Provider provider) { + Long id = provider.getId(); + if (id == null) { + throw new IllegalStateException("no provider id"); + } + + URL oldProvider = findProviderUrl(id); + if (oldProvider == null) { + throw new IllegalStateException("Provider was changed!"); + } + URL newProvider = provider.toUrl(); + + registryService.unregister(oldProvider); + registryService.register(newProvider); + } + + public Provider findProvider(Long id) { + return SyncUtils.url2Provider(findProviderUrlPair(id)); + } + + public Pair findProviderUrlPair(Long id) { + return SyncUtils.filterFromCategory(getRegistryCache(), Constants.PROVIDERS_CATEGORY, id); + } + + public List findServices() { + List ret = new ArrayList(); + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (providerUrls != null) ret.addAll(providerUrls.keySet()); + return ret; + } + + public List findAddresses() { + List ret = new ArrayList(); + + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (null == providerUrls) return ret; + + for (Map.Entry> e1 : providerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + String app = u.getAddress(); + if (app != null) ret.add(app); + } + } + + return ret; + } + + public List findAddressesByApplication(String application) { + List ret = new ArrayList(); + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + for (Map.Entry> e1 : providerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) { + String addr = u.getAddress(); + if (addr != null) ret.add(addr); + } + } + } + + return ret; + } + + public List findAddressesByService(String service) { + List ret = new ArrayList(); + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (null == providerUrls) return ret; + + for (Map.Entry e2 : providerUrls.get(service).entrySet()) { + URL u = e2.getValue(); + String app = u.getAddress(); + if (app != null) ret.add(app); + } + + return ret; + } + + public List findApplicationsByServiceName(String service) { + List ret = new ArrayList(); + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (null == providerUrls) return ret; + + Map value = providerUrls.get(service); + if (value == null) { + return ret; + } + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + String app = u.getParameter(Constants.APPLICATION_KEY); + if (app != null) ret.add(app); + } + + return ret; + } + + public List findByService(String serviceName) { + return SyncUtils.url2ProviderList(findProviderUrlByService(serviceName)); + } + + private Map findProviderUrlByService(String service) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); + filter.put(SyncUtils.SERVICE_FILTER_KEY, service); + + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findAll() { + return SyncUtils.url2ProviderList(findAllProviderUrl()); + } + + private Map findAllProviderUrl() { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findByAddress(String providerAddress) { + return SyncUtils.url2ProviderList(findProviderUrlByAddress(providerAddress)); + } + + public Map findProviderUrlByAddress(String address) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); + filter.put(SyncUtils.ADDRESS_FILTER_KEY, address); + + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findServicesByAddress(String address) { + List ret = new ArrayList(); + + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (providerUrls == null || address == null || address.length() == 0) return ret; + + for (Map.Entry> e1 : providerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + if (address.equals(u.getAddress())) { + ret.add(e1.getKey()); + break; + } + } + } + + return ret; + } + + public List findApplications() { + List ret = new ArrayList(); + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (providerUrls == null) return ret; + + for (Map.Entry> e1 : providerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + String app = u.getParameter(Constants.APPLICATION_KEY); + if (app != null) ret.add(app); + } + } + + return ret; + } + + public List findByApplication(String application) { + return SyncUtils.url2ProviderList(findProviderUrlByApplication(application)); + } + + private Map findProviderUrlByApplication(String application) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); + filter.put(Constants.APPLICATION_KEY, application); + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findServicesByApplication(String application) { + List ret = new ArrayList(); + + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (providerUrls == null || application == null || application.length() == 0) return ret; + + for (Map.Entry> e1 : providerUrls.entrySet()) { + Map value = e1.getValue(); + for (Map.Entry e2 : value.entrySet()) { + URL u = e2.getValue(); + if (application.equals(u.getParameter(Constants.APPLICATION_KEY))) { + ret.add(e1.getKey()); + break; + } + } + } + + return ret; + } + + public List findMethodsByService(String service) { + List ret = new ArrayList(); + + ConcurrentMap> providerUrls = getRegistryCache().get(Constants.PROVIDERS_CATEGORY); + if (providerUrls == null || service == null || service.length() == 0) return ret; + + Map providers = providerUrls.get(service); + if (null == providers || providers.isEmpty()) return ret; + + Entry p = providers.entrySet().iterator().next(); + String value = p.getValue().getParameter("methods"); + if (value == null || value.length() == 0) { + return ret; + } + String[] methods = value.split(ParseUtils.METHOD_SPLIT); + if (methods == null || methods.length == 0) { + return ret; + } + + for (String m : methods) { + ret.add(m); + } + return ret; + } + + private URL findProviderUrl(Long id) { + return findProvider(id).toUrl(); + } + + public Provider findByServiceAndAddress(String service, String address) { + return SyncUtils.url2Provider(findProviderUrl(service, address)); + } + + private Pair findProviderUrl(String service, String address) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); + filter.put(SyncUtils.ADDRESS_FILTER_KEY, address); + + Map ret = SyncUtils.filterFromCategory(getRegistryCache(), filter); + if (ret.isEmpty()) { + return null; + } else { + Long key = ret.entrySet().iterator().next().getKey(); + return new Pair(key, ret.get(key)); + } + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/RouteServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/RouteServiceImpl.java new file mode 100644 index 0000000..f618e90 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/RouteServiceImpl.java @@ -0,0 +1,169 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubboadmin.governance.service.RouteService; +import com.alibaba.dubboadmin.governance.sync.util.Pair; +import com.alibaba.dubboadmin.governance.sync.util.SyncUtils; +import com.alibaba.dubboadmin.registry.common.domain.Route; + +import org.springframework.stereotype.Component; + +/** + * IbatisRouteService + * + */ +@Component +public class RouteServiceImpl extends AbstractService implements RouteService { + + public void createRoute(Route route) { + registryService.register(route.toUrl()); + } + + public void updateRoute(Route route) { + Long id = route.getId(); + if (id == null) { + throw new IllegalStateException("no route id"); + } + URL oldRoute = findRouteUrl(id); + if (oldRoute == null) { + throw new IllegalStateException("Route was changed!"); + } + + registryService.unregister(oldRoute); + registryService.register(route.toUrl()); + } + + public void deleteRoute(Long id) { + URL oldRoute = findRouteUrl(id); + if (oldRoute == null) { + throw new IllegalStateException("Route was changed!"); + } + registryService.unregister(oldRoute); + } + + public void enableRoute(Long id) { + if (id == null) { + throw new IllegalStateException("no route id"); + } + + URL oldRoute = findRouteUrl(id); + if (oldRoute == null) { + throw new IllegalStateException("Route was changed!"); + } + if (oldRoute.getParameter("enabled", true)) { + return; + } + + registryService.unregister(oldRoute); + URL newRoute = oldRoute.addParameter("enabled", true); + registryService.register(newRoute); + + } + + public void disableRoute(Long id) { + if (id == null) { + throw new IllegalStateException("no route id"); + } + + URL oldRoute = findRouteUrl(id); + if (oldRoute == null) { + throw new IllegalStateException("Route was changed!"); + } + if (!oldRoute.getParameter("enabled", true)) { + return; + } + + URL newRoute = oldRoute.addParameter("enabled", false); + registryService.unregister(oldRoute); + registryService.register(newRoute); + + } + + public List findAll() { + return SyncUtils.url2RouteList(findAllUrl()); + } + + private Map findAllUrl() { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.ROUTERS_CATEGORY); + + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public Route findRoute(Long id) { + return SyncUtils.url2Route(findRouteUrlPair(id)); + } + + public Pair findRouteUrlPair(Long id) { + return SyncUtils.filterFromCategory(getRegistryCache(), Constants.ROUTERS_CATEGORY, id); + } + + private URL findRouteUrl(Long id) { + return findRoute(id).toUrl(); + } + + private Map findRouteUrl(String service, String address, boolean force) { + Map filter = new HashMap(); + filter.put(Constants.CATEGORY_KEY, Constants.ROUTERS_CATEGORY); + if (service != null && service.length() > 0) { + filter.put(SyncUtils.SERVICE_FILTER_KEY, service); + } + if (address != null && address.length() > 0) { + filter.put(SyncUtils.ADDRESS_FILTER_KEY, address); + } + if (force) { + filter.put("force", "true"); + } + return SyncUtils.filterFromCategory(getRegistryCache(), filter); + } + + public List findByService(String serviceName) { + return SyncUtils.url2RouteList(findRouteUrl(serviceName, null, false)); + } + + public List findByAddress(String address) { + return SyncUtils.url2RouteList(findRouteUrl(null, address, false)); + } + + public List findByServiceAndAddress(String service, String address) { + return SyncUtils.url2RouteList(findRouteUrl(service, address, false)); + } + + public List findForceRouteByService(String service) { + return SyncUtils.url2RouteList(findRouteUrl(service, null, true)); + } + + public List findForceRouteByAddress(String address) { + return SyncUtils.url2RouteList(findRouteUrl(null, address, true)); + } + + public List findForceRouteByServiceAndAddress(String service, String address) { + return SyncUtils.url2RouteList(findRouteUrl(service, address, true)); + } + + public List findAllForceRoute() { + return SyncUtils.url2RouteList(findRouteUrl(null, null, true)); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/UserServiceImpl.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..b100bad --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/service/impl/UserServiceImpl.java @@ -0,0 +1,134 @@ +/* + * 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 com.alibaba.dubboadmin.governance.service.impl; + +import java.util.List; +import java.util.Map; + +import com.alibaba.dubboadmin.governance.service.UserService; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.registry.common.util.Coder; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * 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 findAllUsers() { + // TODO Auto-generated method stub + return null; + } + + public Map 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 findUsersByServiceName(String serviceName) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/RegistryServerSync.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/RegistryServerSync.java new file mode 100644 index 0000000..40d2ea2 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/RegistryServerSync.java @@ -0,0 +1,162 @@ +/* + * 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 com.alibaba.dubboadmin.governance.sync; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; +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 com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class RegistryServerSync implements InitializingBean, DisposableBean, NotifyListener { + + private static final Logger logger = LoggerFactory.getLogger(RegistryServerSync.class); + + private static final URL SUBSCRIBE = new URL(Constants.ADMIN_PROTOCOL, NetUtils.getLocalHost(), 0, "", + Constants.INTERFACE_KEY, Constants.ANY_VALUE, + Constants.GROUP_KEY, Constants.ANY_VALUE, + Constants.VERSION_KEY, Constants.ANY_VALUE, + Constants.CLASSIFIER_KEY, Constants.ANY_VALUE, + Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + "," + + Constants.CONSUMERS_CATEGORY + "," + + Constants.ROUTERS_CATEGORY + "," + + Constants.CONFIGURATORS_CATEGORY, + Constants.ENABLED_KEY, Constants.ANY_VALUE, + Constants.CHECK_KEY, String.valueOf(false)); + + private static final AtomicLong ID = new AtomicLong(); + + /** + * Make sure ID never changed when the same url notified many times + */ + private final ConcurrentHashMap URL_IDS_MAPPER = new ConcurrentHashMap(); + + // ConcurrentMap>> + private final ConcurrentMap>> + registryCache = new ConcurrentHashMap>>(); + @Autowired + private RegistryService registryService; + + public ConcurrentMap>> getRegistryCache() { + return registryCache; + } + + public void afterPropertiesSet() throws Exception { + logger.info("Init Dubbo Admin Sync Cache..."); + registryService.subscribe(SUBSCRIBE, this); + } + + public void destroy() throws Exception { + registryService.unsubscribe(SUBSCRIBE, this); + } + + // Notification of of any service with any type (override、subcribe、route、provider) is full. + public void notify(List urls) { + if (urls == null || urls.isEmpty()) { + return; + } + // Map>> + final Map>> categories = new HashMap>>(); + String interfaceName = null; + for (URL url : urls) { + String category = url.getParameter(Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY); + if (Constants.EMPTY_PROTOCOL.equalsIgnoreCase(url.getProtocol())) { // NOTE: group and version in empty protocol is * + ConcurrentMap> services = registryCache.get(category); + if (services != null) { + String group = url.getParameter(Constants.GROUP_KEY); + String version = url.getParameter(Constants.VERSION_KEY); + // NOTE: group and version in empty protocol is * + if (!Constants.ANY_VALUE.equals(group) && !Constants.ANY_VALUE.equals(version)) { + services.remove(url.getServiceKey()); + } else { + for (Map.Entry> serviceEntry : services.entrySet()) { + String service = serviceEntry.getKey(); + if (Tool.getInterface(service).equals(url.getServiceInterface()) + && (Constants.ANY_VALUE.equals(group) || StringUtils.isEquals(group, Tool.getGroup(service))) + && (Constants.ANY_VALUE.equals(version) || StringUtils.isEquals(version, Tool.getVersion(service)))) { + services.remove(service); + } + } + } + } + } else { + if (StringUtils.isEmpty(interfaceName)) { + interfaceName = url.getServiceInterface(); + } + Map> services = categories.get(category); + if (services == null) { + services = new HashMap>(); + categories.put(category, services); + } + String service = url.getServiceKey(); + Map ids = services.get(service); + if (ids == null) { + ids = new HashMap(); + services.put(service, ids); + } + + // Make sure we use the same ID for the same URL + if (URL_IDS_MAPPER.containsKey(url.toFullString())) { + ids.put(URL_IDS_MAPPER.get(url.toFullString()), url); + } else { + long currentId = ID.incrementAndGet(); + ids.put(currentId, url); + URL_IDS_MAPPER.putIfAbsent(url.toFullString(), currentId); + } + } + } + if (categories.size() == 0) { + return; + } + for (Map.Entry>> categoryEntry : categories.entrySet()) { + String category = categoryEntry.getKey(); + ConcurrentMap> services = registryCache.get(category); + if (services == null) { + services = new ConcurrentHashMap>(); + registryCache.put(category, services); + } else {// Fix map can not be cleared when service is unregistered: when a unique “group/service:version” service is unregistered, but we still have the same services with different version or group, so empty protocols can not be invoked. + Set keys = new HashSet(services.keySet()); + for (String key : keys) { + if (Tool.getInterface(key).equals(interfaceName) && !categoryEntry.getValue().entrySet().contains(key)) { + services.remove(key); + } + } + } + services.putAll(categoryEntry.getValue()); + } + } +} + diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/util/Pair.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/util/Pair.java new file mode 100644 index 0000000..0fbed83 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/util/Pair.java @@ -0,0 +1,84 @@ +/* + * 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 com.alibaba.dubboadmin.governance.sync.util; + +import java.util.Map; + +public class Pair implements Map.Entry { + + private K key; + + private V value; + + public Pair() { + } + + public Pair(K key, V value) { + this.key = key; + this.value = value; + } + + public K getKey() { + return key; + } + + public void setKey(K key) { + this.key = key; + } + + public V getValue() { + return value; + } + + public V setValue(V value) { + V old = this.value; + this.value = value; + return old; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Pair other = (Pair) obj; + if (key == null) { + if (other.key != null) + return false; + } else if (!key.equals(other.key)) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/util/SyncUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/util/SyncUtils.java new file mode 100644 index 0000000..96e94a3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/sync/util/SyncUtils.java @@ -0,0 +1,256 @@ +/* + * 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 com.alibaba.dubboadmin.governance.sync.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.domain.Route; + +public class SyncUtils { + + public static final String SERVICE_FILTER_KEY = ".service"; + + public static final String ADDRESS_FILTER_KEY = ".address"; + + public static final String ID_FILTER_KEY = ".id"; + + public static Provider url2Provider(Pair pair) { + if (pair == null) { + return null; + } + + Long id = pair.getKey(); + URL url = pair.getValue(); + + if (url == null) + return null; + + Provider p = new Provider(); + p.setId(id); + p.setService(url.getServiceKey()); + p.setAddress(url.getAddress()); + p.setApplication(url.getParameter(Constants.APPLICATION_KEY)); + p.setUrl(url.toIdentityString()); + p.setParameters(url.toParameterString()); + + p.setDynamic(url.getParameter("dynamic", true)); + p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true)); + p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT)); + p.setUsername(url.getParameter("owner")); + + return p; + } + + public static List url2ProviderList(Map ps) { + List ret = new ArrayList(); + for (Map.Entry entry : ps.entrySet()) { + ret.add(url2Provider(new Pair(entry.getKey(), entry.getValue()))); + } + return ret; + } + + public static Consumer url2Consumer(Pair pair) { + if (pair == null) { + return null; + } + + Long id = pair.getKey(); + URL url = pair.getValue(); + + if (null == url) + return null; + + Consumer c = new Consumer(); + c.setId(id); + c.setService(url.getServiceKey()); + c.setAddress(url.getHost()); + c.setApplication(url.getParameter(Constants.APPLICATION_KEY)); + c.setParameters(url.toParameterString()); + + return c; + } + + public static List url2ConsumerList(Map cs) { + List list = new ArrayList(); + if (cs == null) return list; + for (Map.Entry entry : cs.entrySet()) { + list.add(url2Consumer(new Pair(entry.getKey(), entry.getValue()))); + } + return list; + } + + public static Route url2Route(Pair pair) { + if (pair == null) { + return null; + } + + Long id = pair.getKey(); + URL url = pair.getValue(); + + if (null == url) + return null; + + Route r = new Route(); + r.setId(id); + r.setName(url.getParameter("name")); + r.setService(url.getServiceKey()); + r.setPriority(url.getParameter(Constants.PRIORITY_KEY, 0)); + r.setEnabled(url.getParameter(Constants.ENABLED_KEY, true)); + r.setForce(url.getParameter(Constants.FORCE_KEY, false)); + r.setRule(url.getParameterAndDecoded(Constants.RULE_KEY)); + return r; + } + + public static List url2RouteList(Map cs) { + List list = new ArrayList(); + if (cs == null) return list; + for (Map.Entry entry : cs.entrySet()) { + list.add(url2Route(new Pair(entry.getKey(), entry.getValue()))); + } + return list; + } + + public static Override url2Override(Pair pair) { + if (pair == null) { + return null; + } + + Long id = pair.getKey(); + URL url = pair.getValue(); + + if (null == url) + return null; + + Override o = new Override(); + o.setId(id); + + Map parameters = new HashMap(url.getParameters()); + + o.setService(url.getServiceKey()); + parameters.remove(Constants.INTERFACE_KEY); + parameters.remove(Constants.GROUP_KEY); + parameters.remove(Constants.VERSION_KEY); + parameters.remove(Constants.APPLICATION_KEY); + parameters.remove(Constants.CATEGORY_KEY); + parameters.remove(Constants.DYNAMIC_KEY); + parameters.remove(Constants.ENABLED_KEY); + + o.setEnabled(url.getParameter(Constants.ENABLED_KEY, true)); + + String host = url.getHost(); + boolean anyhost = url.getParameter(Constants.ANYHOST_VALUE, false); + if (!anyhost || !"0.0.0.0".equals(host)) { + o.setAddress(url.getAddress()); + } + + o.setApplication(url.getParameter(Constants.APPLICATION_KEY, url.getUsername())); + parameters.remove(Constants.VERSION_KEY); + + o.setParams(StringUtils.toQueryString(parameters)); + + return o; + } + + // Map>> + public static >> Map filterFromCategory(Map urls, Map filter) { + String c = (String) filter.get(Constants.CATEGORY_KEY); + if (c == null) throw new IllegalArgumentException("no category"); + + filter.remove(Constants.CATEGORY_KEY); + return filterFromService(urls.get(c), filter); + } + + public static List url2OverrideList(Map cs) { + List + list = new ArrayList(); + if (cs == null) return list; + for (Map.Entry entry : cs.entrySet()) { + list.add(url2Override(new Pair(entry.getKey(), entry.getValue()))); + } + return list; + } + + + // Map> + public static Map filterFromService(Map> urls, Map filter) { + Map ret = new HashMap(); + if (urls == null) return ret; + + String s = (String) filter.remove(SERVICE_FILTER_KEY); + if (s == null) { + for (Map.Entry> entry : urls.entrySet()) { + filterFromUrls(entry.getValue(), ret, filter); + } + } else { + Map map = urls.get(s); + filterFromUrls(map, ret, filter); + } + + return ret; + } + + // Map + static void filterFromUrls(Map from, Map to, Map filter) { + if (from == null || from.isEmpty()) return; + + for (Map.Entry entry : from.entrySet()) { + URL url = entry.getValue(); + + boolean match = true; + for (Map.Entry e : filter.entrySet()) { + String key = e.getKey(); + String value = e.getValue(); + + if (ADDRESS_FILTER_KEY.equals(key)) { + if (!value.equals(url.getAddress())) { + match = false; + break; + } + } else { + if (!value.equals(url.getParameter(key))) { + match = false; + break; + } + } + } + + if (match) { + to.put(entry.getKey(), url); + } + } + } + + public static >> Pair filterFromCategory(Map urls, String category, Long id) { + SM services = urls.get(category); + if (services == null) return null; + + for (Map.Entry> e1 : services.entrySet()) { + Map u = e1.getValue(); + if (u.containsKey(id)) return new Pair(id, u.get(id)); + } + return null; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/ContextUtil.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/ContextUtil.java new file mode 100644 index 0000000..d4e6838 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/ContextUtil.java @@ -0,0 +1,38 @@ +/* + * 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 com.alibaba.dubboadmin.governance.util; + +import java.util.Map; + +/** + * TODO Comment of ContextUtil + * + */ +public class ContextUtil { + + private ContextUtil(Map c) { + } + + public static Object get(Map context, Object key, Object defaultv) { + Object res = context.get(key); + if (res == null) { + res = defaultv; + } + return res; + } +} + diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/GovernanceWarmup.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/GovernanceWarmup.java new file mode 100644 index 0000000..e23c86a --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/GovernanceWarmup.java @@ -0,0 +1,108 @@ +/* + * 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 com.alibaba.dubboadmin.governance.util; + +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; +import com.alibaba.dubbo.common.status.StatusChecker; +import com.alibaba.dubboadmin.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; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/Paginator.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/Paginator.java new file mode 100644 index 0000000..4ec1152 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/Paginator.java @@ -0,0 +1,195 @@ +/* + * 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 com.alibaba.dubboadmin.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("
"); + str.append(""); + + // generate flip section + // The total number of records + str.append("total items: " + this.totalItems + "  "); + + // 2. Pages: current page / total pages + str.append("page " + this.currentPage + " of " + this.totalPage + "nbsp; "); + + // 3. Home, Previous + if (this.currentPage > 1) { + str.append("Home"); + str.append("Previous"); + } else { + str.append("Home"); + str.append("Previous"); + } + + // 4. Activity block + int[] slider = getSlider(); + for (int i = 0; i < slider.length; i++) { + if (slider[i] == this.currentPage) { + str.append(""); + } else { + str.append(""); + } + str.append(slider[i] + ""); + } + + // 5. Next page + if (this.currentPage < this.totalPage) { + str.append(""); + } else { + str.append(""); + } + str.append("Next  "); + + // 6. Jump section + str.append("jump to page "); + str.append(""); + + // 7. Implicit conditions + str.append("
"); + return str.toString(); + } + + /** + * Get the initial record + * + * @return + */ + public int getStartIndex() { + return (this.currentPage - 1) * this.itemsPerPage + 1; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/UrlUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/UrlUtils.java new file mode 100644 index 0000000..15fa653 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/UrlUtils.java @@ -0,0 +1,61 @@ +/* + * 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 com.alibaba.dubboadmin.governance.util; + +import java.util.Map; +import java.util.Map.Entry; + +/** + * UrlUtils.java + * + */ +public class UrlUtils { + + public static String paramsMapToString(Map params) { + StringBuilder paramsString = new StringBuilder(); + for (Entry param : params.entrySet()) { + if (paramsString != null) { + paramsString.append("&"); + } + paramsString.append(param.getKey()); + paramsString.append("="); + for (int i = 0; i < param.getValue().length; i++) { + if (i == 0) { + paramsString.append(param.getValue()[i]); + } else { + paramsString.append(","); + paramsString.append(param.getValue()[i]); + } + } + } + return paramsString.toString(); + } + + public static String arrayToString(String[] values) { + StringBuilder paramsString = new StringBuilder(); + for (int i = 0; i < values.length; i++) { + if (i == 0) { + paramsString.append(values[i]); + } else { + paramsString.append(","); + paramsString.append(values[i]); + } + } + return paramsString.toString(); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/WebConstants.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/WebConstants.java new file mode 100644 index 0000000..9d6cc3f --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/governance/util/WebConstants.java @@ -0,0 +1,85 @@ +/* + * 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 com.alibaba.dubboadmin.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 context; + + public static final Map 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"); + } + + + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/ChangeListener.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/ChangeListener.java new file mode 100644 index 0000000..d74361c --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/ChangeListener.java @@ -0,0 +1,28 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common; + +public interface ChangeListener { + + /** + * Invoked when data changed + * + * @param type data type + */ + void onChanged(String type); + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/StatusManager.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/StatusManager.java new file mode 100644 index 0000000..5120bae --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/StatusManager.java @@ -0,0 +1,122 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.alibaba.dubbo.common.status.Status; +import com.alibaba.dubbo.common.status.Status.Level; +import com.alibaba.dubbo.common.status.StatusChecker; + +/** + * StatusManager + * + */ +public class StatusManager { + + private static final StatusManager INSTANCE = new StatusManager(); + private final Map statusHandlers = new ConcurrentHashMap(); + + private StatusManager() { + } + + public static StatusManager getInstance() { + return INSTANCE; + } + + public static Status getStatusSummary(Map statusList) { + return getSummaryStatus(statusList); + } + + public static Status getSummaryStatus(Map statuses) { + Level level = Level.OK; + StringBuilder msg = new StringBuilder(); + for (Map.Entry 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 statusHandlers) { + this.statusHandlers.putAll(statusHandlers); + } + + public void addStatusHandlers(Collection 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 getStatusList() { + return getStatusList(null); + } + + /** + * Exclude items do not need to show in Summary Page + */ + public Map getStatusList(String[] excludes) { + Map statuses = new HashMap(); + Map temp = new HashMap(); + temp.putAll(statusHandlers); + if (excludes != null && excludes.length > 0) { + for (String exclude : excludes) { + temp.remove(exclude); + } + } + for (Map.Entry entry : temp.entrySet()) { + statuses.put(entry.getKey(), entry.getValue().check()); + } + return statuses; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Access.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Access.java new file mode 100644 index 0000000..28baf26 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Access.java @@ -0,0 +1,70 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +public class Access extends Entity { + + private static final long serialVersionUID = -962351722638094446L; + + private String service; /*service name*/ + + private String address; /*address of consumer*/ + + private boolean allow; /*status*/ + + private String username; /*user name*/ + + public Access() { + } + + public Access(Long id) { + super(id); + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public boolean isAllow() { + return allow; + } + + public void setAllow(boolean allow) { + this.allow = allow; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Agreement.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Agreement.java new file mode 100644 index 0000000..8a55871 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Agreement.java @@ -0,0 +1,104 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * Specifies the applied Quality of Service Level Agreement (SLA) object. + * + */ +public class Agreement extends Entity { + + private static final long serialVersionUID = -4888604682731513790L; + + private String service; // service name + + private String consumerApplication; // application of consumer + + private long invocationQuantity; // call of the day + + private int tps; // TPS limit + + private int responseTime; // Response time in milliseconds + + private double availability; // ratio of available + + private String username; + + public Agreement() { + } + + public Agreement(Long id) { + super(id); + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getConsumerApplication() { + return consumerApplication; + } + + public void setConsumerApplication(String consumerApplication) { + this.consumerApplication = consumerApplication; + } + + public long getInvocationQuantity() { + return invocationQuantity; + } + + public void setInvocationQuantity(long invocationQuantity) { + this.invocationQuantity = invocationQuantity; + } + + public int getTps() { + return tps; + } + + public void setTps(int tps) { + this.tps = tps; + } + + public int getResponseTime() { + return responseTime; + } + + public void setResponseTime(int responseTime) { + this.responseTime = responseTime; + } + + public double getAvailability() { + return availability; + } + + public void setAvailability(double availability) { + this.availability = availability; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Approval.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Approval.java new file mode 100644 index 0000000..921381c --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Approval.java @@ -0,0 +1,89 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * Service online approval. + * + */ +public class Approval extends Entity { + private static final long serialVersionUID = -8778092807313048367L; + + private String service; // service name + + private String version; + // You can use wildcards, *,1.1.* + // Can contain more than one, 1.1.3,1.1.5,2.* + + private boolean forProvider; // Provider or consumer + + private String machineList; // service machine + // You can use wildcards, 172.3.8.* + // an contain more than one, 172.1.9.8,172.1.9.123,172.3.3.* + + private String username; + + private String approveUser; // approver + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public boolean isForProvider() { + return forProvider; + } + + public void setForProvider(boolean forProvider) { + this.forProvider = forProvider; + } + + public String getMachineList() { + return machineList; + } + + public void setMachineList(String machineList) { + this.machineList = machineList; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getApproveUser() { + return approveUser; + } + + public void setApproveUser(String approveUser) { + this.approveUser = approveUser; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/ApprovalRequisition.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/ApprovalRequisition.java new file mode 100644 index 0000000..d28ef0a --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/ApprovalRequisition.java @@ -0,0 +1,99 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * Service online / offline approval + * + */ +public class ApprovalRequisition extends Entity { + private static final long serialVersionUID = -8778092807313048367L; + + private char operation; // Apply for action: add (C), modify (U), delete (D) + + private Long approvalId; + + private String service; // service name + + private String version; + // wildcards, *,1.1.* + // more than one, 1.1.3,1.1.5,2.* + + private boolean forProvider; + + private String machineList; // servcice machine + // wildcards, 172.3.8.* + // more thaan one, 172.1.9.8,172.1.9.123,172.3.3.* + + private String username; + + public char getOperation() { + return operation; + } + + public void setOperation(char operation) { + this.operation = operation; + } + + public Long getApprovalId() { + return approvalId; + } + + public void setApprovalId(Long approvalId) { + this.approvalId = approvalId; + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public boolean isForProvider() { + return forProvider; + } + + public void setForProvider(boolean forProvider) { + this.forProvider = forProvider; + } + + public String getMachineList() { + return machineList; + } + + public void setMachineList(String machineList) { + this.machineList = machineList; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Change.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Change.java new file mode 100644 index 0000000..6859de7 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Change.java @@ -0,0 +1,99 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * Service change information object + * + */ +public class Change extends Entity { + + public static final String PROVIDER_TYPE = "P"; //provider change + public static final String CONSUMER_TYPE = "N"; //consumer change + public static final String ROUTE_TYPE = "R"; //route change + public static final String WEIGHT_TYPE = "W"; //weight change + public static final String LOADBALANCE_TYPE = "L"; //loadbalance change + public static final String CLUSTER_TYPE = "G"; //group change + public static final String USER_TYPE = "U"; //user change + public static final String CONFIG_TYPE = "C"; //system config change + public static final String FEATURE_TYPE = "F"; //feature change + public static final String LAYER_TYPE = "Y"; //layer change + public static final String TEST_TYPE = "T"; //service test change + public static final String MOCK_TYPE = "M"; //service mock change + public static final String ACCESS_TYPE = "A"; //access change + public static final String OVERRIDE_TYPE = "O"; //override change + private static final long serialVersionUID = 15528419903956898L; + private String type; /* type of change */ + + private String service; /* service name */ + + private long sequence; /* NO. of change */ + + private String data; /* what is changed */ + + public Change() { + } + + public Change(Long id) { + super(id); + } + + public Change(String type, String serviceName) { + this.type = type; + this.service = serviceName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + @Deprecated + /** + * us id as sequence + */ + public long getSequence() { + return sequence; + } + + @Deprecated + /** + * use id as sequence + */ + public void setSequence(long sequence) { + this.sequence = sequence; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Cluster.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Cluster.java new file mode 100644 index 0000000..15124e3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Cluster.java @@ -0,0 +1,60 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +public class Cluster extends Entity { + + private static final long serialVersionUID = 8704571999015097948L; + + private String name; /* Service provider group name, a group can contain several providers*/ + + private String address; /* address of consumer */ + + private String username; + + public Cluster() { + } + + public Cluster(Long id) { + super(id); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Config.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Config.java new file mode 100644 index 0000000..72bfd40 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Config.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.registry.common.domain; + +/** + * Config instance + * + */ +public class Config extends Entity { + + public static final String MAIL_ENABLED = "MailEnabled"; + public static final String MAIL_HOST = "MailHost"; + public static final String MAIL_PORT = "MailPort"; + public static final String MAIL_FROM = "MailFrom"; + public static final String MAIL_AUTH = "MailAuth"; + public static final String MAIL_USERNAME = "MailUsername"; + public static final String MAIL_PASSWORD = "MailPassword"; + public static final String BULLETIN_MESSAGE = "BulletinMessage"; + public static final String ALLOW_ANONYMOUS_LOGIN = "AllowAnonymousLogin"; // Whether to allow anonymous login + public static final String ALLOW_LEGACY_LOGIN = "AllowLegacyLogin"; // Whether to allow legacy system login + public static final String MAX_THREAD_SIZE = "MaxThreadSize"; // The maximum number of threads + public static final String MAX_CONNECTION_SIZE = "MaxConnectionSize"; // The maximum number of connections + public static final String MAX_CACHE_SIZE = "MaxCacheSize"; // The maximum number of cache (not space) + public static final String MAX_MAIL_SIZE = "MaxMailSize"; // The maximum number of mail queues + public static final String ALIVED_CHECK_INTERVAL = "AlivedCheckInterval"; + public static final String DIRTY_CHECK_INTERVAL = "DirtyCheckInterval"; + public static final String CHANGED_CHECK_INTERVAL = "ChangedCheckInterval"; + public static final String CHANGED_CLEAR_INTERVAL = "ChangedClearInterval"; + public static final String FAILED_RETRY_INTERVAL = "FailedRetryInterval"; + public static final String HEARTBEAT_CHECK_INTERVAL = "HeartbeatCheckInterval";// Heartbeat check interval + public static final String HEARTBEAT_CHECK_TIMEOUT = "HeartbeatCheckTimeout";// The biggest interval for not receive a heartbeat + public static final String WARMUP_WAIT_TIME = "WarmupWaitTime"; + public static final String AUTO_REDIRECT_INTERVAL = "AutoRedirectInterval"; + public static final String AUTO_REDIRECT_THRESHOLD = "AutoRedirectThreshold"; + public static final String AUTO_REDIRECT_TOLERATE_PERCENT = "AutoRedirectToleratePercent"; + public static final String NOTIFY_TIMEOUT = "NotifyTimeout"; + public static final String ROUTE_ENABLED = "RouteEnabled"; + public static final String BUC_SERVICE_ADDRESS = "BucServiceAddress"; + public static final String DEFAULT_SERVICE_PARAMETERS = "DefaultServiceParameters"; + public static final String WARM_UP_ENABLED = "WarmupEnabled"; + public static final String HELP_DOCUMENT_URL = "HelpDocumentUrl"; + public static final String HOMEPAGE_DOMAIN = "HomepageDomain"; + public static final String HOMEPAGE_URL = "HomepageUrl"; + public static final String LOG_LEVEL = "LogLevel"; + public static final String DEFAULT_ROLE = "DefaultRole"; // The default role of user + public static final String SERVER_ROUTE_ENABLED = "ServerRouteEnabled"; + private static final long serialVersionUID = 7938303018328907548L; + private String key; + + private String value; + + private String username; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + @java.lang.Override + public String toString() { + return key + "=" + value; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Consumer.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Consumer.java new file mode 100644 index 0000000..c02f802 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Consumer.java @@ -0,0 +1,229 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.StringUtils; + +/** + * Consumer + * + */ +public class Consumer extends Entity { + + private static final long serialVersionUID = -1140894843784583237L; + + private String service; /* The name of the service referenced by the consumer */ + + private String parameters; + + private String result; /*route result*/ + + private String address; /* address of consumer */ + + private String registry; /* Consumer connected registry address */ + + private String application; /* application name */ + + private String username; /* user name of consumer */ + + private String statistics; /* Service call statistics */ + + private Date collected; /* Date statistics was recorded */ + + private Override override; + + private List overrides; + + private List routes; + + private List providers; + + private Date expired; + + private long alived; /*Time to live in milliseconds*/ + + public Consumer() { + } + + public Consumer(Long id) { + super(id); + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getParameters() { + return parameters; + } + + public void setParameters(String parameters) { + this.parameters = parameters; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getRegistry() { + return registry; + } + + public void setRegistry(String registry) { + this.registry = registry; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getStatistics() { + return statistics; + } + + public void setStatistics(String statistics) { + this.statistics = statistics; + } + + public Date getCollected() { + return collected; + } + + public void setCollected(Date collected) { + this.collected = collected; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getApplication() { + return application; + } + + public void setApplication(String application) { + this.application = application; + } + + public Date getExpired() { + return expired; + } + + + public void setExpired(Date expired) { + this.expired = expired; + } + + + public long getAlived() { + return alived; + } + + + public void setAlived(long alived) { + this.alived = alived; + } + + public Override getOverride() { + return override; + } + + public void setOverride(Override override) { + this.override = override; + } + + public List getOverrides() { + return overrides; + } + + public void setOverrides(List overrides) { + this.overrides = overrides; + } + + public List getRoutes() { + return routes; + } + + public void setRoutes(List routes) { + this.routes = routes; + } + + public List getProviders() { + return providers; + } + + public void setProviders(List providers) { + this.providers = providers; + } + + public String toString() { + return "Consumer [service=" + service + ", parameters=" + parameters + ", result=" + result + + ", address=" + address + ", registry=" + registry + ", application=" + + application + ", username=" + username + ", statistics=" + statistics + + ", collected=" + collected + ", routes=" + routes + ", overrides=" + overrides + + ", expired=" + expired + ", alived=" + alived + "]"; + } + + public URL toUrl() { + String group = null; + String version = null; + String path = service; + int i = path.indexOf("/"); + if (i > 0) { + group = path.substring(0, i); + path = path.substring(i + 1); + } + i = path.lastIndexOf(":"); + if (i > 0) { + version = path.substring(i + 1); + path = path.substring(0, i); + } + Map param = StringUtils.parseQueryString(parameters); + param.put(Constants.CATEGORY_KEY, Constants.CONSUMERS_CATEGORY); + if (group != null) { + param.put(Constants.GROUP_KEY, group); + } + if (version != null) { + param.put(Constants.VERSION_KEY, version); + } + return URL.valueOf(Constants.CONSUMER_PROTOCOL + "://" + address + "/" + path + + "?" + StringUtils.toQueryString(param)); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/DependItem.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/DependItem.java new file mode 100644 index 0000000..0a0524b --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/DependItem.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.registry.common.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * DependItem + * + */ +public class DependItem { + + private final List recursives = new ArrayList(); + 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 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 + + "]"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Dependency.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Dependency.java new file mode 100644 index 0000000..46f1032 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Dependency.java @@ -0,0 +1,45 @@ +/* + * 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 com.alibaba.dubboadmin.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; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Document.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Document.java new file mode 100644 index 0000000..95b8f9b --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Document.java @@ -0,0 +1,86 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * Document + * + */ +public class Document extends Entity { + + public static final String EXTERNAL_TYPE = "E"; + public static final String INTERNAL_TYPE = "I"; + public static final String API_TYPE = "A"; + private static final long serialVersionUID = 5059135057592486874L; + private String service; + + private String title; + + private String type; + + private String content; + + private String username; + + public Document() { + } + + public Document(Long id) { + super(id); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Entity.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Entity.java new file mode 100644 index 0000000..54531f7 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Entity.java @@ -0,0 +1,121 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * Entity + * + */ +public abstract class Entity implements Serializable { + + private static final long serialVersionUID = -3031128781434583143L; + + private List ids; + + private Long id; + + private Date created; + + private Date modified; + + private Date now; + + private String operator; + + private String operatorAddress; + + private boolean miss; + + public Entity() { + } + + public Entity(Long id) { + this.id = id; + } + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Date getModified() { + return modified; + } + + public void setModified(Date modified) { + this.modified = modified; + } + + public Date getNow() { + return now; + } + + public void setNow(Date now) { + this.now = now; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + if (operator != null && operator.length() > 200) { + operator = operator.substring(0, 200); + } + this.operator = operator; + } + + public String getOperatorAddress() { + return operatorAddress; + } + + public void setOperatorAddress(String operatorAddress) { + this.operatorAddress = operatorAddress; + } + + public boolean isMiss() { + return miss; + } + + public void setMiss(boolean miss) { + this.miss = miss; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Favorite.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Favorite.java new file mode 100644 index 0000000..bc65057 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Favorite.java @@ -0,0 +1,60 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +public class Favorite extends Entity { + + private static final long serialVersionUID = -1281982267153430266L; + + private String name; + + private String url; + + private String username; + + public Favorite() { + } + + public Favorite(Long id) { + super(id); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Feature.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Feature.java new file mode 100644 index 0000000..f751ff5 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Feature.java @@ -0,0 +1,62 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * System features + */ +public class Feature extends Entity { + + private static final long serialVersionUID = 3246619851259746169L; + + private String name; + + private boolean enabled; + + private String username; + + public Feature() { + } + + public Feature(Long id) { + super(id); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean getEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Layer.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Layer.java new file mode 100644 index 0000000..0ad3acf --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Layer.java @@ -0,0 +1,66 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +public class Layer extends Entity { + private static final long serialVersionUID = 6114868933223039253L; + + private String username; + + private String arch; + private String name; + private int value; + + public Layer(Long id) { + super(id); + } + + public Layer() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getArch() { + return arch; + } + + public void setArch(String arch) { + this.arch = arch; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/LoadBalance.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/LoadBalance.java new file mode 100644 index 0000000..651b8ca --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/LoadBalance.java @@ -0,0 +1,75 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * LoadBalance + * + */ +public class LoadBalance extends Entity { + + public static final String ALL_METHOD = "*"; + private static final long serialVersionUID = -6050324375352581440L; + private String service; /* service name */ + + private String method; /* method name */ + + private String strategy; /*loadbalance policy*/ + + private String username; + + public LoadBalance() { + } + + public LoadBalance(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 getStrategy() { + return strategy; + } + + public void setStrategy(String strategy) { + this.strategy = strategy; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Mock.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Mock.java new file mode 100644 index 0000000..1d88db7 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Mock.java @@ -0,0 +1,124 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +/** + * Mock + * + */ +public class Mock 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; + + private String consumerAddr; + + public Mock() { + } + + public Mock(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; + } + + public String getConsumerAddr() { + return consumerAddr; + } + + public void setConsumerAddr(String consumerAddr) { + this.consumerAddr = consumerAddr; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Operation.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Operation.java new file mode 100644 index 0000000..6043242 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Operation.java @@ -0,0 +1,100 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Record error messages and record all user operations + * + */ +public class Operation extends Entity { + + public static final String PROVIDER_TYPE = "Provider"; + public static final String CONSUMER_TYPE = "Consumer"; + public static final String ROUTE_TYPE = "Route"; + public static final String WEIGHT_TYPE = "Weight"; + public static final String CLUSTER_TYPE = "Cluster"; + public static final String DOCUMENT_TYPE = "Document"; + public static final String LOADBALANCE_TYPE = "LoadBalance"; + public static final String TEST_TYPE = "Test"; + public static final String MOCK_TYPE = "Mock"; + public static final String AGREEMENT_TYPE = "Agreement"; + public static final String APPROVAL_TYPE = "Approval"; + public static final String APPROVAL_REQUISITION_TYPE = "ApprovalRequisition"; + public static final String USER_TYPE = "User"; + public static final String FEATURE_TYPE = "Feature"; + public static final String LAYER_TYPE = "Layer"; + public static final String CONFIG_TYPE = "Config"; + public static final List TYPES = + Collections.unmodifiableList( + Arrays.asList(new String[]{PROVIDER_TYPE, CONSUMER_TYPE, ROUTE_TYPE, WEIGHT_TYPE, + CLUSTER_TYPE, DOCUMENT_TYPE, LOADBALANCE_TYPE, TEST_TYPE, + AGREEMENT_TYPE, USER_TYPE, FEATURE_TYPE, CONFIG_TYPE})); + private static final long serialVersionUID = 8220325876753890396L; + private String username; // operator + + private String dataType; // data type, e.g., route, cluster + + private String operateType; // operations, e.g. update, create + + private String data; // record data information + + public Operation() { + } + + public Operation(Long id) { + super(id); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public String getData() { + return data; + } + + public void setData(String data) { + if (data != null && data.length() > 1000) { + data = data.substring(0, 1000); + } + this.data = data; + } + + public String getOperateType() { + return operateType; + } + + public void setOperateType(String operateType) { + this.operateType = operateType; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Override.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Override.java new file mode 100644 index 0000000..eeedd20 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Override.java @@ -0,0 +1,202 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.StringUtils; + +public class Override extends Entity { + + private static final long serialVersionUID = 114828505391757846L; + + private String service; + + private String params; + + private String application; + + private String address; + + private String username; + + private boolean enabled; + + public Override() { + } + + public Override(long id) { + super(id); + } + + public String getService() { + return service; + } + + + public void setService(String service) { + this.service = service; + } + + + public String getParams() { + return params; + } + + + public void setParams(String params) { + this.params = params; + } + + + public String getApplication() { + return application; + } + + + public void setApplication(String application) { + this.application = application; + } + + + public String getAddress() { + return address; + } + + + public void setAddress(String address) { + this.address = address; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + + public boolean isEnabled() { + return enabled; + } + + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String toString() { + return "Override [service=" + service + ", params=" + params + ", application=" + + application + ", address=" + address + ", username=" + username + ", enabled=" + enabled + "]"; + } + + public boolean isDefault() { + return (getAddress() == null || getAddress().length() == 0 || Constants.ANY_VALUE.equals(getAddress()) || Constants.ANYHOST_VALUE.equals(getAddress())) + && (getApplication() == null || getApplication().length() == 0 || Constants.ANY_VALUE.equals(getApplication())); + } + + public boolean isMatch(String service, String address, String application) { + return isEnabled() && getParams() != null && getParams().length() > 0 + && service.equals(getService()) + && (address == null || getAddress() == null || getAddress().length() == 0 || getAddress().equals(Constants.ANY_VALUE) || getAddress().equals(Constants.ANYHOST_VALUE) || getAddress().equals(address)) + && (application == null || getApplication() == null || getApplication().length() == 0 || getApplication().equals(Constants.ANY_VALUE) || getApplication().equals(application)); + } + + public boolean isUniqueMatch(Provider provider) { + return isEnabled() && getParams() != null && getParams().length() > 0 + && provider.getService().equals(getService()) + && provider.getAddress().equals(getAddress()); + } + + public boolean isMatch(Provider provider) { + return isEnabled() && getParams() != null && getParams().length() > 0 + && provider.getService().equals(getService()) + && (getAddress() == null || getAddress().length() == 0 || getAddress().equals(Constants.ANY_VALUE) || getAddress().equals(Constants.ANYHOST_VALUE) || getAddress().equals(provider.getAddress())) + && (getApplication() == null || getApplication().length() == 0 || getApplication().equals(Constants.ANY_VALUE) || getApplication().equals(provider.getApplication())); + } + + public boolean isUniqueMatch(Consumer consumer) { + return isEnabled() && getParams() != null && getParams().length() > 0 + && consumer.getService().equals(getService()) + && consumer.getAddress().equals(getAddress()); + } + + public boolean isMatch(Consumer consumer) { + return isEnabled() && getParams() != null && getParams().length() > 0 + && consumer.getService().equals(getService()) + && (getAddress() == null || getAddress().length() == 0 || getAddress().equals(Constants.ANY_VALUE) || getAddress().equals(Constants.ANYHOST_VALUE) || getAddress().equals(consumer.getAddress())) + && (getApplication() == null || getApplication().length() == 0 || getApplication().equals(Constants.ANY_VALUE) || getApplication().equals(consumer.getApplication())); + } + + public Map toParametersMap() { + Map map = StringUtils.parseQueryString(getParams()); + map.remove(Constants.INTERFACE_KEY); + map.remove(Constants.GROUP_KEY); + map.remove(Constants.VERSION_KEY); + map.remove(Constants.APPLICATION_KEY); + map.remove(Constants.CATEGORY_KEY); + map.remove(Constants.DYNAMIC_KEY); + map.remove(Constants.ENABLED_KEY); + return map; + } + + public URL toUrl() { + String group = null; + String version = null; + String path = service; + int i = path.indexOf("/"); + if (i > 0) { + group = path.substring(0, i); + path = path.substring(i + 1); + } + i = path.lastIndexOf(":"); + if (i > 0) { + version = path.substring(i + 1); + path = path.substring(0, i); + } + StringBuilder sb = new StringBuilder(); + sb.append(Constants.OVERRIDE_PROTOCOL); + sb.append("://"); + if (!StringUtils.isBlank(address) && !Constants.ANY_VALUE.equals(address)) { + sb.append(address); + } else { + sb.append(Constants.ANYHOST_VALUE); + } + sb.append("/"); + sb.append(path); + sb.append("?"); + Map param = StringUtils.parseQueryString(params); + param.put(Constants.CATEGORY_KEY, Constants.CONFIGURATORS_CATEGORY); + param.put(Constants.ENABLED_KEY, String.valueOf(isEnabled())); + param.put(Constants.DYNAMIC_KEY, "false"); + if (!StringUtils.isBlank(application) && !Constants.ANY_VALUE.equals(application)) { + param.put(Constants.APPLICATION_KEY, application); + } + if (group != null) { + param.put(Constants.GROUP_KEY, group); + } + if (version != null) { + param.put(Constants.VERSION_KEY, version); + } + sb.append(StringUtils.toQueryString(param)); + return URL.valueOf(sb.toString()); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Owner.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Owner.java new file mode 100644 index 0000000..278fb83 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Owner.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.registry.common.domain; + +public class Owner extends Entity { + + private static final long serialVersionUID = -4891350118145794727L; + + /** + * wildcards allowed + */ + private String service; + + private String username; + + private User user; + + public Owner() { + } + + public Owner(Long id) { + super(id); + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/PageList.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/PageList.java new file mode 100644 index 0000000..6405c32 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/PageList.java @@ -0,0 +1,101 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.io.Serializable; +import java.util.List; + +/** + * PageList + * + */ +public class PageList implements Serializable { + + private static final long serialVersionUID = 43869560130672722L; + + private int start; + + private int limit; + + private int total; + + private List list; + + public PageList() { + } + + public PageList(int start, int limit, int total, List 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 getList() { + return list; + } + + public void setList(List 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; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Provider.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Provider.java new file mode 100644 index 0000000..5675874 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Provider.java @@ -0,0 +1,214 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubboadmin.registry.common.registry.ConvertUtil; + +/** + * Provider + * + */ +public class Provider extends Entity { + + private static final long serialVersionUID = 5981342400350878171L; + + private String service;/* The name of the service provided by the provider */ + + private String url; /* Provider's address for service */ + + private String parameters; /* Provider provides service parameters */ + + private String address; /* Provider address */ + + private String registry;/* The provider's registry address */ + + private boolean dynamic; /* provider was registered dynamically */ + + private boolean enabled; /* provider enabled or not */ + + private int weight; /* provider weight */ + + private String application; /* application name */ + + private String username; /* operator */ + + private Date expired; /* time to expire */ + + private long alived; /* time to live in milliseconds */ + + private Override override; + + private List overrides; + + public Provider() { + } + + public Provider(Long id) { + super(id); + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getParameters() { + return parameters; + } + + public void setParameters(String parameters) { + this.parameters = parameters; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getRegistry() { + return registry; + } + + public void setRegistry(String registry) { + this.registry = registry; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getApplication() { + return application; + } + + public void setApplication(String application) { + this.application = application; + } + + public boolean isDynamic() { + return dynamic; + } + + public void setDynamic(boolean dynamic) { + this.dynamic = dynamic; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + + public Date getExpired() { + return expired; + } + + + public void setExpired(Date expired) { + this.expired = expired; + } + + public long getAlived() { + return alived; + } + + public void setAlived(long aliveSeconds) { + this.alived = aliveSeconds; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public Override getOverride() { + return override; + } + + public void setOverride(Override override) { + this.override = override; + } + + public List getOverrides() { + return overrides; + } + + public void setOverrides(List overrides) { + this.overrides = overrides; + } + + public URL toUrl() { + Map serviceName2Map = ConvertUtil.serviceName2Map(getService()); + /*if(!serviceName2Map.containsKey(Constants.INTERFACE_KEY)) { + throw new IllegalArgumentException("No interface info"); + } + if(!serviceName2Map.containsKey(Constants.VERSION_KEY)) { + throw new IllegalArgumentException("No version info"); + }*/ + + String u = getUrl(); + URL url = URL.valueOf(u + "?" + getParameters()); + + url = url.addParameters(serviceName2Map); + + boolean dynamic = isDynamic(); + if (!dynamic) { + url = url.addParameter(Constants.DYNAMIC_KEY, false); + } + boolean enabled = isEnabled(); + if (enabled != url.getParameter("enabled", true)) { + if (enabled) { + url = url.removeParameter("enabled"); + } else { + url = url.addParameter("enabled", false); + } + } + + return url; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Registry.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Registry.java new file mode 100644 index 0000000..a70464e --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Registry.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.registry.common.domain; + +import java.util.Date; + +/** + * Registry + * + */ +public class Registry extends Entity { + + private static final long serialVersionUID = -8866645978415551309L; + + private String registry;/* registry address */ + + private String url; + + private int connections = 0;/* connections number to registry */ + + private Date expired; /*time to expire*/ + + private long alived; + + public Registry() { + } + + public Registry(Long id) { + super(id); + } + + public Registry(String registryAddress, String consoleUrl, int aliveSeconds) { + this.registry = registryAddress; + this.url = consoleUrl; + this.alived = aliveSeconds; + } + + public String getAddress() { + return registry; + } + + public void setAddress(String registry) { + this.registry = registry; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Date getExpired() { + return expired; + } + + public void setExpired(Date expiredDate) { + this.expired = expiredDate; + } + + public long getAlived() { + return alived; + } + + public void setAlived(long aliveSeconds) { + this.alived = aliveSeconds; + } + + + public int getConnections() { + return connections; + } + + + public void setConnections(int connections) { + this.connections = connections; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Route.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Route.java new file mode 100644 index 0000000..b6e8d47 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Route.java @@ -0,0 +1,201 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.util.List; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; + +/** + * Route + * + */ +public class Route extends Entity { + + public static final String ALL_METHOD = "*"; + public static final String KEY_METHOD = "method"; + + // WHEN KEY + public static final String KEY_CONSUMER_APPLICATION = "consumer.application"; + public static final String KEY_CONSUMER_GROUP = "consumer.cluster"; + public static final String KEY_CONSUMER_VERSION = "consumer.version"; + public static final String KEY_CONSUMER_HOST = "consumer.host"; + public static final String KEY_CONSUMER_METHODS = "consumer.methods"; + public static final String KEY_PROVIDER_APPLICATION = "provider.application"; + + // THEN KEY + public static final String KEY_PROVIDER_GROUP = "provider.cluster"; + public static final String KEY_PROVIDER_PROTOCOL = "provider.protocol"; + public static final String KEY_PROVIDER_VERSION = "provider.version"; + public static final String KEY_PROVIDER_HOST = "provider.host"; + public static final String KEY_PROVIDER_PORT = "provider.port"; + private static final long serialVersionUID = -7630589008164140656L; + private long parentId; //default 0 + + private String name; + + private String service; + + private String rule; + + private String matchRule; + + private String filterRule; + + private int priority; + + private String username; + + private boolean enabled; + + private boolean force; + + private List children; + + public Route() { + } + + public Route(Long id) { + super(id); + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public long getParentId() { + return parentId; + } + + public void setParentId(long parentId) { + this.parentId = parentId; + } + + public List getChildren() { + return children; + } + + public void setChildren(List subRules) { + this.children = subRules; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getRule() { + return rule; + } + + public void setRule(String rule) { + this.rule = rule; + String[] rules = rule.split(" => "); + if (rules.length != 2) { + throw new IllegalArgumentException("Illegal Route Condition Rule"); + } + this.matchRule = rules[0]; + this.filterRule = rules[1]; + } + + public String getMatchRule() { + return matchRule; + } + + public void setMatchRule(String matchRule) { + this.matchRule = matchRule; + } + + public String getFilterRule() { + return filterRule; + } + + public void setFilterRule(String filterRule) { + this.filterRule = filterRule; + } + + @java.lang.Override + public String toString() { + return "Route [parentId=" + parentId + ", name=" + name + + ", serviceName=" + service + ", matchRule=" + matchRule + + ", filterRule=" + filterRule + ", priority=" + priority + + ", username=" + username + ", enabled=" + enabled + "]"; + } + + public URL toUrl() { + String group = null; + String version = null; + String path = service; + int i = path.indexOf("/"); + if (i > 0) { + group = path.substring(0, i); + path = path.substring(i + 1); + } + i = path.lastIndexOf(":"); + if (i > 0) { + version = path.substring(i + 1); + path = path.substring(0, i); + } + return URL.valueOf(Constants.ROUTE_PROTOCOL + "://" + Constants.ANYHOST_VALUE + "/" + path + + "?" + Constants.CATEGORY_KEY + "=" + Constants.ROUTERS_CATEGORY + + "&router=condition&runtime=false&enabled=" + isEnabled() + "&priority=" + getPriority() + "&force=" + isForce() + "&dynamic=false" + + "&name=" + getName() + "&" + Constants.RULE_KEY + "=" + URL.encode(getMatchRule() + " => " + getFilterRule()) + + (group == null ? "" : "&" + Constants.GROUP_KEY + "=" + group) + + (version == null ? "" : "&" + Constants.VERSION_KEY + "=" + version)); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/SearchHistory.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/SearchHistory.java new file mode 100644 index 0000000..32c405b --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/SearchHistory.java @@ -0,0 +1,60 @@ +/* + * 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 com.alibaba.dubboadmin.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; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Test.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Test.java new file mode 100644 index 0000000..e4a1530 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Test.java @@ -0,0 +1,114 @@ +/* + * 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 com.alibaba.dubboadmin.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; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/User.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/User.java new file mode 100644 index 0000000..e9826d3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/User.java @@ -0,0 +1,259 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +import java.util.Arrays; +import java.util.List; + +import com.alibaba.dubboadmin.registry.common.route.ParseUtils; + +/** + * User + * + */ +public class User extends Entity { + + public static final String REALM = "dubbo"; + public static final String ROOT = "R"; + public static final String ADMINISTRATOR = "A"; + public static final String MANAGER = "M"; + public static final String GUEST = "G"; + public static final String ANONYMOUS = "anonymous"; + public static final String LEGACY = "legacy"; + private static final long serialVersionUID = 7330539198581235339L; + private String username; + + private String password; + + private String role; + + private String creator; + + private boolean enabled; + + private String name; + + private String department; + + private String email; + + private String phone; + + private String alitalk; + + private String locale; + + private String servicePrivilege; + + private List servicePrivileges; + + public User() { + } + + public User(Long id) { + super(id); + } + + public static boolean isValidPrivilege(String servicePrivilege) { + if (servicePrivilege == null || servicePrivilege.length() == 0) { + return true; + } + String[] privileges = servicePrivilege.trim().split("\\s*,\\s*"); + for (String privilege : privileges) { + if (privilege.endsWith("*")) { + privilege = privilege.substring(0, privilege.length() - 1); + } + if (privilege.indexOf('*') > -1) { + return false; + } + } + return true; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean hasServicePrivilege(String[] services) { + if (services == null || services.length == 0) + throw new IllegalArgumentException("services == null"); + for (String service : services) { + boolean r = hasServicePrivilege(service); + if (!r) + return false; + } + return true; + } + + public boolean canGrantPrivilege(String servicePrivilege) { + if (servicePrivilege == null || servicePrivilege.length() == 0) { + return true; + } + if (servicePrivileges == null || servicePrivileges.size() == 0) { + return false; + } + String[] privileges = servicePrivilege.trim().split("\\s*,\\s*"); + for (String privilege : privileges) { + boolean hasPrivilege = false; + for (String ownPrivilege : servicePrivileges) { + if (matchPrivilege(ownPrivilege, privilege)) { + hasPrivilege = true; + } + } + if (!hasPrivilege) { + return false; + } + } + return true; + } + + private boolean matchPrivilege(String ownPrivilege, String privilege) { + if ("*".equals(ownPrivilege) || ownPrivilege.equals(privilege)) { + return true; + } + if (privilege.endsWith("*")) { + if (!ownPrivilege.endsWith("*")) { + return false; + } + privilege = privilege.substring(0, privilege.length() - 1); + ownPrivilege = ownPrivilege.substring(0, ownPrivilege.length() - 1); + return privilege.startsWith(ownPrivilege); + } else { + if (ownPrivilege.endsWith("*")) { + ownPrivilege = ownPrivilege.substring(0, ownPrivilege.length() - 1); + } + return privilege.startsWith(ownPrivilege); + } + } + + public boolean hasServicePrivilege(String service) { + if (service == null || service.length() == 0) + return false; + if (role == null || GUEST.equalsIgnoreCase(role)) { + return false; + } + if (ROOT.equalsIgnoreCase(role)) { + return true; + } + + if (servicePrivileges != null && servicePrivileges.size() > 0) { + for (String privilege : servicePrivileges) { + boolean ok = ParseUtils.isMatchGlobPattern(privilege, service); + if (ok) { + return true; + } + } + } + return false; + } + + public String getServicePrivilege() { + return servicePrivilege; + } + + public void setServicePrivilege(String servicePrivilege) { + this.servicePrivilege = servicePrivilege; + if (servicePrivilege != null && servicePrivilege.length() > 0) { + servicePrivileges = Arrays.asList(servicePrivilege.trim().split("\\s*,\\s*")); + } + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getAlitalk() { + return alitalk; + } + + public void setAlitalk(String alitalk) { + this.alitalk = alitalk; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Weight.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Weight.java new file mode 100644 index 0000000..2f3f0da --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/domain/Weight.java @@ -0,0 +1,71 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.domain; + +public class Weight extends Entity { + + //default weight value + public static final int DEFAULT_WEIGHT = 5; + private static final long serialVersionUID = -1281982267153430266L; + private String address; /* User-configured provider address expression */ + + private String serviceName; + + private int weight; /* weight value */ + + private String username; + + public Weight() { + } + + public Weight(Long id) { + super(id); + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getService() { + return serviceName; + } + + public void setService(String serviceName) { + this.serviceName = serviceName; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/registry/ConvertUtil.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/registry/ConvertUtil.java new file mode 100644 index 0000000..b3b1508 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/registry/ConvertUtil.java @@ -0,0 +1,117 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.registry; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.utils.StringUtils; + +public class ConvertUtil { + private ConvertUtil() { + } + + public static Map> convertRegister(Map> register) { + Map> newRegister = new HashMap>(); + for (Map.Entry> entry : register.entrySet()) { + String serviceName = entry.getKey(); + Map serviceUrls = entry.getValue(); + if (!serviceName.contains(":") && !serviceName.contains("/")) { + for (Map.Entry entry2 : serviceUrls.entrySet()) { + String serviceUrl = entry2.getKey(); + String serviceQuery = entry2.getValue(); + Map 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 newUrls = newRegister.get(name); + if (newUrls == null) { + newUrls = new HashMap(); + newRegister.put(name, newUrls); + } + newUrls.put(serviceUrl, StringUtils.toQueryString(params)); + } + } else { + newRegister.put(serviceName, serviceUrls); + } + } + return newRegister; + } + + public static Map convertSubscribe(Map subscribe) { + Map newSubscribe = new HashMap(); + for (Map.Entry entry : subscribe.entrySet()) { + String serviceName = entry.getKey(); + String serviceQuery = entry.getValue(); + if (!serviceName.contains(":") && !serviceName.contains("/")) { + Map 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 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 ret = new HashMap(); + 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; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/OverrideUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/OverrideUtils.java new file mode 100644 index 0000000..6de10ee --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/OverrideUtils.java @@ -0,0 +1,119 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.route; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Provider; + +public class OverrideUtils { + + public static final Comparator OVERRIDE_COMPARATOR = new Comparator() { + 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 overrides) { + if (consumer == null || overrides == null) { + return; + } + List result = new ArrayList(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 overrides) { + if (provider == null || overrides == null) { + return; + } + List result = new ArrayList(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); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/ParseUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/ParseUtils.java new file mode 100644 index 0000000..396b4e7 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/ParseUtils.java @@ -0,0 +1,335 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.route; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.alibaba.dubbo.common.utils.StringUtils; + +/** + * String parsing tools related to interpolation, including Glob mode, Query string, Service URL processing. + * + */ +public class ParseUtils { + + private static final ConcurrentMap + REPLACE_PARAMETER_PATTERNS = new ConcurrentHashMap(); + public static String METHOD_SPLIT = ","; + private static Pattern VARIABLE_PATTERN = Pattern.compile( + "\\$\\s*\\{?\\s*([\\._0-9a-zA-Z]+)\\s*\\}?"); + private static Pattern QUERY_PATTERN = Pattern + .compile("([&=]?)\\s*([^&=\\s]+)"); + + private ParseUtils() { + } + + /** + * Execute interpolation (variable insertion). + * + * @param expression Expression string containing variables. Variable names in expressions can also be enclosed in {} 。 + * @param params Variable set. Variable names can include . , _ characters. + * @return After the completion of the interpolation string. Such as:
 xxx $ {name} zzz -> xxxjerryzzz   (where the variable name = "jerry")
+     * @throws IllegalStateException The variables used in the expression string are not in the variable set
+     */
+    // FIXME Is it reasonable to throw an IllegalStateException??
+    public static String interpolate(String expression, Map params) {
+        if (expression == null || expression.length() == 0) {
+            throw new IllegalArgumentException("glob pattern is empty!");
+        }
+        if (expression.indexOf('$') < 0) {
+            return expression;
+        }
+        Matcher matcher = VARIABLE_PATTERN.matcher(expression);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) { // match one by one
+            String key = matcher.group(1);
+            String value = params == null ? null : params.get(key);
+            if (value == null) {
+                value = "";
+            }
+            matcher.appendReplacement(sb, value);
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+    public static List interpolate(List expressions, Map params) {
+        List ret = new ArrayList();
+
+        if (null == expressions || expressions.isEmpty()) {
+            return ret;
+        }
+
+        for (String expr : expressions) {
+            ret.add(interpolate(expr, params));
+        }
+
+        return ret;
+    }
+
+    /**
+     * Match Glob mode. The current implementation only supports * and supports only one. Does not support ?.
+     * @return For code or value of  null , return  false  directly.
+     */
+    public static boolean isMatchGlobPattern(String pattern, String value) {
+        if ("*".equals(pattern))
+            return true;
+        if ((pattern == null || pattern.length() == 0)
+                && (value == null || value.length() == 0))
+            return true;
+        if ((pattern == null || pattern.length() == 0)
+                || (value == null || value.length() == 0))
+            return false;
+
+        int i = pattern.lastIndexOf('*');
+        // No asterisk found
+        if (i == -1) {
+            return value.equals(pattern);
+        }
+        // Asterisk at the end
+        else if (i == pattern.length() - 1) {
+            return value.startsWith(pattern.substring(0, i));
+        }
+        // Asterisk at the beginning
+        else if (i == 0) {
+            return value.endsWith(pattern.substring(i + 1));
+        }
+        // Asterisk in the middle of the string
+        else {
+            String prefix = pattern.substring(0, i);
+            String suffix = pattern.substring(i + 1);
+            return value.startsWith(prefix) && value.endsWith(suffix);
+        }
+    }
+
+    /**
+     * Whether to match Glob mode. Glob mode is the expression to be interpolated. Glob pattern has more than one, as long as matching a pattern, that match is successful.
+     *
+     * @param patternsNeedInterpolate Multiple Glob patterns to interpolate
+         * @param interpolateParams Set of variables used for interpolation
+         * @param value Glob mode value
+     */
+    public static boolean isMatchGlobPatternsNeedInterpolate(
+        Collection patternsNeedInterpolate,
+        Map interpolateParams, String value) {
+        if (patternsNeedInterpolate != null && !patternsNeedInterpolate.isEmpty()) {
+            for (String patternNeedItp : patternsNeedInterpolate) {
+                if (StringUtils.isEmpty(patternNeedItp)) {
+                    continue;
+                }
+                // FIXME ERROR!! The original implementation, here and only the first non-blank pattern comparison, return the corresponding result!
+                // FIXME ERROR!! Should be confirmed with Liang Fei!!
+                String pattern = interpolate(patternNeedItp, interpolateParams);
+                if (isMatchGlobPattern(pattern, value)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the entries in the collection that match the Glob pattern.
+     */
+    public static Set filterByGlobPattern(String pattern, Collection values) {
+        Set ret = new HashSet();
+        if (pattern == null || values == null) {
+            return ret;
+        }
+
+        for (String v : values) {
+            if (isMatchGlobPattern(pattern, v)) {
+                ret.add(v);
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Find the string that matches the Glob pattern. Multiple patterns, as long as a match pattern, it returns this string.
+     */
+    public static Set filterByGlobPattern(Collection patterns, Collection values) {
+        Set ret = new HashSet();
+        if (null == patterns || values == null || patterns.isEmpty() || values.isEmpty()) {
+            return ret;
+        }
+
+        for (String p : patterns) {
+            for (String v : values) {
+                if (isMatchGlobPattern(p, v)) {
+                    ret.add(v);
+                }
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Whether two Glob patterns have intersection.
+     */
+    public static boolean hasIntersection(String glob1, String glob2) {
+        if (null == glob1 || null == glob2) {
+            return false;
+        }
+
+        if (glob1.contains("*") && glob2.contains("*")) {
+            int index1 = glob1.indexOf("*");
+            int index2 = glob2.indexOf("*");
+
+            String s11 = glob1.substring(0, index1);
+            String s12 = glob1.substring(index1 + 1, glob1.length());
+
+            String s21 = glob2.substring(0, index2);
+            String s22 = glob2.substring(index2 + 1, glob2.length());
+
+            if (!s11.startsWith(s21) && !s21.startsWith(s11)) return false;
+            if (!s12.endsWith(s22) && !s22.endsWith(s12)) return false;
+            return true;
+        } else if (glob1.contains("*")) {
+            return isMatchGlobPattern(glob1, glob2);
+        } else if (glob2.contains("*")) {
+            return isMatchGlobPattern(glob2, glob1);
+        } else {
+            return glob1.equals(glob2);
+        }
+    }
+
+    /**
+     * Parse Query String into Map. For strings that have only Key, key3 =  is ignored.
+     *
+     * @param keyPrefix In the output of the Map Key plus a unified prefix.
+     * @param query Query String,For example: key1=value1&key2=value2
+     * @return When Query String is key1=value1&key2=value2, and prefix is pre.,
+     *         then Map{pre.key1=value1, pre.key=value2} will be returned.
+     */
+    // FIXME Is it reasonable to throw an IllegalStateException??
+    public static Map parseQuery(String keyPrefix, String query) {
+        if (query == null)
+            return new HashMap();
+        if (keyPrefix == null)
+            keyPrefix = "";
+
+        Matcher matcher = QUERY_PATTERN.matcher(query);
+        Map routeQuery = new HashMap();
+        String key = null;
+        while (matcher.find()) { // Match one by one
+            String separator = matcher.group(1);
+            String content = matcher.group(2);
+            if (separator == null || separator.length() == 0
+                    || "&".equals(separator)) {
+                if (key != null)
+                    throw new IllegalStateException("Illegal query string \""
+                            + query + "\", The error char '" + separator
+                            + "' at index " + matcher.start() + " before \""
+                            + content + "\".");
+                key = content;
+            } else if ("=".equals(separator)) {
+                if (key == null)
+                    throw new IllegalStateException("Illegal query string \""
+                            + query + "\", The error char '" + separator
+                            + "' at index " + matcher.start() + " before \""
+                            + content + "\".");
+                routeQuery.put(keyPrefix + key, content);
+                key = null;
+            } else {
+                if (key == null)
+                    throw new IllegalStateException("Illegal query string \""
+                            + query + "\", The error char '" + separator
+                            + "' at index " + matcher.start() + " before \""
+                            + content + "\".");
+            }
+        }
+        /*if (key != null)
+        throw new IllegalStateException("Illegal route rule \"" + query
+                + "\", The error in the end char: " + key);*/
+        return routeQuery;
+    }
+
+    public static Map parseQuery(String query) {
+        return parseQuery("", query);
+    }
+
+    /**
+     * Replace the value of the url parameter.
+     */
+    public static String replaceParameter(String query, String key, String value) {
+        if (query == null || query.length() == 0) {
+            return key + "=" + value;
+        }
+        if (query.indexOf(key + "=") == -1) {
+            return query + "&" + key + "=" + value;
+        }
+        Pattern pattern = REPLACE_PARAMETER_PATTERNS.get(key);
+        if (pattern == null) {
+            pattern = Pattern.compile(key.replaceAll("([^(_0-9A-Za-z)])", "\\\\$0") + "=[^&]+");
+        }
+        Matcher matcher = pattern.matcher(query);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, (key + "=" + value).replace("$", "\\$"));
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+    public static String appendParamToUri(String uri, String name, String value) {
+        if (StringUtils.isEmpty(name) || StringUtils.isEmpty(value)) return uri;
+        if (uri.indexOf('?') != -1) {
+            uri += "&" + name + "=" + value;
+        } else {
+            uri += "?" + name + "=" + value;
+        }
+        return uri;
+    }
+
+    public static String appendParamsToUri(String uri, Map params) {
+        StringBuilder buf = new StringBuilder(uri);
+        boolean first = (uri.indexOf('?') < 0);
+        for (Map.Entry entry : params.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value))
+                continue;
+            if (first) {
+                buf.append("?");
+                first = false;
+            } else {
+                buf.append("&");
+            }
+            buf.append(key);
+            buf.append("=");
+            buf.append(value);
+        }
+        return buf.toString();
+    }
+
+    public static boolean matchEndStarPattern(String value, String pattern) {
+        if (!pattern.endsWith("*")) throw new IllegalArgumentException("not end star pattern!");
+        String perfix = pattern.substring(0, pattern.length() - 1);
+        return value.startsWith(perfix);
+    }
+}
diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteRule.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteRule.java
new file mode 100644
index 0000000..4e6ce27
--- /dev/null
+++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteRule.java
@@ -0,0 +1,567 @@
+/*
+ * 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 com.alibaba.dubboadmin.registry.common.route;
+
+import java.text.ParseException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.alibaba.dubbo.common.utils.StringUtils;
+import com.alibaba.dubboadmin.registry.common.domain.Route;
+
+/**
+ * Router rule can be divided into two parts, When Condition and Then Condition 
+ * When/Then Confition is expressed in a style of (KV) pair, the V part of the condition pair can contain multiple values (a list)
+ * The meaning of Rule: If a request matches When Condition, then use Then Condition to filter providers (only providers match Then Condition will be returned).
+ * The process of using Conditions to match consumers and providers is called `Filter`. + * When Condition are used to filter ConsumersController, while Then Condition are used to filter ProvidersController. + * RouteRule performs like this: If a Consumer matches When Condition, then only return the ProvidersController matches Then Condition. This means RouteRule should be applied to current Consumer and the providers returned are filtered by RouteRule.
+ * + * An example of Route Rule: + * key1 = value11,value12 & key2 = value21 & key2 != value22 => key3 = value3 & key4 = value41,vlaue42 & key5 !=value51 + * 。 + * The part before => is called When Condition, it's a KV pair; the follower part is Then Condition, also a KV pair. V part in KV can have more than one value, separated by ','

+ * + * Value object, thread safe. + * + */ +public class RouteRule { + @SuppressWarnings("unchecked") + static RouteRule EMPTY = new RouteRule(Collections.EMPTY_MAP, Collections.EMPTY_MAP); + private static Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)"); + private static Pattern CONDITION_SEPERATOR = Pattern.compile("(.*)=>(.*)"); + private static Pattern VALUE_LIST_SEPARATOR = Pattern.compile("\\s*,\\s*"); + final Map whenCondition; + final Map thenCondition; + private volatile String tostring = null; + + // FIXME + private RouteRule(Map when, Map then) { + for (Map.Entry entry : when.entrySet()) { + entry.getValue().freeze(); + } + for (Map.Entry entry : then.entrySet()) { + entry.getValue().freeze(); + } + + // NOTE: Both When Condition and Then Condition can be null + this.whenCondition = when; + this.thenCondition = then; + } + + public static Map parseRule(String rule) + throws ParseException { + Map condition = new HashMap(); + if (StringUtils.isBlank(rule)) { + return condition; + } + // K-V pair, contains matches part and mismatches part + MatchPair pair = null; + // V part has multiple values + Set values = null; + final Matcher matcher = ROUTE_PATTERN.matcher(rule); + while (matcher.find()) { // match one by one + String separator = matcher.group(1); + String content = matcher.group(2); + // The expression starts + if (separator == null || separator.length() == 0) { + pair = new MatchPair(); + condition.put(content, pair); + } + // The KV starts + else if ("&".equals(separator)) { + if (condition.get(content) == null) { + pair = new MatchPair(); + condition.put(content, pair); + } else { + condition.put(content, pair); + } + + } + // The Value part of KV starts + else if ("=".equals(separator)) { + if (pair == null) + throw new ParseException("Illegal route rule \"" + + rule + "\", The error char '" + separator + + "' at index " + matcher.start() + " before \"" + + content + "\".", matcher.start()); + + values = pair.matches; + values.add(content); + } + // The Value part of KV starts + else if ("!=".equals(separator)) { + if (pair == null) + throw new ParseException("Illegal route rule \"" + + rule + "\", The error char '" + separator + + "' at index " + matcher.start() + " before \"" + + content + "\".", matcher.start()); + + values = pair.unmatches; + values.add(content); + } + // The Value part of KV has multiple values, separated by ',' + else if (",".equals(separator)) { // separated by ',' + if (values == null || values.size() == 0) + throw new ParseException("Illegal route rule \"" + + rule + "\", The error char '" + separator + + "' at index " + matcher.start() + " before \"" + + content + "\".", matcher.start()); + values.add(content); + } else { + throw new ParseException("Illegal route rule \"" + rule + + "\", The error char '" + separator + "' at index " + + matcher.start() + " before \"" + content + "\".", matcher.start()); + } + } + return condition; + } + + /** + * Parse the RouteRule as a string into an object. + * + * @throws ParseException RouteRule string format is wrong. The following input conditions, RouteRule are illegal. + *
  • input is null。 + *
  • input is "" or " "。 + *
  • input Rule doesn't have a When Condition + *
  • input Rule doesn't have a Then Condition + *
+ */ + public static RouteRule parse(Route route) throws ParseException { + if (route == null) + throw new ParseException("null route!", 0); + + if (route.getMatchRule() == null && route.getFilterRule() == null) { + return parse(route.getRule()); + } + + return parse(route == null ? null : route.getMatchRule(), route == null ? null : route.getFilterRule()); + } + + public static RouteRule parse(String whenRule, String thenRule) throws ParseException { + /*if (whenRule == null || whenRule.trim().length() == 0) { + throw new ParseException("Illegal route rule without when express", 0); + }*/ + if (thenRule == null || thenRule.trim().length() == 0) { + throw new ParseException("Illegal route rule without then express", 0); + } + Map when = parseRule(whenRule.trim()); + Map then = parseRule(thenRule.trim()); + return new RouteRule(when, then); + } + + public static RouteRule parse(String rule) throws ParseException { + if (StringUtils.isBlank(rule)) { + throw new ParseException("Illegal blank route rule", 0); + } + + final Matcher matcher = CONDITION_SEPERATOR.matcher(rule); + if (!matcher.matches()) throw new ParseException("condition seperator => not found!", 0); + + return parse(matcher.group(1), matcher.group(2)); + } + + /** + * @see #parse(String) + * @throws RuntimeException This is an wrapper exception for the {@link ParseException} thrown by the {@link #parse (String)} method. + */ + public static RouteRule parseQuitely(Route route) { + try { + return parse(route); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + static Map parseNameAndValueListString2Condition(Map params, Map notParams) { + Map condition = new HashMap(); + + for (Entry entry : params.entrySet()) { + String valueListString = entry.getValue(); + if (StringUtils.isBlank(valueListString)) { + continue; + } + String[] list = VALUE_LIST_SEPARATOR.split(valueListString); + Set set = new HashSet(); + for (String item : list) { + if (StringUtils.isBlank(item)) { + continue; + } + set.add(item.trim()); + } + if (set.isEmpty()) { + continue; + } + + String key = entry.getKey(); + MatchPair matchPair = condition.get(key); + if (null == matchPair) { + matchPair = new MatchPair(); + condition.put(key, matchPair); + } + + matchPair.matches = set; + } + for (Entry entry : notParams.entrySet()) { + String valueListString = entry.getValue(); + if (StringUtils.isBlank(valueListString)) { + continue; + } + String[] list = VALUE_LIST_SEPARATOR.split(valueListString); + Set set = new HashSet(); + for (String item : list) { + if (StringUtils.isBlank(item)) { + continue; + } + set.add(item.trim()); + } + if (set.isEmpty()) { + continue; + } + + String key = entry.getKey(); + MatchPair matchPair = condition.get(key); + if (null == matchPair) { + matchPair = new MatchPair(); + condition.put(key, matchPair); + } + + matchPair.unmatches = set; + } + + return condition; + } + + public static RouteRule createFromNameAndValueListString(Map whenParams, Map notWhenParams, + Map thenParams, Map notThenParams) { + Map when = parseNameAndValueListString2Condition(whenParams, notWhenParams); + Map then = parseNameAndValueListString2Condition(thenParams, notThenParams); + + return new RouteRule(when, then); + } + + public static RouteRule createFromCondition(Map whenCondition, Map thenCondition) { + return new RouteRule(whenCondition, thenCondition); + } + + public static RouteRule copyWithRemove(RouteRule copy, Set whenParams, Set thenParams) { + Map when = new HashMap(); + for (Entry entry : copy.getWhenCondition().entrySet()) { + if (whenParams == null || !whenParams.contains(entry.getKey())) { + when.put(entry.getKey(), entry.getValue()); + } + } + + Map then = new HashMap(); + for (Entry entry : copy.getThenCondition().entrySet()) { + if (thenParams == null || !thenParams.contains(entry.getKey())) { + then.put(entry.getKey(), entry.getValue()); + } + } + + return new RouteRule(when, then); + } + + /** + * Replace with the new condition value. + * + * @param copy Replace Base + * @param whenCondition WhenCondition to replace, if Base does not have an item, insert it directly. + * @param thenCondition ThenCondition to replace, if Base has no items, then insert directly. + * @return RouteRule after replacement + */ + public static RouteRule copyWithReplace(RouteRule copy, Map whenCondition, Map thenCondition) { + if (null == copy) { + throw new NullPointerException("Argument copy is null!"); + } + + Map when = new HashMap(); + when.putAll(copy.getWhenCondition()); + if (whenCondition != null) { + when.putAll(whenCondition); + } + + Map then = new HashMap(); + then.putAll(copy.getThenCondition()); + if (thenCondition != null) { + then.putAll(thenCondition); + } + + return new RouteRule(when, then); + } + + // TODO ToString out of the current list is out of order, should we sort? + static void join(StringBuilder sb, Set valueSet) { + boolean isFirst = true; + for (String s : valueSet) { + if (isFirst) { + isFirst = false; + } else { + sb.append(","); + } + + sb.append(s); + } + } + + /** + * Whether the sample passed the conditions. + *

+ * If there is a Key in the KV for the sample, there is a corresponding MatchPair, and Value does not pass through MatchPair; {@code false} is returned; otherwise, {@code true} is returned. + * + * @see MatchPair#pass(String) + */ + public static boolean matchCondition(Map sample, + Map condition) { + for (Map.Entry entry : sample.entrySet()) { + String key = entry.getKey(); + + MatchPair pair = condition.get(key); + if (pair != null && !pair.pass(entry.getValue())) { + return false; + } + } + return true; + } + + + // FIXME Remove such method calls + public static String join(Set valueSet) { + StringBuilder sb = new StringBuilder(128); + join(sb, valueSet); + return sb.toString(); + } + + // TODO At present, the multiple Key of Condition is in disorder. Should we sort it? + public static void contidionToString(StringBuilder sb, Map condition) { + boolean isFirst = true; + for (Entry entry : condition.entrySet()) { + String keyName = entry.getKey(); + MatchPair p = entry.getValue(); + + @SuppressWarnings("unchecked") + Set[] setArray = new Set[]{p.matches, p.unmatches}; + String[] opArray = {" = ", " != "}; + + for (int i = 0; i < setArray.length; ++i) { + if (setArray[i].isEmpty()) { + continue; + } + if (isFirst) { + isFirst = false; + } else { + sb.append(" & "); + } + + sb.append(keyName); + sb.append(opArray[i]); + join(sb, setArray[i]); + } + } + } + + public boolean isWhenContainValue(String key, String value) { + MatchPair matchPair = whenCondition.get(key); + if (null == matchPair) { + return false; + } + + return matchPair.containeValue(value); + } + + public boolean isThenContainValue(String key, String value) { + MatchPair matchPair = thenCondition.get(key); + if (null == matchPair) { + return false; + } + + return matchPair.containeValue(value); + } + + public boolean isContainValue(String key, String value) { + return isWhenContainValue(key, value) || isThenContainValue(key, value); + } + + public Map getWhenCondition() { + return whenCondition; + } + + public Map getThenCondition() { + return thenCondition; + } + + public String getWhenConditionString() { + StringBuilder sb = new StringBuilder(512); + contidionToString(sb, whenCondition); + return sb.toString(); + } + + public String getThenConditionString() { + StringBuilder sb = new StringBuilder(512); + contidionToString(sb, thenCondition); + return sb.toString(); + } + + @Override + public String toString() { + if (tostring != null) + return tostring; + StringBuilder sb = new StringBuilder(512); + contidionToString(sb, whenCondition); + sb.append(" => "); + contidionToString(sb, thenCondition); + return tostring = sb.toString(); + } + + // Automatic generation with Eclipse + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((thenCondition == null) ? 0 : thenCondition.hashCode()); + result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode()); + return result; + } + + // Automatic generation with Eclipse + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RouteRule other = (RouteRule) obj; + if (thenCondition == null) { + if (other.thenCondition != null) + return false; + } else if (!thenCondition.equals(other.thenCondition)) + return false; + if (whenCondition == null) { + if (other.whenCondition != null) + return false; + } else if (!whenCondition.equals(other.whenCondition)) + return false; + return true; + } + + public static class MatchPair { + Set matches = new HashSet(); + Set unmatches = new HashSet(); + private volatile boolean freezed = false; + + public MatchPair() { + } + + public MatchPair(Set matches, Set unmatches) { + if (matches == null || unmatches == null) { + throw new IllegalArgumentException("argument of MatchPair is null!"); + } + + this.matches = matches; + this.unmatches = unmatches; + } + + public Set getMatches() { + return matches; + } + + public Set getUnmatches() { + return unmatches; + } + + public MatchPair copy() { + MatchPair ret = new MatchPair(); + ret.matches.addAll(matches); + ret.unmatches.addAll(unmatches); + return ret; + } + + void freeze() { + if (freezed) return; + synchronized (this) { + if (freezed) return; + matches = Collections.unmodifiableSet(matches); + unmatches = Collections.unmodifiableSet(unmatches); + } + } + + public boolean containeValue(String value) { + return matches.contains(value) || unmatches.contains(value); + } + + /** + * Whether a given value is matched by the {@link MatchPair}. + * return {@code false}, if + *

    + *
  1. value is in unmatches + *
  2. matches is not null, but value is not in matches. + *
+ * otherwise, returntrue。 + */ + public boolean pass(String sample) { + if (unmatches.contains(sample)) return false; + if (matches.isEmpty()) return true; + return matches.contains(sample); + } + + @Override + public String toString() { + return String.format("{matches=%s,unmatches=%s}", matches.toString(), unmatches.toString()); + } + + // Automatic generation with Eclipse + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((matches == null) ? 0 : matches.hashCode()); + result = prime * result + ((unmatches == null) ? 0 : unmatches.hashCode()); + return result; + } + + // Automatic generation with Eclipse + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MatchPair other = (MatchPair) obj; + if (matches == null) { + if (other.matches != null) + return false; + } else if (!matches.equals(other.matches)) + return false; + if (unmatches == null) { + if (other.unmatches != null) + return false; + } else if (!unmatches.equals(other.unmatches)) + return false; + return true; + } + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteRuleUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteRuleUtils.java new file mode 100644 index 0000000..7d1aebd --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteRuleUtils.java @@ -0,0 +1,155 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.route; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.alibaba.dubbo.common.utils.StringUtils; + +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 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 > Map expandCondition( + Map condition, String srcKeyName, String destKeyName, + Map expandName2Set) { + if (null == condition || StringUtils.isEmpty(srcKeyName) || StringUtils.isEmpty(destKeyName)) { + return condition; + } + + RouteRule.MatchPair matchPair = condition.get(srcKeyName); + if (matchPair == null) { + return condition; + } + + Map ret = new HashMap(); + + Iterator> iterator = condition.entrySet().iterator(); + for (; iterator.hasNext(); ) { + Entry 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 matches = new HashSet(); + Set unmatches = new HashSet(); + // 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, {key1={matches={value1,value2,$var1},unmatches={Vx,Vy,$var2}}} + * @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 condition, + Map valueParams, Map kv) { + if (condition != null && condition.size() > 0) { + for (Map.Entry entry : condition.entrySet()) { + String condName = entry.getKey(); + RouteRule.MatchPair p = entry.getValue(); + String value = kv.get(condName); + Set 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 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 filterServiceByRule(List services, RouteRule rule) { + if (null == services || services.isEmpty() || rule == null) { + return new HashSet(); + } + + RouteRule.MatchPair p = rule.getWhenCondition().get("service"); + if (p == null) { + return new HashSet(); + } + + Set filter = ParseUtils.filterByGlobPattern(p.getMatches(), services); + Set set = ParseUtils.filterByGlobPattern(p.getUnmatches(), services); + filter.addAll(set); + return filter; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteUtils.java new file mode 100644 index 0000000..6774182 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/route/RouteUtils.java @@ -0,0 +1,314 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.route; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.domain.Route; + +/** + * RouteParser route rule parse tool。 + * + */ +public class RouteUtils { + + public static boolean matchRoute(String consumerAddress, String consumerQueryUrl, Route route, Map> clusters) { + RouteRule rule = RouteRule.parseQuitely(route); + Map when = RouteRuleUtils.expandCondition( + rule.getWhenCondition(), "consumer.cluster", "consumer.host", clusters); + Map 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 previewRoute(String serviceName, String consumerAddress, String queryUrl, Map serviceUrls, + Route route, Map> clusters, List routed) { + if (null == route) { + throw new IllegalArgumentException("Route is null."); + } + List routes = new ArrayList(); + routes.add(route); + return route(serviceName, consumerAddress, queryUrl, serviceUrls, routes, clusters, routed); + } + + /** + * @return Map + */ + public static List findUsedRoute(String serviceName, String consumerAddress, String consumerQueryUrl, + List routes, Map> clusters) { + List routed = new ArrayList(); + Map urls = new HashMap(); + urls.put("dubbo://" + consumerAddress + "/" + serviceName, consumerQueryUrl); + RouteUtils.route(serviceName, consumerAddress, consumerQueryUrl, urls, routes, clusters, routed); + return routed; + } + + public static List route(String serviceName, String consumerAddress, String consumerQueryUrl, List providers, + List overrides, List routes, Map> clusters, List routed) { + if (providers == null) { + return null; + } + Map urls = new HashMap(); + urls.put("consumer://" + consumerAddress + "/" + serviceName, consumerQueryUrl); // not empty dummy data + for (Provider provider : providers) { + if (com.alibaba.dubboadmin.web.pulltool.Tool.isProviderEnabled(provider, overrides)) { + urls.put(provider.getUrl(), provider.getParameters()); + } + } + urls = RouteUtils.route(serviceName, consumerAddress, consumerQueryUrl, urls, routes, clusters, routed); + List result = new ArrayList(); + 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. aplication=nasdaq&dubbo=2.0.3&methods=updateItems,validateNew&revision=1.7.0 + * @param serviceUrls providers + * @param routes all route rules + * @param clusters all clusters + * @return route result, Map + */ + // 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 route(String serviceName, String consumerAddress, String consumerQueryUrl, Map serviceUrls, + List routes, Map> clusters, List routed) { + if (serviceUrls == null || serviceUrls.size() == 0) { + return serviceUrls; + } + if (routes == null || routes.isEmpty()) { + return serviceUrls; + } + + Map rules = route2RouteRule(routes, clusters); + + final Map 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> url2ProviderSample = new HashMap>(); + for (Map.Entry 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 sample = new HashMap(); + 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> url2Methods = new HashMap>(); + + // 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 + // if method1 matches and , we should reduce the priority of . + 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 then = rule.getThenCondition(); + if (then != null) { + Map> 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 mts = url2Methods.get(url); + if (mts == null) { + mts = new HashSet(); + url2Methods.put(url, mts); + } + mts.add(method); + } + } // end of for methods + + return appendMethodsToUrls(serviceUrls, url2Methods); + } + + static Map route2RouteRule(List routes, + Map> clusters) { + Map rules = new HashMap(); + // 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 rrs = new HashMap(); + for (Map.Entry entry : rules.entrySet()) { + RouteRule rr = entry.getValue(); + + Map when = RouteRuleUtils.expandCondition( + rr.getWhenCondition(), "consumer.cluster", "consumer.host", clusters); + Map then = RouteRuleUtils.expandCondition( + rr.getThenCondition(), "provider.cluster", "provider.host", clusters); + + rrs.put(entry.getKey(), RouteRule.createFromCondition(when, then)); + } + rules = rrs; + } + return rules; + } + + static Map appendMethodsToUrls(Map serviceUrls, + Map> url2Methods) { + // Add method parameters to URL + Map results = new HashMap(); + for (Map.Entry> entry : url2Methods.entrySet()) { + String url = entry.getKey(); + String query = serviceUrls.get(url); + + Set 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 consumerSample, List routes, Map 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> getUrlsMatchedCondition(Map condition, + Map parameters, Map> url2Sample) { + Map> result = new HashMap>(); + for (Map.Entry> entry : url2Sample.entrySet()) { + Map sample = entry.getValue(); + + Map params = new HashMap(); + params.putAll(sample); + params.putAll(parameters); + + if (RouteRuleUtils.isMatchCondition(condition, params, sample)) { + result.put(entry.getKey(), entry.getValue()); + } + } + return result; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/DatabaseStatusChecker.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/DatabaseStatusChecker.java new file mode 100644 index 0000000..d02def8 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/DatabaseStatusChecker.java @@ -0,0 +1,99 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.status; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; + +import javax.sql.DataSource; + +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; + +/** + * 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"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/LoadStatusChecker.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/LoadStatusChecker.java new file mode 100644 index 0000000..cfbf5cc --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/LoadStatusChecker.java @@ -0,0 +1,45 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.status; + +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.lang.reflect.Method; + +import com.alibaba.dubbo.common.status.Status; +import com.alibaba.dubbo.common.status.StatusChecker; + +/** + * 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); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/MemoryStatusChecker.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/MemoryStatusChecker.java new file mode 100644 index 0000000..c28e35a --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/status/MemoryStatusChecker.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.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); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Coder.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Coder.java new file mode 100644 index 0000000..644a12b --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Coder.java @@ -0,0 +1,59 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.util; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import com.alibaba.dubbo.common.io.Bytes; + +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)); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Entities.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Entities.java new file mode 100644 index 0000000..8361430 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Entities.java @@ -0,0 +1,953 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.util; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +/** + *

+ * Provides HTML and XML entity utilities. + *

+ * + * @version $Id: Entities.java 181192 2012-06-21 05:05:47Z tony.chenl $ + * @see ISO Entities + * @see HTML 3.2 Character Entities for ISO Latin-1 + * @see HTML 4.0 Character entity references + * @see HTML 4.01 Character References + * @see HTML 4.01 Code positions + * @since 2.0 + */ +class Entities { + + /** + *

+ * The set of entities supported by standard XML. + *

+ */ + public static final Entities XML; + /** + *

+ * The set of entities supported by HTML 3.2. + *

+ */ + public static final Entities HTML32; + /** + *

+ * The set of entities supported by HTML 4.0. + *

+ */ + public static final Entities HTML40; + // package scoped for testing + static final String[][] ISO8859_1_ARRAY = {{"nbsp", "160"}, // non-breaking space + {"iexcl", "161"}, // inverted exclamation mark + {"cent", "162"}, // cent sign + {"pound", "163"}, // pound sign + {"curren", "164"}, // currency sign + {"yen", "165"}, // yen sign = yuan sign + {"brvbar", "166"}, // broken bar = broken vertical bar + {"sect", "167"}, // section sign + {"uml", "168"}, // diaeresis = spacing diaeresis + {"copy", "169"}, // � - copyright sign + {"ordf", "170"}, // feminine ordinal indicator + {"laquo", "171"}, // left-pointing double angle quotation mark = left pointing guillemet + {"not", "172"}, // not sign + {"shy", "173"}, // soft hyphen = discretionary hyphen + {"reg", "174"}, // � - registered trademark sign + {"macr", "175"}, // macron = spacing macron = overline = APL overbar + {"deg", "176"}, // degree sign + {"plusmn", "177"}, // plus-minus sign = plus-or-minus sign + {"sup2", "178"}, // superscript two = superscript digit two = squared + {"sup3", "179"}, // superscript three = superscript digit three = cubed + {"acute", "180"}, // acute accent = spacing acute + {"micro", "181"}, // micro sign + {"para", "182"}, // pilcrow sign = paragraph sign + {"middot", "183"}, // middle dot = Georgian comma = Greek middle dot + {"cedil", "184"}, // cedilla = spacing cedilla + {"sup1", "185"}, // superscript one = superscript digit one + {"ordm", "186"}, // masculine ordinal indicator + {"raquo", "187"}, // right-pointing double angle quotation mark = right pointing guillemet + {"frac14", "188"}, // vulgar fraction one quarter = fraction one quarter + {"frac12", "189"}, // vulgar fraction one half = fraction one half + {"frac34", "190"}, // vulgar fraction three quarters = fraction three quarters + {"iquest", "191"}, // inverted question mark = turned question mark + {"Agrave", "192"}, // � - uppercase A, grave accent + {"Aacute", "193"}, // � - uppercase A, acute accent + {"Acirc", "194"}, // � - uppercase A, circumflex accent + {"Atilde", "195"}, // � - uppercase A, tilde + {"Auml", "196"}, // � - uppercase A, umlaut + {"Aring", "197"}, // � - uppercase A, ring + {"AElig", "198"}, // � - uppercase AE + {"Ccedil", "199"}, // � - uppercase C, cedilla + {"Egrave", "200"}, // � - uppercase E, grave accent + {"Eacute", "201"}, // � - uppercase E, acute accent + {"Ecirc", "202"}, // � - uppercase E, circumflex accent + {"Euml", "203"}, // � - uppercase E, umlaut + {"Igrave", "204"}, // � - uppercase I, grave accent + {"Iacute", "205"}, // � - uppercase I, acute accent + {"Icirc", "206"}, // � - uppercase I, circumflex accent + {"Iuml", "207"}, // � - uppercase I, umlaut + {"ETH", "208"}, // � - uppercase Eth, Icelandic + {"Ntilde", "209"}, // � - uppercase N, tilde + {"Ograve", "210"}, // � - uppercase O, grave accent + {"Oacute", "211"}, // � - uppercase O, acute accent + {"Ocirc", "212"}, // � - uppercase O, circumflex accent + {"Otilde", "213"}, // � - uppercase O, tilde + {"Ouml", "214"}, // � - uppercase O, umlaut + {"times", "215"}, // multiplication sign + {"Oslash", "216"}, // � - uppercase O, slash + {"Ugrave", "217"}, // � - uppercase U, grave accent + {"Uacute", "218"}, // � - uppercase U, acute accent + {"Ucirc", "219"}, // � - uppercase U, circumflex accent + {"Uuml", "220"}, // � - uppercase U, umlaut + {"Yacute", "221"}, // � - uppercase Y, acute accent + {"THORN", "222"}, // � - uppercase THORN, Icelandic + {"szlig", "223"}, // � - lowercase sharps, German + {"agrave", "224"}, // � - lowercase a, grave accent + {"aacute", "225"}, // � - lowercase a, acute accent + {"acirc", "226"}, // � - lowercase a, circumflex accent + {"atilde", "227"}, // � - lowercase a, tilde + {"auml", "228"}, // � - lowercase a, umlaut + {"aring", "229"}, // � - lowercase a, ring + {"aelig", "230"}, // � - lowercase ae + {"ccedil", "231"}, // � - lowercase c, cedilla + {"egrave", "232"}, // � - lowercase e, grave accent + {"eacute", "233"}, // � - lowercase e, acute accent + {"ecirc", "234"}, // � - lowercase e, circumflex accent + {"euml", "235"}, // � - lowercase e, umlaut + {"igrave", "236"}, // � - lowercase i, grave accent + {"iacute", "237"}, // � - lowercase i, acute accent + {"icirc", "238"}, // � - lowercase i, circumflex accent + {"iuml", "239"}, // � - lowercase i, umlaut + {"eth", "240"}, // � - lowercase eth, Icelandic + {"ntilde", "241"}, // � - lowercase n, tilde + {"ograve", "242"}, // � - lowercase o, grave accent + {"oacute", "243"}, // � - lowercase o, acute accent + {"ocirc", "244"}, // � - lowercase o, circumflex accent + {"otilde", "245"}, // � - lowercase o, tilde + {"ouml", "246"}, // � - lowercase o, umlaut + {"divide", "247"}, // division sign + {"oslash", "248"}, // � - lowercase o, slash + {"ugrave", "249"}, // � - lowercase u, grave accent + {"uacute", "250"}, // � - lowercase u, acute accent + {"ucirc", "251"}, // � - lowercase u, circumflex accent + {"uuml", "252"}, // � - lowercase u, umlaut + {"yacute", "253"}, // � - lowercase y, acute accent + {"thorn", "254"}, // � - lowercase thorn, Icelandic + {"yuml", "255"}, // � - lowercase y, umlaut + }; + // http://www.w3.org/TR/REC-html40/sgml/entities.html + // package scoped for testing + static final String[][] HTML40_ARRAY = { + // + {"fnof", "402"}, // latin small f with hook = function= florin, U+0192 ISOtech --> + // + {"Alpha", "913"}, // greek capital letter alpha, U+0391 --> + {"Beta", "914"}, // greek capital letter beta, U+0392 --> + {"Gamma", "915"}, // greek capital letter gamma,U+0393 ISOgrk3 --> + {"Delta", "916"}, // greek capital letter delta,U+0394 ISOgrk3 --> + {"Epsilon", "917"}, // greek capital letter epsilon, U+0395 --> + {"Zeta", "918"}, // greek capital letter zeta, U+0396 --> + {"Eta", "919"}, // greek capital letter eta, U+0397 --> + {"Theta", "920"}, // greek capital letter theta,U+0398 ISOgrk3 --> + {"Iota", "921"}, // greek capital letter iota, U+0399 --> + {"Kappa", "922"}, // greek capital letter kappa, U+039A --> + {"Lambda", "923"}, // greek capital letter lambda,U+039B ISOgrk3 --> + {"Mu", "924"}, // greek capital letter mu, U+039C --> + {"Nu", "925"}, // greek capital letter nu, U+039D --> + {"Xi", "926"}, // greek capital letter xi, U+039E ISOgrk3 --> + {"Omicron", "927"}, // greek capital letter omicron, U+039F --> + {"Pi", "928"}, // greek capital letter pi, U+03A0 ISOgrk3 --> + {"Rho", "929"}, // greek capital letter rho, U+03A1 --> + // + {"Sigma", "931"}, // greek capital letter sigma,U+03A3 ISOgrk3 --> + {"Tau", "932"}, // greek capital letter tau, U+03A4 --> + {"Upsilon", "933"}, // greek capital letter upsilon,U+03A5 ISOgrk3 --> + {"Phi", "934"}, // greek capital letter phi,U+03A6 ISOgrk3 --> + {"Chi", "935"}, // greek capital letter chi, U+03A7 --> + {"Psi", "936"}, // greek capital letter psi,U+03A8 ISOgrk3 --> + {"Omega", "937"}, // greek capital letter omega,U+03A9 ISOgrk3 --> + {"alpha", "945"}, // greek small letter alpha,U+03B1 ISOgrk3 --> + {"beta", "946"}, // greek small letter beta, U+03B2 ISOgrk3 --> + {"gamma", "947"}, // greek small letter gamma,U+03B3 ISOgrk3 --> + {"delta", "948"}, // greek small letter delta,U+03B4 ISOgrk3 --> + {"epsilon", "949"}, // greek small letter epsilon,U+03B5 ISOgrk3 --> + {"zeta", "950"}, // greek small letter zeta, U+03B6 ISOgrk3 --> + {"eta", "951"}, // greek small letter eta, U+03B7 ISOgrk3 --> + {"theta", "952"}, // greek small letter theta,U+03B8 ISOgrk3 --> + {"iota", "953"}, // greek small letter iota, U+03B9 ISOgrk3 --> + {"kappa", "954"}, // greek small letter kappa,U+03BA ISOgrk3 --> + {"lambda", "955"}, // greek small letter lambda,U+03BB ISOgrk3 --> + {"mu", "956"}, // greek small letter mu, U+03BC ISOgrk3 --> + {"nu", "957"}, // greek small letter nu, U+03BD ISOgrk3 --> + {"xi", "958"}, // greek small letter xi, U+03BE ISOgrk3 --> + {"omicron", "959"}, // greek small letter omicron, U+03BF NEW --> + {"pi", "960"}, // greek small letter pi, U+03C0 ISOgrk3 --> + {"rho", "961"}, // greek small letter rho, U+03C1 ISOgrk3 --> + {"sigmaf", "962"}, // greek small letter final sigma,U+03C2 ISOgrk3 --> + {"sigma", "963"}, // greek small letter sigma,U+03C3 ISOgrk3 --> + {"tau", "964"}, // greek small letter tau, U+03C4 ISOgrk3 --> + {"upsilon", "965"}, // greek small letter upsilon,U+03C5 ISOgrk3 --> + {"phi", "966"}, // greek small letter phi, U+03C6 ISOgrk3 --> + {"chi", "967"}, // greek small letter chi, U+03C7 ISOgrk3 --> + {"psi", "968"}, // greek small letter psi, U+03C8 ISOgrk3 --> + {"omega", "969"}, // greek small letter omega,U+03C9 ISOgrk3 --> + {"thetasym", "977"}, // greek small letter theta symbol,U+03D1 NEW --> + {"upsih", "978"}, // greek upsilon with hook symbol,U+03D2 NEW --> + {"piv", "982"}, // greek pi symbol, U+03D6 ISOgrk3 --> + // + {"bull", "8226"}, // bullet = black small circle,U+2022 ISOpub --> + // + {"hellip", "8230"}, // horizontal ellipsis = three dot leader,U+2026 ISOpub --> + {"prime", "8242"}, // prime = minutes = feet, U+2032 ISOtech --> + {"Prime", "8243"}, // double prime = seconds = inches,U+2033 ISOtech --> + {"oline", "8254"}, // overline = spacing overscore,U+203E NEW --> + {"frasl", "8260"}, // fraction slash, U+2044 NEW --> + // + {"weierp", "8472"}, // script capital P = power set= Weierstrass p, U+2118 ISOamso --> + {"image", "8465"}, // blackletter capital I = imaginary part,U+2111 ISOamso --> + {"real", "8476"}, // blackletter capital R = real part symbol,U+211C ISOamso --> + {"trade", "8482"}, // trade mark sign, U+2122 ISOnum --> + {"alefsym", "8501"}, // alef symbol = first transfinite cardinal,U+2135 NEW --> + // + // + {"larr", "8592"}, // leftwards arrow, U+2190 ISOnum --> + {"uarr", "8593"}, // upwards arrow, U+2191 ISOnum--> + {"rarr", "8594"}, // rightwards arrow, U+2192 ISOnum --> + {"darr", "8595"}, // downwards arrow, U+2193 ISOnum --> + {"harr", "8596"}, // left right arrow, U+2194 ISOamsa --> + {"crarr", "8629"}, // downwards arrow with corner leftwards= carriage return, U+21B5 NEW --> + {"lArr", "8656"}, // leftwards double arrow, U+21D0 ISOtech --> + // + {"uArr", "8657"}, // upwards double arrow, U+21D1 ISOamsa --> + {"rArr", "8658"}, // rightwards double arrow,U+21D2 ISOtech --> + // + {"dArr", "8659"}, // downwards double arrow, U+21D3 ISOamsa --> + {"hArr", "8660"}, // left right double arrow,U+21D4 ISOamsa --> + // + {"forall", "8704"}, // for all, U+2200 ISOtech --> + {"part", "8706"}, // partial differential, U+2202 ISOtech --> + {"exist", "8707"}, // there exists, U+2203 ISOtech --> + {"empty", "8709"}, // empty set = null set = diameter,U+2205 ISOamso --> + {"nabla", "8711"}, // nabla = backward difference,U+2207 ISOtech --> + {"isin", "8712"}, // element of, U+2208 ISOtech --> + {"notin", "8713"}, // not an element of, U+2209 ISOtech --> + {"ni", "8715"}, // contains as member, U+220B ISOtech --> + // + {"prod", "8719"}, // n-ary product = product sign,U+220F ISOamsb --> + // + {"sum", "8721"}, // n-ary summation, U+2211 ISOamsb --> + // + {"minus", "8722"}, // minus sign, U+2212 ISOtech --> + {"lowast", "8727"}, // asterisk operator, U+2217 ISOtech --> + {"radic", "8730"}, // square root = radical sign,U+221A ISOtech --> + {"prop", "8733"}, // proportional to, U+221D ISOtech --> + {"infin", "8734"}, // infinity, U+221E ISOtech --> + {"ang", "8736"}, // angle, U+2220 ISOamso --> + {"and", "8743"}, // logical and = wedge, U+2227 ISOtech --> + {"or", "8744"}, // logical or = vee, U+2228 ISOtech --> + {"cap", "8745"}, // intersection = cap, U+2229 ISOtech --> + {"cup", "8746"}, // union = cup, U+222A ISOtech --> + {"int", "8747"}, // integral, U+222B ISOtech --> + {"there4", "8756"}, // therefore, U+2234 ISOtech --> + {"sim", "8764"}, // tilde operator = varies with = similar to,U+223C ISOtech --> + // + {"cong", "8773"}, // approximately equal to, U+2245 ISOtech --> + {"asymp", "8776"}, // almost equal to = asymptotic to,U+2248 ISOamsr --> + {"ne", "8800"}, // not equal to, U+2260 ISOtech --> + {"equiv", "8801"}, // identical to, U+2261 ISOtech --> + {"le", "8804"}, // less-than or equal to, U+2264 ISOtech --> + {"ge", "8805"}, // greater-than or equal to,U+2265 ISOtech --> + {"sub", "8834"}, // subset of, U+2282 ISOtech --> + {"sup", "8835"}, // superset of, U+2283 ISOtech --> + // + {"sube", "8838"}, // subset of or equal to, U+2286 ISOtech --> + {"supe", "8839"}, // superset of or equal to,U+2287 ISOtech --> + {"oplus", "8853"}, // circled plus = direct sum,U+2295 ISOamsb --> + {"otimes", "8855"}, // circled times = vector product,U+2297 ISOamsb --> + {"perp", "8869"}, // up tack = orthogonal to = perpendicular,U+22A5 ISOtech --> + {"sdot", "8901"}, // dot operator, U+22C5 ISOamsb --> + // + // + {"lceil", "8968"}, // left ceiling = apl upstile,U+2308 ISOamsc --> + {"rceil", "8969"}, // right ceiling, U+2309 ISOamsc --> + {"lfloor", "8970"}, // left floor = apl downstile,U+230A ISOamsc --> + {"rfloor", "8971"}, // right floor, U+230B ISOamsc --> + {"lang", "9001"}, // left-pointing angle bracket = bra,U+2329 ISOtech --> + // + {"rang", "9002"}, // right-pointing angle bracket = ket,U+232A ISOtech --> + // + // + {"loz", "9674"}, // lozenge, U+25CA ISOpub --> + // + {"spades", "9824"}, // black spade suit, U+2660 ISOpub --> + // + {"clubs", "9827"}, // black club suit = shamrock,U+2663 ISOpub --> + {"hearts", "9829"}, // black heart suit = valentine,U+2665 ISOpub --> + {"diams", "9830"}, // black diamond suit, U+2666 ISOpub --> + + // + {"OElig", "338"}, // -- latin capital ligature OE,U+0152 ISOlat2 --> + {"oelig", "339"}, // -- latin small ligature oe, U+0153 ISOlat2 --> + // + {"Scaron", "352"}, // -- latin capital letter S with caron,U+0160 ISOlat2 --> + {"scaron", "353"}, // -- latin small letter s with caron,U+0161 ISOlat2 --> + {"Yuml", "376"}, // -- latin capital letter Y with diaeresis,U+0178 ISOlat2 --> + // + {"circ", "710"}, // -- modifier letter circumflex accent,U+02C6 ISOpub --> + {"tilde", "732"}, // small tilde, U+02DC ISOdia --> + // + {"ensp", "8194"}, // en space, U+2002 ISOpub --> + {"emsp", "8195"}, // em space, U+2003 ISOpub --> + {"thinsp", "8201"}, // thin space, U+2009 ISOpub --> + {"zwnj", "8204"}, // zero width non-joiner,U+200C NEW RFC 2070 --> + {"zwj", "8205"}, // zero width joiner, U+200D NEW RFC 2070 --> + {"lrm", "8206"}, // left-to-right mark, U+200E NEW RFC 2070 --> + {"rlm", "8207"}, // right-to-left mark, U+200F NEW RFC 2070 --> + {"ndash", "8211"}, // en dash, U+2013 ISOpub --> + {"mdash", "8212"}, // em dash, U+2014 ISOpub --> + {"lsquo", "8216"}, // left single quotation mark,U+2018 ISOnum --> + {"rsquo", "8217"}, // right single quotation mark,U+2019 ISOnum --> + {"sbquo", "8218"}, // single low-9 quotation mark, U+201A NEW --> + {"ldquo", "8220"}, // left double quotation mark,U+201C ISOnum --> + {"rdquo", "8221"}, // right double quotation mark,U+201D ISOnum --> + {"bdquo", "8222"}, // double low-9 quotation mark, U+201E NEW --> + {"dagger", "8224"}, // dagger, U+2020 ISOpub --> + {"Dagger", "8225"}, // double dagger, U+2021 ISOpub --> + {"permil", "8240"}, // per mille sign, U+2030 ISOtech --> + {"lsaquo", "8249"}, // single left-pointing angle quotation mark,U+2039 ISO proposed --> + // + {"rsaquo", "8250"}, // single right-pointing angle quotation mark,U+203A ISO proposed --> + // + {"euro", "8364"}, // -- euro sign, U+20AC NEW --> + }; + private static final String[][] BASIC_ARRAY = {{"quot", "34"}, // " - double-quote + {"amp", "38"}, // & - ampersand + {"lt", "60"}, // < - less-than + {"gt", "62"}, // > - greater-than + }; + private static final String[][] APOS_ARRAY = {{"apos", "39"}, // XML apostrophe + }; + + static { + XML = new Entities(); + XML.addEntities(BASIC_ARRAY); + XML.addEntities(APOS_ARRAY); + } + + static { + HTML32 = new Entities(); + HTML32.addEntities(BASIC_ARRAY); + HTML32.addEntities(ISO8859_1_ARRAY); + } + + static { + HTML40 = new Entities(); + fillWithHtml40Entities(HTML40); + } + + // package scoped for testing + EntityMap map = new Entities.LookupEntityMap(); + + /** + *

+ * Fills the specified entities instance with HTML 40 entities. + *

+ * + * @param entities the instance to be filled. + */ + static void fillWithHtml40Entities(Entities entities) { + entities.addEntities(BASIC_ARRAY); + entities.addEntities(ISO8859_1_ARRAY); + entities.addEntities(HTML40_ARRAY); + } + + /** + *

+ * Adds entities to this entity. + *

+ * + * @param entityArray array of entities to be added + */ + public void addEntities(String[][] entityArray) { + for (int i = 0; i < entityArray.length; ++i) { + addEntity(entityArray[i][0], Integer.parseInt(entityArray[i][1])); + } + } + + /** + *

+ * Add an entity to this entity. + *

+ * + * @param name name of the entity + * @param value vale of the entity + */ + public void addEntity(String name, int value) { + map.add(name, value); + } + + /** + *

+ * Returns the name of the entity identified by the specified value. + *

+ * + * @param value the value to locate + * @return entity name associated with the specified value + */ + public String entityName(int value) { + return map.name(value); + } + + /** + *

+ * Returns the value of the entity identified by the specified name. + *

+ * + * @param name the name to locate + * @return entity value associated with the specified name + */ + public int entityValue(String name) { + return map.value(name); + } + + /** + *

+ * Escapes the characters in a String. + *

+ *

+ *

+ * For example, if you have called addEntity("foo", 0xA1), escape("\u00A1") will return + * "&foo;" + *

+ * + * @param str The String to escape. + * @return A new escaped String. + */ + public String escape(String str) { + StringWriter stringWriter = createStringWriter(str); + try { + this.escape(stringWriter, str); + } catch (IOException e) { + // This should never happen because ALL the StringWriter methods called by #escape(Writer, String) do not + // throw IOExceptions. + throw new IllegalStateException(e); + } + return stringWriter.toString(); + } + + /** + *

+ * Escapes the characters in the String passed and writes the result to the Writer + * passed. + *

+ * + * @param writer The Writer to write the results of the escaping to. Assumed to be a non-null value. + * @param str The String to escape. Assumed to be a non-null value. + * @throws IOException when Writer passed throws the exception from calls to the {@link Writer#write(int)} + * methods. + * @see #escape(String) + * @see Writer + */ + public void escape(Writer writer, String str) throws IOException { + int len = str.length(); + for (int i = 0; i < len; i++) { + char c = str.charAt(i); + String entityName = this.entityName(c); + if (entityName == null) { + if (c > 0x7F) { + writer.write("&#"); + writer.write(Integer.toString(c, 10)); + writer.write(';'); + } else { + writer.write(c); + } + } else { + writer.write('&'); + writer.write(entityName); + writer.write(';'); + } + } + } + + /** + *

+ * Unescapes the entities in a String. + *

+ *

+ *

+ * For example, if you have called addEntity("foo", 0xA1), unescape("&foo;") will return + * "\u00A1" + *

+ * + * @param str The String to escape. + * @return A new escaped String. + */ + public String unescape(String str) { + int firstAmp = str.indexOf('&'); + if (firstAmp < 0) { + return str; + } else { + StringWriter stringWriter = createStringWriter(str); + try { + this.doUnescape(stringWriter, str, firstAmp); + } catch (IOException e) { + // This should never happen because ALL the StringWriter methods called by #escape(Writer, String) + // do not throw IOExceptions. + throw new IllegalStateException(e); + } + return stringWriter.toString(); + } + } + + /** + * Make the StringWriter 10% larger than the source String to avoid growing the writer + * + * @param str The source string + * @return A newly created StringWriter + */ + private StringWriter createStringWriter(String str) { + return new StringWriter((int) (str.length() + (str.length() * 0.1))); + } + + /** + *

+ * Unescapes the escaped entities in the String passed and writes the result to the + * Writer passed. + *

+ * + * @param writer The Writer to write the results to; assumed to be non-null. + * @param str The source String to unescape; assumed to be non-null. + * @throws IOException when Writer passed throws the exception from calls to the {@link Writer#write(int)} + * methods. + * @see #escape(String) + * @see Writer + */ + public void unescape(Writer writer, String str) throws IOException { + int firstAmp = str.indexOf('&'); + if (firstAmp < 0) { + writer.write(str); + return; + } else { + doUnescape(writer, str, firstAmp); + } + } + + /** + * Underlying unescape method that allows the optimisation of not starting from the 0 index again. + * + * @param writer The Writer to write the results to; assumed to be non-null. + * @param str The source String to unescape; assumed to be non-null. + * @param firstAmp The int index of the first ampersand in the source String. + * @throws IOException when Writer passed throws the exception from calls to the {@link Writer#write(int)} + * methods. + */ + private void doUnescape(Writer writer, String str, int firstAmp) throws IOException { + writer.write(str, 0, firstAmp); + int len = str.length(); + for (int i = firstAmp; i < len; i++) { + char c = str.charAt(i); + if (c == '&') { + int nextIdx = i + 1; + int semiColonIdx = str.indexOf(';', nextIdx); + if (semiColonIdx == -1) { + writer.write(c); + continue; + } + int amphersandIdx = str.indexOf('&', i + 1); + if (amphersandIdx != -1 && amphersandIdx < semiColonIdx) { + // Then the text looks like &...&...; + writer.write(c); + continue; + } + String entityContent = str.substring(nextIdx, semiColonIdx); + int entityValue = -1; + int entityContentLen = entityContent.length(); + if (entityContentLen > 0) { + if (entityContent.charAt(0) == '#') { // escaped value content is an integer (decimal or + // hexidecimal) + if (entityContentLen > 1) { + char isHexChar = entityContent.charAt(1); + try { + switch (isHexChar) { + case 'X': + case 'x': { + entityValue = Integer.parseInt(entityContent.substring(2), 16); + break; + } + default: { + entityValue = Integer.parseInt(entityContent.substring(1), 10); + } + } + if (entityValue > 0xFFFF) { + entityValue = -1; + } + } catch (NumberFormatException e) { + entityValue = -1; + } + } + } else { // escaped value content is an entity name + entityValue = this.entityValue(entityContent); + } + } + + if (entityValue == -1) { + writer.write('&'); + writer.write(entityContent); + writer.write(';'); + } else { + writer.write(entityValue); + } + i = semiColonIdx; // move index up to the semi-colon + } else { + writer.write(c); + } + } + } + + static interface EntityMap { + /** + *

+ * Add an entry to this entity map. + *

+ * + * @param name the entity name + * @param value the entity value + */ + void add(String name, int value); + + /** + *

+ * Returns the name of the entity identified by the specified value. + *

+ * + * @param value the value to locate + * @return entity name associated with the specified value + */ + String name(int value); + + /** + *

+ * Returns the value of the entity identified by the specified name. + *

+ * + * @param name the name to locate + * @return entity value associated with the specified name + */ + int value(String name); + } + + static class PrimitiveEntityMap implements EntityMap { + private Map mapNameToValue = new HashMap(); + + private IntHashMap mapValueToName = new IntHashMap(); + + /** + * {@inheritDoc} + */ + public void add(String name, int value) { + mapNameToValue.put(name, Integer.valueOf(value)); + mapValueToName.put(value, name); + } + + /** + * {@inheritDoc} + */ + public String name(int value) { + return (String) mapValueToName.get(value); + } + + /** + * {@inheritDoc} + */ + public int value(String name) { + Object value = mapNameToValue.get(name); + if (value == null) { + return -1; + } + return ((Integer) value).intValue(); + } + } + + static abstract class MapIntMap implements Entities.EntityMap { + protected Map mapNameToValue; + + protected Map mapValueToName; + + /** + * {@inheritDoc} + */ + public void add(String name, int value) { + mapNameToValue.put(name, Integer.valueOf(value)); + mapValueToName.put(Integer.valueOf(value), name); + } + + /** + * {@inheritDoc} + */ + public String name(int value) { + return (String) mapValueToName.get(Integer.valueOf(value)); + } + + /** + * {@inheritDoc} + */ + public int value(String name) { + Object value = mapNameToValue.get(name); + if (value == null) { + return -1; + } + return ((Integer) value).intValue(); + } + } + + static class HashEntityMap extends MapIntMap { + /** + * Constructs a new instance of HashEntityMap. + */ + public HashEntityMap() { + mapNameToValue = new HashMap(); + mapValueToName = new HashMap(); + } + } + + static class TreeEntityMap extends MapIntMap { + /** + * Constructs a new instance of TreeEntityMap. + */ + public TreeEntityMap() { + mapNameToValue = new TreeMap(); + mapValueToName = new TreeMap(); + } + } + + static class LookupEntityMap extends PrimitiveEntityMap { + private String[] lookupTable; + + private int LOOKUP_TABLE_SIZE = 256; + + /** + * {@inheritDoc} + */ + public String name(int value) { + if (value < LOOKUP_TABLE_SIZE) { + return lookupTable()[value]; + } + return super.name(value); + } + + /** + *

+ * Returns the lookup table for this entity map. The lookup table is created if it has not been previously. + *

+ * + * @return the lookup table + */ + private String[] lookupTable() { + if (lookupTable == null) { + createLookupTable(); + } + return lookupTable; + } + + /** + *

+ * Creates an entity lookup table of LOOKUP_TABLE_SIZE elements, initialized with entity names. + *

+ */ + private void createLookupTable() { + lookupTable = new String[LOOKUP_TABLE_SIZE]; + for (int i = 0; i < LOOKUP_TABLE_SIZE; ++i) { + lookupTable[i] = super.name(i); + } + } + } + + static class ArrayEntityMap implements EntityMap { + protected int growBy = 100; + + protected int size = 0; + + protected String[] names; + + protected int[] values; + + /** + * Constructs a new instance of ArrayEntityMap. + */ + public ArrayEntityMap() { + names = new String[growBy]; + values = new int[growBy]; + } + + /** + * Constructs a new instance of ArrayEntityMap specifying the size by which the array should + * grow. + * + * @param growBy array will be initialized to and will grow by this amount + */ + public ArrayEntityMap(int growBy) { + this.growBy = growBy; + names = new String[growBy]; + values = new int[growBy]; + } + + /** + * {@inheritDoc} + */ + public void add(String name, int value) { + ensureCapacity(size + 1); + names[size] = name; + values[size] = value; + size++; + } + + /** + * Verifies the capacity of the entity array, adjusting the size if necessary. + * + * @param capacity size the array should be + */ + protected void ensureCapacity(int capacity) { + if (capacity > names.length) { + int newSize = Math.max(capacity, size + growBy); + String[] newNames = new String[newSize]; + System.arraycopy(names, 0, newNames, 0, size); + names = newNames; + int[] newValues = new int[newSize]; + System.arraycopy(values, 0, newValues, 0, size); + values = newValues; + } + } + + /** + * {@inheritDoc} + */ + public String name(int value) { + for (int i = 0; i < size; ++i) { + if (values[i] == value) { + return names[i]; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + public int value(String name) { + for (int i = 0; i < size; ++i) { + if (names[i].equals(name)) { + return values[i]; + } + } + return -1; + } + } + + static class BinaryEntityMap extends ArrayEntityMap { + + /** + * Constructs a new instance of BinaryEntityMap. + */ + public BinaryEntityMap() { + super(); + } + + /** + * Constructs a new instance of ArrayEntityMap specifying the size by which the underlying array + * should grow. + * + * @param growBy array will be initialized to and will grow by this amount + */ + public BinaryEntityMap(int growBy) { + super(growBy); + } + + /** + * Performs a binary search of the entity array for the specified key. This method is based on code in + * {@link java.util.Arrays}. + * + * @param key the key to be found + * @return the index of the entity array matching the specified key + */ + private int binarySearch(int key) { + int low = 0; + int high = size - 1; + + while (low <= high) { + int mid = (low + high) >>> 1; + int midVal = values[mid]; + + if (midVal < key) { + low = mid + 1; + } else if (midVal > key) { + high = mid - 1; + } else { + return mid; // key found + } + } + return -(low + 1); // key not found. + } + + /** + * {@inheritDoc} + */ + public void add(String name, int value) { + ensureCapacity(size + 1); + int insertAt = binarySearch(value); + if (insertAt > 0) { + return; // note: this means you can't insert the same value twice + } + insertAt = -(insertAt + 1); // binarySearch returns it negative and off-by-one + System.arraycopy(values, insertAt, values, insertAt + 1, size - insertAt); + values[insertAt] = value; + System.arraycopy(names, insertAt, names, insertAt + 1, size - insertAt); + names[insertAt] = name; + size++; + } + + /** + * {@inheritDoc} + */ + public String name(int value) { + int index = binarySearch(value); + if (index < 0) { + return null; + } + return names[index]; + } + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/IntHashMap.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/IntHashMap.java new file mode 100644 index 0000000..4713cb8 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/IntHashMap.java @@ -0,0 +1,357 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.util; + +/** + *

A hash map that uses primitive ints for the key rather than objects.

+ *

+ *

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.

+ * + * @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; + + /** + *

Constructs a new, empty hashtable with a default capacity and load + * factor, which is 20 and 0.75 respectively.

+ */ + public IntHashMap() { + this(20, 0.75f); + } + + /** + *

Constructs a new, empty hashtable with the specified initial capacity + * and default load factor, which is 0.75.

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

Constructs a new, empty hashtable with the specified initial + * capacity and the specified load factor.

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

Returns the number of keys in this hashtable.

+ * + * @return the number of keys in this hashtable. + */ + public int size() { + return count; + } + + /** + *

Tests if this hashtable maps no keys to values.

+ * + * @return true if this hashtable maps no keys to values; + * false otherwise. + */ + public boolean isEmpty() { + return count == 0; + } + + /** + *

Tests if some key maps into the specified value in this hashtable. + * This operation is more expensive than the containsKey + * method.

+ *

+ *

Note that this method is identical in functionality to containsValue, + * (which is part of the Map interface in the collections framework).

+ * + * @param value a value to search for. + * @return true if and only if some key maps to the + * value argument in this hashtable as + * determined by the equals method; + * false otherwise. + * @throws NullPointerException if the value is null. + * @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; + } + + /** + *

Returns true if this HashMap maps one or more keys + * to this value.

+ *

+ *

Note that this method is identical in functionality to contains + * (which predates the Map interface).

+ * + * @param value value whose presence in this HashMap is to be tested. + * @return boolean true if the value is contained + * @see java.util.Map + * @since JDK1.2 + */ + public boolean containsValue(Object value) { + return contains(value); + } + + /** + *

Tests if the specified object is a key in this hashtable.

+ * + * @param key possible key. + * @return true if and only if the specified object is a + * key in this hashtable, as determined by the equals + * method; false 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; + } + + /** + *

Returns the value to which the specified key is mapped in this map.

+ * + * @param key a key in the hashtable. + * @return the value to which the key is mapped in this hashtable; + * null 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; + } + + /** + *

Increases the capacity of and internally reorganizes this + * hashtable, in order to accommodate and access its entries more + * efficiently.

+ *

+ *

This method is called automatically when the number of keys + * in the hashtable exceeds this hashtable's capacity and load + * factor.

+ */ + 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; + } + } + } + + /** + *

Maps the specified key to the specified + * value in this hashtable. The key cannot be + * null.

+ *

+ *

The value can be retrieved by calling the get method + * with a key that is equal to the original key.

+ * + * @param key the hashtable key. + * @param value the value. + * @return the previous value of the specified key in this hashtable, + * or null if it did not have one. + * @throws NullPointerException if the key is null. + * @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; + } + + /** + *

Removes the key (and its corresponding value) from this + * hashtable.

+ *

+ *

This method does nothing if the key is not present in the + * hashtable.

+ * + * @param key the key that needs to be removed. + * @return the value to which the key had been mapped in this hashtable, + * or null 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; + } + + /** + *

Clears this hashtable so that it contains no keys.

+ */ + public synchronized void clear() { + Entry tab[] = table; + for (int index = tab.length; --index >= 0; ) { + tab[index] = null; + } + count = 0; + } + + /** + *

Innerclass that acts as a datastructure to create a new entry in the + * table.

+ */ + private static class Entry { + int hash; + int key; + Object value; + Entry next; + + /** + *

Create a new entry with the given values.

+ * + * @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; + } + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/LocaleUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/LocaleUtils.java new file mode 100644 index 0000000..58a29c1 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/LocaleUtils.java @@ -0,0 +1,38 @@ +/* + * 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 com.alibaba.dubboadmin.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(); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/MessageSource.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/MessageSource.java new file mode 100644 index 0000000..3613abb --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/MessageSource.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.registry.common.util; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; + +/** + * 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; + } + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/OverrideUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/OverrideUtils.java new file mode 100644 index 0000000..3c20cae --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/OverrideUtils.java @@ -0,0 +1,125 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.registry.common.domain.LoadBalance; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Weight; + +/** + * OverrideUtils.java + * + */ +public class OverrideUtils { + public static List overridesToWeights(List overrides) { + List weights = new ArrayList(); + if (overrides == null) { + return weights; + } + for (Override o : overrides) { + if (StringUtils.isEmpty(o.getParams())) { + continue; + } else { + Map params = StringUtils.parseQueryString(o.getParams()); + for (Map.Entry entry : params.entrySet()) { + if (entry.getKey().equals("weight")) { + Weight weight = new Weight(); + weight.setAddress(o.getAddress()); + weight.setId(o.getId()); + weight.setService(o.getService()); + weight.setWeight(Integer.valueOf(entry.getValue())); + weights.add(weight); + } + } + } + } + return weights; + } + + public static Weight overrideToWeight(Override override) { + return overridesToWeights(Arrays.asList(override)).get(0); + } + + public static Override weightToOverride(Weight weight) { + Override override = new Override(); + override.setId(weight.getId()); + override.setAddress(weight.getAddress()); + override.setEnabled(true); + override.setParams("weight=" + weight.getWeight()); + override.setService(weight.getService()); + return override; + } + + public static List overridesToLoadBalances(List overrides) { + List loadBalances = new ArrayList(); + if (overrides == null) { + return loadBalances; + } + for (Override o : overrides) { + if (StringUtils.isEmpty(o.getParams())) { + continue; + } else { + Map params = StringUtils.parseQueryString(o.getParams()); + for (Map.Entry entry : params.entrySet()) { + if (entry.getKey().endsWith("loadbalance")) { + LoadBalance loadBalance = new LoadBalance(); + String method = null; + if (entry.getKey().endsWith(".loadbalance")) { + method = entry.getKey().split(".loadbalance")[0]; + } else { + method = "*"; + } + + loadBalance.setMethod(method); + loadBalance.setId(o.getId()); + loadBalance.setService(o.getService()); + loadBalance.setStrategy(entry.getValue()); + loadBalances.add(loadBalance); + + } + } + } + } + return loadBalances; + } + + public static LoadBalance overrideToLoadBalance(Override override) { + return OverrideUtils.overridesToLoadBalances(Arrays.asList(override)).get(0); + } + + public static Override loadBalanceToOverride(LoadBalance loadBalance) { + Override override = new Override(); + override.setId(loadBalance.getId()); + override.setService(loadBalance.getService()); + override.setEnabled(true); + String method = loadBalance.getMethod(); + String strategy = loadBalance.getStrategy(); + if (StringUtils.isEmpty(method) || method.equals("*")) { + override.setParams("loadbalance=" + strategy); + } else { + override.setParams(method + ".loadbalance=" + strategy); + } + return override; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/StringEscapeUtils.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/StringEscapeUtils.java new file mode 100644 index 0000000..32419a9 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/StringEscapeUtils.java @@ -0,0 +1,661 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.util; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; + +/** + *

Escapes and unescapes Strings for + * Java, Java Script, HTML, XML, and SQL.

+ * + * @version $Id: StringEscapeUtils.java 181192 2012-06-21 05:05:47Z tony.chenl $ + * @since 2.0 + */ +public class StringEscapeUtils { + + private static final char CSV_DELIMITER = ','; + private static final char CSV_QUOTE = '"'; + private static final String CSV_QUOTE_STR = String.valueOf(CSV_QUOTE); + private static final char[] CSV_SEARCH_CHARS = new char[]{CSV_DELIMITER, CSV_QUOTE, '\r', '\n'}; + + /** + *

StringEscapeUtils instances should NOT be constructed in + * standard programming.

+ *

+ *

Instead, the class should be used as: + *

StringEscapeUtils.escapeJava("foo");

+ * + *

This constructor is public to permit tools that require a JavaBean + * instance to operate.

+ */ + public StringEscapeUtils() { + super(); + } + + // Java and JavaScript + //-------------------------------------------------------------------------- + + /** + *

Escapes the characters in a String using Java String rules.

+ *

+ *

Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)

+ *

+ *

So a tab becomes the characters '\\' and + * 't'.

+ *

+ *

The only difference between Java strings and JavaScript strings + * is that in JavaScript, a single quote must be escaped.

+ *

+ *

Example: + *

+     * input string: He didn't say, "Stop!"
+     * output string: He didn't say, \"Stop!\"
+     * 
+ *

+ * + * @param str String to escape values in, may be null + * @return String with escaped values, null if null string input + */ + public static String escapeJava(String str) { + return escapeJavaStyleString(str, false); + } + + /** + *

Escapes the characters in a String using Java String rules to + * a Writer.

+ *

+ *

A null string input has no effect.

+ * + * @param out Writer to write escaped string into + * @param str String to escape values in, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on underlying Writer + * @see #escapeJava(java.lang.String) + */ + public static void escapeJava(Writer out, String str) throws IOException { + escapeJavaStyleString(out, str, false); + } + + /** + *

Escapes the characters in a String using JavaScript String rules.

+ *

Escapes any values it finds into their JavaScript String form. + * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)

+ *

+ *

So a tab becomes the characters '\\' and + * 't'.

+ *

+ *

The only difference between Java strings and JavaScript strings + * is that in JavaScript, a single quote must be escaped.

+ *

+ *

Example: + *

+     * input string: He didn't say, "Stop!"
+     * output string: He didn\'t say, \"Stop!\"
+     * 
+ *

+ * + * @param str String to escape values in, may be null + * @return String with escaped values, null if null string input + */ + public static String escapeJavaScript(String str) { + return escapeJavaStyleString(str, true); + } + + /** + *

Escapes the characters in a String using JavaScript String rules + * to a Writer.

+ *

+ *

A null string input has no effect.

+ * + * @param out Writer to write escaped string into + * @param str String to escape values in, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on underlying Writer + * @see #escapeJavaScript(java.lang.String) + **/ + public static void escapeJavaScript(Writer out, String str) throws IOException { + escapeJavaStyleString(out, str, true); + } + + /** + *

Worker method for the {@link #escapeJavaScript(String)} method.

+ * + * @param str String to escape values in, may be null + * @param escapeSingleQuotes escapes single quotes if true + * @return the escaped string + */ + private static String escapeJavaStyleString(String str, boolean escapeSingleQuotes) { + if (str == null) { + return null; + } + try { + StringWriter writer = new StringWriter(str.length() * 2); + escapeJavaStyleString(writer, str, escapeSingleQuotes); + return writer.toString(); + } catch (IOException ioe) { + // this should never ever happen while writing to a StringWriter + ioe.printStackTrace(); + return null; + } + } + + /** + *

Worker method for the {@link #escapeJavaScript(String)} method.

+ * + * @param out write to receieve the escaped string + * @param str String to escape values in, may be null + * @param escapeSingleQuote escapes single quotes if true + * @throws IOException if an IOException occurs + */ + private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote) throws IOException { + if (out == null) { + throw new IllegalArgumentException("The Writer must not be null"); + } + if (str == null) { + return; + } + int sz; + sz = str.length(); + for (int i = 0; i < sz; i++) { + char ch = str.charAt(i); + + // handle unicode + if (ch > 0xfff) { + out.write("\\u" + hex(ch)); + } else if (ch > 0xff) { + out.write("\\u0" + hex(ch)); + } else if (ch > 0x7f) { + out.write("\\u00" + hex(ch)); + } else if (ch < 32) { + switch (ch) { + case '\b': + out.write('\\'); + out.write('b'); + break; + case '\n': + out.write('\\'); + out.write('n'); + break; + case '\t': + out.write('\\'); + out.write('t'); + break; + case '\f': + out.write('\\'); + out.write('f'); + break; + case '\r': + out.write('\\'); + out.write('r'); + break; + default: + if (ch > 0xf) { + out.write("\\u00" + hex(ch)); + } else { + out.write("\\u000" + hex(ch)); + } + break; + } + } else { + switch (ch) { + case '\'': + if (escapeSingleQuote) { + out.write('\\'); + } + out.write('\''); + break; + case '"': + out.write('\\'); + out.write('"'); + break; + case '\\': + out.write('\\'); + out.write('\\'); + break; + case '/': + out.write('\\'); + out.write('/'); + break; + default: + out.write(ch); + break; + } + } + } + } + + /** + *

Returns an upper case hexadecimal String for the given + * character.

+ * + * @param ch The character to convert. + * @return An upper case hexadecimal String + */ + private static String hex(char ch) { + return Integer.toHexString(ch).toUpperCase(); + } + + /** + *

Unescapes any Java literals found in the String. + * For example, it will turn a sequence of '\' and + * 'n' into a newline character, unless the '\' + * is preceded by another '\'.

+ * + * @param str the String to unescape, may be null + * @return a new unescaped String, null if null string input + */ + public static String unescapeJava(String str) { + if (str == null) { + return null; + } + try { + StringWriter writer = new StringWriter(str.length()); + unescapeJava(writer, str); + return writer.toString(); + } catch (IOException ioe) { + // this should never ever happen while writing to a StringWriter + ioe.printStackTrace(); + return null; + } + } + + /** + *

Unescapes any Java literals found in the String to a + * Writer.

+ *

+ *

For example, it will turn a sequence of '\' and + * 'n' into a newline character, unless the '\' + * is preceded by another '\'.

+ *

+ *

A null string input has no effect.

+ * + * @param out the Writer used to output unescaped characters + * @param str the String to unescape, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on underlying Writer + */ + public static void unescapeJava(Writer out, String str) throws IOException { + if (out == null) { + throw new IllegalArgumentException("The Writer must not be null"); + } + if (str == null) { + return; + } + int sz = str.length(); + StringBuffer unicode = new StringBuffer(4); + boolean hadSlash = false; + boolean inUnicode = false; + for (int i = 0; i < sz; i++) { + char ch = str.charAt(i); + if (inUnicode) { + // if in unicode, then we're reading unicode + // values in somehow + unicode.append(ch); + if (unicode.length() == 4) { + // unicode now contains the four hex digits + // which represents our unicode character + try { + int value = Integer.parseInt(unicode.toString(), 16); + out.write((char) value); + unicode.setLength(0); + inUnicode = false; + hadSlash = false; + } catch (NumberFormatException nfe) { + throw new RuntimeException("Unable to parse unicode value: " + unicode, nfe); + } + } + continue; + } + if (hadSlash) { + // handle an escaped value + hadSlash = false; + switch (ch) { + case '\\': + out.write('\\'); + break; + case '\'': + out.write('\''); + break; + case '\"': + out.write('"'); + break; + case 'r': + out.write('\r'); + break; + case 'f': + out.write('\f'); + break; + case 't': + out.write('\t'); + break; + case 'n': + out.write('\n'); + break; + case 'b': + out.write('\b'); + break; + case 'u': { + // uh-oh, we're in unicode country.... + inUnicode = true; + break; + } + default: + out.write(ch); + break; + } + continue; + } else if (ch == '\\') { + hadSlash = true; + continue; + } + out.write(ch); + } + if (hadSlash) { + // then we're in the weird case of a \ at the end of the + // string, let's output it anyway. + out.write('\\'); + } + } + + /** + *

Unescapes any JavaScript literals found in the String.

+ *

+ *

For example, it will turn a sequence of '\' and 'n' + * into a newline character, unless the '\' is preceded by another + * '\'.

+ * + * @param str the String to unescape, may be null + * @return A new unescaped String, null if null string input + * @see #unescapeJava(String) + */ + public static String unescapeJavaScript(String str) { + return unescapeJava(str); + } + + /** + *

Unescapes any JavaScript literals found in the String to a + * Writer.

+ *

+ *

For example, it will turn a sequence of '\' and 'n' + * into a newline character, unless the '\' is preceded by another + * '\'.

+ *

+ *

A null string input has no effect.

+ * + * @param out the Writer used to output unescaped characters + * @param str the String to unescape, may be null + * @throws IllegalArgumentException if the Writer is null + * @throws IOException if error occurs on underlying Writer + * @see #unescapeJava(Writer, String) + */ + public static void unescapeJavaScript(Writer out, String str) throws IOException { + unescapeJava(out, str); + } + + // HTML and XML + //-------------------------------------------------------------------------- + + /** + *

Escapes the characters in a String using HTML entities.

+ *

+ *

+ * For example: + *

+ *

"bread" & "butter"

+ * becomes: + *

+ * &quot;bread&quot; &amp; &quot;butter&quot;. + *

+ *

+ *

Supports all known HTML 4.0 entities, including funky accents. + * Note that the commonly used apostrophe escape character (&apos;) + * is not a legal entity and so is not supported).

+ * + * @param str the String to escape, may be null + * @return a new escaped String, null if null string input + * @see #unescapeHtml(String) + * @see ISO Entities + * @see HTML 3.2 Character Entities for ISO Latin-1 + * @see HTML 4.0 Character entity references + * @see HTML 4.01 Character References + * @see HTML 4.01 Code positions + */ + public static String escapeHtml(String str) { + if (str == null) { + return null; + } + try { + StringWriter writer = new StringWriter((int) (str.length() * 1.5)); + escapeHtml(writer, str); + return writer.toString(); + } catch (IOException e) { + //assert false; + //should be impossible + e.printStackTrace(); + return null; + } + } + + /** + *

Escapes the characters in a String using HTML entities and writes + * them to a Writer.

+ *

+ *

+ * For example: + *

+ * "bread" & "butter" + *

becomes:

+ * &quot;bread&quot; &amp; &quot;butter&quot;. + *

+ *

Supports all known HTML 4.0 entities, including funky accents. + * Note that the commonly used apostrophe escape character (&apos;) + * is not a legal entity and so is not supported).

+ * + * @param writer the writer receiving the escaped string, not null + * @param string the String to escape, may be null + * @throws IllegalArgumentException if the writer is null + * @throws IOException when Writer passed throws the exception from + * calls to the {@link Writer#write(int)} methods. + * @see #escapeHtml(String) + * @see #unescapeHtml(String) + * @see ISO Entities + * @see HTML 3.2 Character Entities for ISO Latin-1 + * @see HTML 4.0 Character entity references + * @see HTML 4.01 Character References + * @see HTML 4.01 Code positions + */ + public static void escapeHtml(Writer writer, String string) throws IOException { + if (writer == null) { + throw new IllegalArgumentException("The Writer must not be null."); + } + if (string == null) { + return; + } + Entities.HTML40.escape(writer, string); + } + + //----------------------------------------------------------------------- + + /** + *

Unescapes a string containing entity escapes to a string + * containing the actual Unicode characters corresponding to the + * escapes. Supports HTML 4.0 entities.

+ *

+ *

For example, the string "&lt;Fran&ccedil;ais&gt;" + * will become "<Français>"

+ *

+ *

If an entity is unrecognized, it is left alone, and inserted + * verbatim into the result string. e.g. "&gt;&zzzz;x" will + * become ">&zzzz;x".

+ * + * @param str the String to unescape, may be null + * @return a new unescaped String, null if null string input + * @see #escapeHtml(Writer, String) + */ + public static String unescapeHtml(String str) { + if (str == null) { + return null; + } + try { + StringWriter writer = new StringWriter((int) (str.length() * 1.5)); + unescapeHtml(writer, str); + return writer.toString(); + } catch (IOException e) { + //assert false; + //should be impossible + e.printStackTrace(); + return null; + } + } + + /** + *

Unescapes a string containing entity escapes to a string + * containing the actual Unicode characters corresponding to the + * escapes. Supports HTML 4.0 entities.

+ *

+ *

For example, the string "&lt;Fran&ccedil;ais&gt;" + * will become "<Français>"

+ *

+ *

If an entity is unrecognized, it is left alone, and inserted + * verbatim into the result string. e.g. "&gt;&zzzz;x" will + * become ">&zzzz;x".

+ * + * @param writer the writer receiving the unescaped string, not null + * @param string the String to unescape, may be null + * @throws IllegalArgumentException if the writer is null + * @throws IOException if an IOException occurs + * @see #escapeHtml(String) + */ + public static void unescapeHtml(Writer writer, String string) throws IOException { + if (writer == null) { + throw new IllegalArgumentException("The Writer must not be null."); + } + if (string == null) { + return; + } + Entities.HTML40.unescape(writer, string); + } + + //----------------------------------------------------------------------- + + /** + *

Escapes the characters in a String using XML entities.

+ *

+ *

For example: "bread" & "butter" => + * &quot;bread&quot; &amp; &quot;butter&quot;. + *

+ *

+ *

Supports only the five basic XML entities (gt, lt, quot, amp, apos). + * Does not support DTDs or external entities.

+ *

+ *

Note that unicode characters greater than 0x7f are currently escaped to + * their numerical \\u equivalent. This may change in future releases.

+ * + * @param writer the writer receiving the unescaped string, not null + * @param str the String to escape, may be null + * @throws IllegalArgumentException if the writer is null + * @throws IOException if there is a problem writing + * @see #unescapeXml(java.lang.String) + */ + public static void escapeXml(Writer writer, String str) throws IOException { + if (writer == null) { + throw new IllegalArgumentException("The Writer must not be null."); + } + if (str == null) { + return; + } + Entities.XML.escape(writer, str); + } + + /** + *

Escapes the characters in a String using XML entities.

+ *

+ *

For example: "bread" & "butter" => + * &quot;bread&quot; &amp; &quot;butter&quot;. + *

+ *

+ *

Supports only the five basic XML entities (gt, lt, quot, amp, apos). + * Does not support DTDs or external entities.

+ *

+ *

Note that unicode characters greater than 0x7f are currently escaped to + * their numerical \\u equivalent. This may change in future releases.

+ * + * @param str the String to escape, may be null + * @return a new escaped String, null if null string input + * @see #unescapeXml(java.lang.String) + */ + public static String escapeXml(String str) { + if (str == null) { + return null; + } + return Entities.XML.escape(str); + } + + //----------------------------------------------------------------------- + + /** + *

Unescapes a string containing XML entity escapes to a string + * containing the actual Unicode characters corresponding to the + * escapes.

+ *

+ *

Supports only the five basic XML entities (gt, lt, quot, amp, apos). + * Does not support DTDs or external entities.

+ *

+ *

Note that numerical \\u unicode codes are unescaped to their respective + * unicode characters. This may change in future releases.

+ * + * @param writer the writer receiving the unescaped string, not null + * @param str the String to unescape, may be null + * @throws IllegalArgumentException if the writer is null + * @throws IOException if there is a problem writing + * @see #escapeXml(String) + */ + public static void unescapeXml(Writer writer, String str) throws IOException { + if (writer == null) { + throw new IllegalArgumentException("The Writer must not be null."); + } + if (str == null) { + return; + } + Entities.XML.unescape(writer, str); + } + + /** + *

Unescapes a string containing XML entity escapes to a string + * containing the actual Unicode characters corresponding to the + * escapes.

+ *

+ *

Supports only the five basic XML entities (gt, lt, quot, amp, apos). + * Does not support DTDs or external entities.

+ *

+ *

Note that numerical \\u unicode codes are unescaped to their respective + * unicode characters. This may change in future releases.

+ * + * @param str the String to unescape, may be null + * @return a new unescaped String, null if null string input + * @see #escapeXml(String) + */ + public static String unescapeXml(String str) { + if (str == null) { + return null; + } + return Entities.XML.unescape(str); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Tool.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Tool.java new file mode 100644 index 0000000..a5d3e95 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/registry/common/util/Tool.java @@ -0,0 +1,167 @@ +/* + * 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 com.alibaba.dubboadmin.registry.common.util; + +import java.lang.reflect.Array; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.NetUtils; +import com.alibaba.dubbo.common.utils.StringUtils; + +/** + * Tool + * + */ +public class Tool { + + private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$"); + private static final Comparator SIMPLE_NAME_COMPARATOR = new Comparator() { + 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 sortSimpleName(List 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; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/BaseController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/BaseController.java new file mode 100644 index 0000000..4cab02f --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/BaseController.java @@ -0,0 +1,85 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc; + +import java.util.Map; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; +import com.alibaba.dubboadmin.governance.biz.common.i18n.MessageResourceService; +import com.alibaba.dubboadmin.governance.util.WebConstants; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.web.pulltool.RootContextPath; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.ui.Model; + +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); + } + + private String getDefaultRedirect(Map context, String operate) { + String defaultRedirect = (String) context.get("defaultRedirect"); + return defaultRedirect; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/RouterController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/RouterController.java new file mode 100644 index 0000000..adf04d3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/RouterController.java @@ -0,0 +1,344 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc; + +import java.lang.reflect.Method; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubboadmin.SpringUtil; +import com.alibaba.dubboadmin.governance.util.WebConstants; +import com.alibaba.dubboadmin.web.mvc.governance.ServicesController; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + + +@Controller +public class RouterController { + + @Autowired + ServicesController servicesController; + + private boolean isPrimitive(Class cls) { + return cls.isPrimitive() || cls == Boolean.class || cls == Byte.class + || cls == Character.class || cls == Short.class || cls == Integer.class + || cls == Long.class || cls == Float.class || cls == Double.class + || cls == String.class; + } + + private Object convertPrimitive(Class cls, String value) { + if (cls == boolean.class || cls == Boolean.class) { + return value == null || value.length() == 0 ? false : Boolean.valueOf(value); + } else if (cls == byte.class || cls == Byte.class) { + return value == null || value.length() == 0 ? 0 : Byte.valueOf(value); + } else if (cls == char.class || cls == Character.class) { + return value == null || value.length() == 0 ? '\0' : value.charAt(0); + } else if (cls == short.class || cls == Short.class) { + return value == null || value.length() == 0 ? 0 : Short.valueOf(value); + } else if (cls == int.class || cls == Integer.class) { + return value == null || value.length() == 0 ? 0 : Integer.valueOf(value); + } else if (cls == long.class || cls == Long.class) { + return value == null || value.length() == 0 ? 0 : Long.valueOf(value); + } else if (cls == float.class || cls == Float.class) { + return value == null || value.length() == 0 ? 0 : Float.valueOf(value); + } else if (cls == double.class || cls == Double.class) { + return value == null || value.length() == 0 ? 0 : Double.valueOf(value); + } + return value; + } + + //address mapping + @RequestMapping("/governance/addresses/{ip:[0-9.]+:?[0-9]+}/{type}") + public String addressRouter(@PathVariable("ip") String ip, @PathVariable("type") String type, + HttpServletRequest request, HttpServletResponse response, Model model) { + model.addAttribute("address", ip); + return appRouter(null, "addresses", ip, type, request, response, model); + } + + @RequestMapping("/governance/addresses/{ip:[0-9.]+:?[0-9]+}/{type}/{action}") + public String addresswithIDRouter(@RequestParam Map params, @PathVariable("ip") String ip, @PathVariable("type") String type, + @PathVariable("action") String action, HttpServletRequest request, + HttpServletResponse response, Model model) { + model.addAttribute("address", ip); + return appAction(params, null, "addresses",ip, type, action, request, response, model); + } + + @RequestMapping("/governance/addresses/{ip:[0-9.]+:?[0-9]+}/{type}/{id}/{action}") + public String addressWithIDandAction(@PathVariable("ip") String ip, @PathVariable("type") String type, + @PathVariable("id") String id, @PathVariable("action") String action, + HttpServletRequest request, HttpServletResponse response, Model model) { + model.addAttribute("address", ip); + return appActionWithIdandAction(null, null, type, id, action, request, response, model); + } + + + // service mapping + @RequestMapping("/governance/services/{service}/{type}") + public String servicerRouter(@PathVariable("service") String service, @PathVariable("type") String type, + HttpServletRequest request, HttpServletResponse response, Model model) { + model.addAttribute("service", service); + return appRouter(null, "services", service, type, request, response, model); + } + + @RequestMapping("/governance/services/{service}/{type}/{action}") + public String serviceAction(@RequestParam Map param, + @PathVariable("service") String service, @PathVariable("type") String type, + @PathVariable("action") String action, HttpServletRequest request, + HttpServletResponse response, Model model) { + for (Map.Entry entry : param.entrySet()) { + System.out.println("key: " + entry.getKey()); + System.out.println("value: " + entry.getValue()); + } + model.addAttribute("service", service); + return appAction(param, null, "services", service, type, action, request, response, model); + } + + @RequestMapping("/governance/services/{service}/{type}/{id}/{action}") + public String serviceActionWithId(@RequestParam Map param, + @PathVariable("service") String service, + @PathVariable("type") String type, @PathVariable("id") String id, + @PathVariable("action") String action, HttpServletRequest request, HttpServletResponse response, Model model) { + String method = request.getMethod(); + String app = null; + System.out.println("type: " + type); + System.out.println("action: " + action); + System.out.println("method: " + method); + for (Map.Entry entry : param.entrySet()) { + if (entry.getKey().equals("application")) { + app = (String)entry.getValue(); + } + System.out.println("key: " + entry.getKey()); + System.out.println("value: " + entry.getValue()); + } + return appActionWithIdandAction(app, service, type, id, action, request, response, model); + } + + // app mapping all execute goes here + //@RequestMapping("/governance/applications/{app}/services/{ids}/{action}") + //public String serviceActionWithApp(@PathVariable("app") String app, @PathVariable("ids") String ids, + // @PathVariable("type") String type, HttpServletRequest request, + // HttpServletResponse response, Model model) { + // return ""; + //} + + @RequestMapping("/governance/applications/{app}/{elements}/{element}/{type}") + public String appRouter(@PathVariable("app") String app, @PathVariable("elements") String elements, + @PathVariable("element") String element, @PathVariable("type") String type, + HttpServletRequest request, + HttpServletResponse response, Model model) { + if (app != null) { + model.addAttribute("app", app); + } + if (StringUtils.isNumeric(element)) { + //service action, shield, recover.. + Long[] ids = new Long[1]; + ids[0] = Long.valueOf(element); + model.addAttribute("service", request.getParameter("service")); + try { + Method m = servicesController.getClass().getDeclaredMethod(type, Long[].class, HttpServletRequest.class, + HttpServletResponse.class, Model.class); + Object result = m.invoke(servicesController, ids, request, response, model); + return (String) result; + } catch (Exception e) { + e.printStackTrace(); + } + } + if (elements.equals("services")) { + model.addAttribute("service", element); + } else if (elements.equals("addresses")) { + model.addAttribute("address", element); + } + + String name = WebConstants.mapper.get(type); + if (name != null) { + Object controller = SpringUtil.getBean(name); + if (controller != null) { + try { + Method index = controller.getClass().getDeclaredMethod("index", HttpServletRequest.class, HttpServletResponse.class, + Model.class); + Object result = index.invoke(controller, request, response, model); + return (String)result; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return ""; + } + + @RequestMapping("/governance/applications/{app}/{type}") + public String appWithService(@PathVariable("app") String app, @PathVariable("type") String type, + HttpServletRequest request, + HttpServletResponse response, + Model model) { + model.addAttribute("app", app); + String name = WebConstants.mapper.get(type); + if (name != null) { + Object controller = SpringUtil.getBean(name); + try { + Method index = controller.getClass().getDeclaredMethod("index", HttpServletRequest.class, + HttpServletResponse.class, Model.class); + Object result = index.invoke(controller, request, response, model); + return (String) result; + } catch (Exception e) { + e.printStackTrace(); + } + + } + return ""; + } + + + @RequestMapping("/governance/applications/{app}/{elements}/{element}/{type}/{action}") + public String appAction(@RequestParam Map params, @PathVariable("app") String app, + @PathVariable("elements") String elements, @PathVariable("element") String element, + @PathVariable("type") String type, @PathVariable("action") String action, + HttpServletRequest request, HttpServletResponse response, Model model) { + if (app != null) { + model.addAttribute("app", app); + } + if (elements.equals("services")) { + model.addAttribute("service", element); + } else if (elements.equals("addresses")) { + model.addAttribute("address", element); + } + + String name = WebConstants.mapper.get(type); + if (name != null) { + Object controller = SpringUtil.getBean(name); + if (controller != null) { + if (request.getMethod().equals("POST")) { + Method[] methods = controller.getClass().getDeclaredMethods(); + for (Method method : methods) { + if (method.getName().equals(action)) { + Class param = method.getParameterTypes()[0]; + try { + if (!param.isAssignableFrom(HttpServletRequest.class)) { + Object value = param.newInstance(); + Method[] mms = param.getDeclaredMethods(); + for (Method m : mms) { + if (m.getName().toLowerCase().startsWith("set")) { + String methodName = m.getName(); + String key = methodName.substring(3).toLowerCase(); + String tmp = params.get(key); + Object obj = tmp; + if (tmp != null) { + Class t = m.getParameterTypes()[0]; + if (isPrimitive(t)) { + obj = convertPrimitive(t, tmp); + } + m.invoke(value, obj); + } + + } + } + return (String)method.invoke(controller, value, request, response, model); + } else { + return (String)method.invoke(controller, request, response, model); + } + } catch (Exception e) { + e.printStackTrace(); + } + + + } + } + } else { + try { + if (StringUtils.isNumeric(action)) { + // action is id, call show method + Method show = controller.getClass().getDeclaredMethod("show", Long.class, HttpServletRequest.class, HttpServletResponse.class, + Model.class); + Object result = show.invoke(controller, Long.valueOf(action), request, response, model); + return (String)result; + } else { + Method m = controller.getClass().getDeclaredMethod(action, HttpServletRequest.class, + HttpServletResponse.class, + Model.class); + Object result = m.invoke(controller, request, response, model); + return (String)result; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + return ""; + } + + + @RequestMapping("/governance/applications/{app}/services/{service}/{type}/{id}/{action}") + public String appActionWithIdandAction(@PathVariable("app") String app, @PathVariable("service") String service, + @PathVariable("type") String type, @PathVariable("id") String id, + @PathVariable("action") String action, + HttpServletRequest request, HttpServletResponse response, Model model) { + if (app != null) { + model.addAttribute("app", app); + } + model.addAttribute("service", service); + String name = WebConstants.mapper.get(type); + if (name != null) { + Object controller = SpringUtil.getBean(name); + if (controller != null) { + try { + Object result = null; + if (StringUtils.isNumeric(id)) { + //single id + Method m = null; + try { + m = controller.getClass().getDeclaredMethod(action, Long.class, HttpServletRequest.class, + HttpServletResponse.class, Model.class); + result = m.invoke(controller, Long.valueOf(id), request, response, model); + } catch (NoSuchMethodException e) { + m = controller.getClass().getDeclaredMethod(action, Long[].class, HttpServletRequest.class, + HttpServletResponse.class, Model.class); + result = m.invoke(controller, new Long[]{Long.valueOf(id)}, request, response, model); + + } + } else { + //id array + String[] array = id.split(","); + Long[] ids = new Long[array.length]; + for (int i = 0; i < array.length; i ++) { + ids[i] = Long.valueOf(array[i]); + } + + Method m = controller.getClass().getDeclaredMethod(action, Long[].class, HttpServletRequest.class, + HttpServletResponse.class, Model.class); + + result = m.invoke(controller, ids, request, response, model); + } + return (String)result; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return ""; + + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/common/auth/DubboUser.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/common/auth/DubboUser.java new file mode 100644 index 0000000..9339417 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/common/auth/DubboUser.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.common.auth; + +import java.io.Serializable; + +import com.alibaba.dubboadmin.registry.common.domain.User; + +/** + * MinasUser: DubboUser + * + */ +public class DubboUser implements Serializable { + + private static final long serialVersionUID = 1L; + + private static final ThreadLocal userHolder = new ThreadLocal(); + + private DubboUser() { + } + + public static final User getCurrentUser() { + return (User) userHolder.get(); + } + + public static final void setCurrentUser(User user) { + userHolder.set(user); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/common/i18n/LocaleUtil.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/common/i18n/LocaleUtil.java new file mode 100644 index 0000000..5d61e8a --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/common/i18n/LocaleUtil.java @@ -0,0 +1,36 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.common.i18n; + +import java.util.Locale; + +public class LocaleUtil { + private static ThreadLocal userLocale = new ThreadLocal(); + + public static void cleanLocale() { + userLocale.remove(); + } + + public static Locale getLocale() { + return userLocale.get(); + } + + public static void setLocale(Locale locale) { + userLocale.set(locale); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/AccessesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/AccessesController.java new file mode 100644 index 0000000..d814f4c --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/AccessesController.java @@ -0,0 +1,303 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.governance.service.RouteService; +import com.alibaba.dubboadmin.registry.common.domain.Access; +import com.alibaba.dubboadmin.registry.common.domain.Route; +import com.alibaba.dubboadmin.registry.common.route.RouteRule; +import com.alibaba.dubboadmin.registry.common.route.RouteRule.MatchPair; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * ProvidersController. URI: /services/$service/accesses + * + */ + +@Controller +@RequestMapping("/governance/accesses") +public class AccessesController extends BaseController { + + private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3}$"); + private static final Pattern LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$"); + private static final Pattern ALL_IP_PATTERN = Pattern.compile("0{1,3}(\\.0{1,3}){3}$"); + + @Autowired + private RouteService routeService; + @Autowired + private ProviderService providerService; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "accesses"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String address = (String)newModel.get("address"); + String service = (String)newModel.get("service"); + + address = Tool.getIP(address); + List routes; + if (service != null && service.length() > 0) { + routes = routeService.findForceRouteByService(service); + } else if (address != null && address.length() > 0) { + routes = routeService.findForceRouteByAddress(address); + } else { + routes = routeService.findAllForceRoute(); + } + List accesses = new ArrayList(); + if (routes == null) { + model.addAttribute("accesses", accesses); + return "governance/screen/accesses/index"; + } + for (Route route : routes) { + Map rule = null; + try { + rule = RouteRule.parseRule(route.getMatchRule()); + } catch (ParseException e) { + logger.error("parse rule error", e); + } + MatchPair pair = rule.get("consumer.host"); + if (pair != null) { + for (String host : pair.getMatches()) { + Access access = new Access(); + access.setAddress(host); + access.setService(route.getService()); + access.setAllow(false); + accesses.add(access); + } + for (String host : pair.getUnmatches()) { + Access access = new Access(); + access.setAddress(host); + access.setService(route.getService()); + access.setAllow(true); + accesses.add(access); + } + } + } + model.addAttribute("accesses", accesses); + return "governance/screen/accesses/index"; + } + + @RequestMapping("/add") + public String add(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "add", "accesses"); + List serviceList = Tool.sortSimpleName(providerService.findServices()); + model.addAttribute("serviceList", serviceList); + return "governance/screen/accesses/add"; + } + + @RequestMapping("/create") + public String create(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, "create", "accesses"); + String addr = request.getParameter("consumerAddress"); + String services = request.getParameter("service"); + Set consumerAddresses = toAddr(addr); + Set aimServices = toService(services); + for (String aimService : aimServices) { + boolean isFirst = false; + List routes = routeService.findForceRouteByService(aimService); + Route route = null; + if (routes == null || routes.size() == 0) { + isFirst = true; + route = new Route(); + route.setService(aimService); + route.setForce(true); + route.setName(aimService + " blackwhitelist"); + route.setFilterRule("false"); + route.setEnabled(true); + } else { + route = routes.get(0); + } + Map when = null; + MatchPair matchPair = null; + if (isFirst) { + when = new HashMap(); + matchPair = new MatchPair(new HashSet(), new HashSet()); + when.put("consumer.host", matchPair); + } else { + when = RouteRule.parseRule(route.getMatchRule()); + matchPair = when.get("consumer.host"); + } + for (String consumerAddress : consumerAddresses) { + if (Boolean.valueOf((String) request.getParameter("allow"))) { + matchPair.getUnmatches().add(Tool.getIP(consumerAddress)); + + } else { + matchPair.getMatches().add(Tool.getIP(consumerAddress)); + } + } + StringBuilder sb = new StringBuilder(); + RouteRule.contidionToString(sb, when); + route.setMatchRule(sb.toString()); + route.setUsername(operator); + if (isFirst) { + routeService.createRoute(route); + } else { + routeService.updateRoute(route); + } + + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../accesses"); + return "governance/screen/redirect"; + + } + + private Set toAddr(String addr) throws IOException { + Set consumerAddresses = new HashSet(); + BufferedReader reader = new BufferedReader(new StringReader(addr)); + while (true) { + String line = reader.readLine(); + if (null == line) + break; + + String[] split = line.split("[\\s,;]+"); + for (String s : split) { + if (s.length() == 0) + continue; + if (!IP_PATTERN.matcher(s).matches()) { + throw new IllegalStateException("illegal IP: " + s); + } + if (LOCAL_IP_PATTERN.matcher(s).matches() || ALL_IP_PATTERN.matcher(s).matches()) { + throw new IllegalStateException("local IP or any host ip is illegal: " + s); + } + + consumerAddresses.add(s); + } + } + return consumerAddresses; + } + + private Set toService(String services) throws IOException { + Set aimServices = new HashSet(); + BufferedReader reader = new BufferedReader(new StringReader(services)); + while (true) { + String line = reader.readLine(); + if (null == line) + break; + + String[] split = line.split("[\\s,;]+"); + for (String s : split) { + if (s.length() == 0) + continue; + aimServices.add(s); + } + } + return aimServices; + } + + /** + * + * @throws ParseException + */ + @RequestMapping("/delete") + public String delete(@RequestParam String accesses, HttpServletRequest request, HttpServletResponse response, Model model) throws ParseException { + prepare(request, response, model, "delete", "accesses"); + String[] temp = accesses.split(" "); + Map> prepareToDeleate = new HashMap>(); + for (String s : temp) { + String service = s.split("=")[0]; + String address = s.split("=")[1]; + Set addresses = prepareToDeleate.get(service); + if (addresses == null) { + prepareToDeleate.put(service, new HashSet()); + addresses = prepareToDeleate.get(service); + } + addresses.add(address); + } + for (Entry> entry : prepareToDeleate.entrySet()) { + + String service = entry.getKey(); + List routes = routeService.findForceRouteByService(service); + if (routes == null || routes.size() == 0) { + continue; + } + for (Route blackwhitelist : routes) { + MatchPair pairs = RouteRule.parseRule(blackwhitelist.getMatchRule()).get("consumer.host"); + Set matches = new HashSet(); + matches.addAll(pairs.getMatches()); + Set unmatches = new HashSet(); + unmatches.addAll(pairs.getUnmatches()); + for (String pair : pairs.getMatches()) { + for (String address : entry.getValue()) { + if (pair.equals(address)) { + matches.remove(pair); + break; + } + } + } + for (String pair : pairs.getUnmatches()) { + for (String address : entry.getValue()) { + if (pair.equals(address)) { + unmatches.remove(pair); + break; + } + } + } + if (matches.size() == 0 && unmatches.size() == 0) { + routeService.deleteRoute(blackwhitelist.getId()); + } else { + Map condition = new HashMap(); + condition.put("consumer.host", new MatchPair(matches, unmatches)); + StringBuilder sb = new StringBuilder(); + RouteRule.contidionToString(sb, condition); + blackwhitelist.setMatchRule(sb.toString()); + routeService.updateRoute(blackwhitelist); + } + } + + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../accesses"); + return "governance/screen/redirect"; + } + + public void show(Map context) { + } + + public void edit(Map context) { + } + + public String update(Map context) { + return null; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/AddressesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/AddressesController.java new file mode 100644 index 0000000..d728e97 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/AddressesController.java @@ -0,0 +1,155 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * ProvidersController. + * URI: /services/$service/providers + * + */ +@Controller +@RequestMapping("/governance/addresses") +public class AddressesController extends BaseController { + + @Autowired + private ProviderService providerService; + + @Autowired + private ConsumerService consumerService; + + @Autowired + ServicesController servicesController; + + private Map context = new HashMap<>(); + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "addresses"); + List providerAddresses = null; + List consumerAddresses = null; + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String application = (String)newModel.get("app"); + String service = (String)newModel.get("service"); + String address = (String)newModel.get("address"); + String keyword = (String)newModel.get("keyword"); + + if (application != null && application.length() > 0) { + providerAddresses = providerService.findAddressesByApplication(application); + consumerAddresses = consumerService.findAddressesByApplication(application); + } else if (service != null && service.length() > 0) { + providerAddresses = providerService.findAddressesByService(service); + consumerAddresses = consumerService.findAddressesByService(service); + } else { + providerAddresses = providerService.findAddresses(); + consumerAddresses = consumerService.findAddresses(); + } + + Set addresses = new TreeSet(); + if (providerAddresses != null) { + addresses.addAll(providerAddresses); + } + if (consumerAddresses != null) { + addresses.addAll(consumerAddresses); + } + model.addAttribute("providerAddresses", providerAddresses); + model.addAttribute("consumerAddresses", consumerAddresses); + model.addAttribute("addresses", addresses); + + if (service == null && application == null + && address == null) { + model.addAttribute("address", "*"); + } + + if (StringUtils.isNotEmpty(keyword)) { + if ("*".equals(keyword)) { + return "governance/screen/addresses/index"; + } + + keyword = keyword.toLowerCase(); + Set newList = new HashSet(); + Set newProviders = new HashSet(); + Set newConsumers = new HashSet(); + + for (String o : addresses) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newList.add(o); + } + } + for (String o : providerAddresses) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newProviders.add(o); + } + } + for (String o : consumerAddresses) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newConsumers.add(o); + } + } + context.put("addresses", newList); + model.addAttribute("addresses", newList); + model.addAttribute("providerAddresses", newProviders); + model.addAttribute("consumerAddresses", newConsumers); + } + return "governance/screen/addresses/index"; + } + + //@RequestMapping("/{ip:[0-9.]+}/{type}") + //public String addressMapping(@PathVariable("ip") String ip, @PathVariable("type") String type, + // HttpServletRequest request, HttpServletResponse response, Model model) { + // return servicesController.route(null, type, null, ip, request, response, model); + //} + + //public void search( + // HttpServletRequest request, HttpServletResponse response, Model model) { + // index(request, response, model); + // + // Set newList = new HashSet(); + // @SuppressWarnings("unchecked") + // Set list = (Set) context.get("addresses"); + // if (StringUtils.isNotEmpty(keyword)) { + // keyword = keyword.toLowerCase(); + // for (String o : list) { + // if (o.toLowerCase().indexOf(keyword) != -1) { + // newList.add(o); + // } + // } + // } + // context.put("addresses", newList); + // model.addAttribute("addresses", newList); + //} +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ApplicationsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ApplicationsController.java new file mode 100644 index 0000000..c277a37 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ApplicationsController.java @@ -0,0 +1,336 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.route.OverrideUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * ProvidersController. + * URI: /applications + * + */ +@Controller +@RequestMapping("/governance/applications") +public class ApplicationsController extends BaseController { + + @Autowired + private ProviderService providerService; + + @Autowired + private ConsumerService consumerService; + + @Autowired + private OverrideService overrideService; + + @Autowired + ServicesController servicesController; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "applications"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + String application = (String)newModel.get("app"); + String address = (String)newModel.get("address"); + String keyword = request.getParameter("keyword"); + if (service != null) { + Set applications = new TreeSet(); + List providerApplications = providerService.findApplicationsByServiceName(service); + if (providerApplications != null && providerApplications.size() > 0) { + applications.addAll(providerApplications); + } + List consumerApplications = consumerService.findApplicationsByServiceName(service); + if (consumerApplications != null && consumerApplications.size() > 0) { + applications.addAll(consumerApplications); + } + model.addAttribute("applications", applications); + model.addAttribute("providerApplications", providerApplications); + model.addAttribute("consumerApplications", consumerApplications); + if (service != null && service.length() > 0) { + List overrides = overrideService.findByService(service); + Map> application2Overrides = new HashMap>(); + if (overrides != null && overrides.size() > 0 + && applications != null && applications.size() > 0) { + for (String a : applications) { + if (overrides != null && overrides.size() > 0) { + List appOverrides = new ArrayList(); + for (Override override : overrides) { + if (override.isMatch(service, null, a)) { + appOverrides.add(override); + } + } + Collections.sort(appOverrides, OverrideUtils.OVERRIDE_COMPARATOR); + application2Overrides.put(a, appOverrides); + } + } + } + model.addAttribute("overrides", application2Overrides); + } + return "governance/screen/applications/index"; + } + if (service == null && application == null + && address == null) { + model.addAttribute("app", "*"); + } + Set applications = new TreeSet(); + List providerApplications = providerService.findApplications(); + if (providerApplications != null && providerApplications.size() > 0) { + applications.addAll(providerApplications); + } + List consumerApplications = consumerService.findApplications(); + if (consumerApplications != null && consumerApplications.size() > 0) { + applications.addAll(consumerApplications); + } + + Set newList = new HashSet(); + Set newProviders = new HashSet(); + Set newConsumers = new HashSet(); + model.addAttribute("applications", applications); + model.addAttribute("providerApplications", providerApplications); + model.addAttribute("consumerApplications", consumerApplications); + + if (StringUtils.isNotEmpty(keyword) && !"*".equals(keyword)) { + keyword = keyword.toLowerCase(); + for (String o : applications) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newList.add(o); + } + } + for (String o : providerApplications) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newProviders.add(o); + } + } + for (String o : consumerApplications) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newConsumers.add(o); + } + } + model.addAttribute("applications", newList); + model.addAttribute("providerApplications", newProviders); + model.addAttribute("consumerApplications", newConsumers); + } + return "governance/screen/applications/index"; + } + + //@RequestMapping("/{application}/services") + //public String getService(@PathVariable("application") String app, HttpServletRequest request, + // HttpServletResponse response, + // Model model) { + // return servicesController.index(app, null, null, null, request, response, model); + //} + + //@RequestMapping("/{application}/services/{serviceName}/{type}") + //public String serviceMapping(@PathVariable("application") String app, + // @PathVariable("serviceName") String serviceName, + // @PathVariable("type") String type, HttpServletRequest request, HttpServletResponse response, + // Model model) { + // return servicesController.route(serviceName, type, app, null, request, response, model); + //} + + //public void search(@RequestParam(required = false) String service, + // @RequestParam(required = false) String address, + // @RequestParam(required = false) String application, + // @RequestParam(required = false) String keyword, + // HttpServletRequest request, HttpServletResponse response, Model model) { + // index(service, address, application, keyword, request, response, model); + // + // //Set newList = new HashSet(); + // //@SuppressWarnings("unchecked") + // //Set apps = (Set) .get("applications"); + // //String keyword = (String) context.get("keyword"); + // //if (StringUtils.isNotEmpty(keyword)) { + // // keyword = keyword.toLowerCase(); + // // for (String o : apps) { + // // if (o.toLowerCase().indexOf(keyword) != -1) { + // // newList.add(o); + // // } + // // } + // //} + // //context.put("applications", newList); + //} + + @RequestMapping("/{ids}/shield") + public String shield(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "force:return null", "shield", request, response, model); + } + + @RequestMapping("/{ids}/tolerant") + public String tolerant(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "fail:return null", "tolerant", request, response, model); + } + + @RequestMapping("/{ids}/recover") + public String recover(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "", "recover", request, response, model); + } + + private String mock(Long[] ids, String mock, String methodName, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, methodName, "applications"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String) newModel.get("service"); + String applications = (String) newModel.get("app"); + if (service == null || service.length() == 0 + || applications == null || applications.length() == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../applications"); + return "governance/screen/redirect"; + } + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../applications"); + return "governance/screen/redirect"; + } + for (String application : SPACE_SPLIT_PATTERN.split(applications)) { + List overrides = overrideService.findByServiceAndApplication(service, application); + if (overrides != null && overrides.size() > 0) { + for (Override override : overrides) { + Map map = StringUtils.parseQueryString(override.getParams()); + if (mock == null || mock.length() == 0) { + map.remove("mock"); + } else { + map.put("mock", URL.encode(mock)); + } + if (map.size() > 0) { + override.setParams(StringUtils.toQueryString(map)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.updateOverride(override); + } else { + overrideService.deleteOverride(override.getId()); + } + } + } else if (mock != null && mock.length() > 0) { + Override override = new Override(); + override.setService(service); + override.setApplication(application); + override.setParams("mock=" + URL.encode(mock)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.saveOverride(override); + } + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../../applications"); + return "governance/screen/redirect"; + } + + @RequestMapping("/allshield") + public String allshield(@RequestParam(required = false) String service, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + return allmock(service, "force:return null", "allshield", request, response, model); + } + + @RequestMapping("/alltolerant") + public String alltolerant(@RequestParam(required = false) String service, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + return allmock(service, "fail:return null", "alltolerant", request, response, model); + } + + @RequestMapping("/allrecover") + public String allrecover(@RequestParam(required = false) String service, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + return allmock(service, "", "allrecover", request, response, model); + } + + private String allmock(String service, String mock, String methodName, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, methodName, "applications"); + if (service == null || service.length() == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../applications"); + return "governance/screen/redirect"; + } + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../applications"); + return "governance/screen/redirect"; + } + List overrides = overrideService.findByService(service); + Override allOverride = null; + if (overrides != null && overrides.size() > 0) { + for (Override override : overrides) { + if (override.isDefault()) { + allOverride = override; + break; + } + } + } + if (allOverride != null) { + Map map = StringUtils.parseQueryString(allOverride.getParams()); + if (mock == null || mock.length() == 0) { + map.remove("mock"); + } else { + map.put("mock", URL.encode(mock)); + } + if (map.size() > 0) { + allOverride.setParams(StringUtils.toQueryString(map)); + allOverride.setEnabled(true); + allOverride.setOperator(operator); + allOverride.setOperatorAddress(operatorAddress); + overrideService.updateOverride(allOverride); + } else { + overrideService.deleteOverride(allOverride.getId()); + } + } else if (mock != null && mock.length() > 0) { + Override override = new Override(); + override.setService(service); + override.setParams("mock=" + URL.encode(mock)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.saveOverride(override); + } + model.addAttribute("success", false); + model.addAttribute("redirect", "../../applications"); + return "governance/screen/redirect"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ConsumersController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ConsumersController.java new file mode 100644 index 0000000..7fa1675 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ConsumersController.java @@ -0,0 +1,538 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.governance.service.RouteService; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.domain.Route; +import com.alibaba.dubboadmin.registry.common.route.OverrideUtils; +import com.alibaba.dubboadmin.registry.common.route.RouteRule; +import com.alibaba.dubboadmin.registry.common.route.RouteRule.MatchPair; +import com.alibaba.dubboadmin.registry.common.route.RouteUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * ConsumersController. URI: /services/$service/consumers + * + */ +@Controller +@RequestMapping("/governance/consumers") +public class ConsumersController extends BaseController { + + @Autowired + private ProviderService providerService; + + @Autowired + private ConsumerService consumerService; + + @Autowired + private OverrideService overrideService; + + @Autowired + private RouteService routeService; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, + Model model) { + prepare(request, response, model, "index", "consumers"); + List consumers; + List overrides; + List providers = null; + List routes = null; + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + String address = (String)newModel.get("address"); + String application = (String)newModel.get("app"); + // service + if (service != null && service.length() > 0) { + consumers = consumerService.findByService(service); + overrides = overrideService.findByService(service); + providers = providerService.findByService(service); + routes = routeService.findByService(service); + } + // address + else if (address != null && address.length() > 0) { + consumers = consumerService.findByAddress(address); + overrides = overrideService.findByAddress(Tool.getIP(address)); + } + // application + else if (application != null && application.length() > 0) { + consumers = consumerService.findByApplication(application); + overrides = overrideService.findByApplication(application); + } + // all + else { + consumers = consumerService.findAll(); + overrides = overrideService.findAll(); + } + if (consumers != null && consumers.size() > 0) { + for (Consumer consumer : consumers) { + if (service == null || service.length() == 0) { + providers = providerService.findByService(consumer.getService()); + routes = routeService.findByService(consumer.getService()); + } + List routed = new ArrayList(); + consumer.setProviders(RouteUtils + .route(consumer.getService(), consumer.getAddress(), consumer.getParameters(), providers, overrides, routes, null, routed)); + consumer.setRoutes(routed); + OverrideUtils.setConsumerOverrides(consumer, overrides); + } + } + model.addAttribute("consumers", consumers); + return "governance/screen/consumers/index"; + } + + @RequestMapping("/{id}") + public String show(@PathVariable("id") Long id, + HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "show", "consumers"); + Consumer consumer = consumerService.findConsumer(id); + List providers = providerService.findByService(consumer.getService()); + List routes = routeService.findByService(consumer.getService()); + List overrides = overrideService.findByService(consumer.getService()); + List routed = new ArrayList(); + consumer.setProviders(RouteUtils.route(consumer.getService(), consumer.getAddress(), consumer.getParameters(), providers, overrides, routes, null, routed)); + consumer.setRoutes(routed); + OverrideUtils.setConsumerOverrides(consumer, overrides); + model.addAttribute("consumer", consumer); + model.addAttribute("providers", consumer.getProviders()); + model.addAttribute("routes", consumer.getRoutes()); + model.addAttribute("overrides", consumer.getOverrides()); + return "governance/screen/consumers/show"; + } + + @RequestMapping("/{id}/edit") + public String edit(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "edit", "consumers"); + Consumer consumer = consumerService.findConsumer(id); + List providers = providerService.findByService(consumer.getService()); + List routes = routeService.findByService(consumer.getService()); + List overrides = overrideService.findByService(consumer.getService()); + List routed = new ArrayList(); + consumer.setProviders(RouteUtils.route(consumer.getService(), consumer.getAddress(), consumer.getParameters(), providers, overrides, routes, null, routed)); + consumer.setRoutes(routed); + OverrideUtils.setConsumerOverrides(consumer, overrides); + model.addAttribute("consumer", consumer); + model.addAttribute("providers", consumer.getProviders()); + model.addAttribute("routes", consumer.getRoutes()); + model.addAttribute("overrides", consumer.getOverrides()); + return "governance/screen/consumers/edit"; + } + + @RequestMapping(value = "/update", method = RequestMethod.POST) //post + public String update(@ModelAttribute Consumer newConsumer, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "update", "consumers"); + boolean success = true; + Long id = newConsumer.getId(); + String parameters = newConsumer.getParameters(); + Consumer consumer = consumerService.findConsumer(id); + if (consumer == null) { + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "governance/consumers"); + return "governance/screen/redirect"; + } + String service = consumer.getService(); + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "governance/consumers"); + return "governance/screen/redirect"; + } + Map oldMap = StringUtils.parseQueryString(consumer.getParameters()); + Map newMap = StringUtils.parseQueryString(parameters); + for (Map.Entry entry : oldMap.entrySet()) { + if (entry.getValue().equals(newMap.get(entry.getKey()))) { + newMap.remove(entry.getKey()); + } + } + String address = consumer.getAddress(); + List overrides = overrideService.findByServiceAndAddress(consumer.getService(), consumer.getAddress()); + OverrideUtils.setConsumerOverrides(consumer, overrides); + Override override = consumer.getOverride(); + if (override != null) { + if (newMap.size() > 0) { + override.setParams(StringUtils.toQueryString(newMap)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.updateOverride(override); + } else { + overrideService.deleteOverride(override.getId()); + } + } else { + override = new Override(); + override.setService(service); + override.setAddress(address); + override.setParams(StringUtils.toQueryString(newMap)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.saveOverride(override); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "governance/consumers"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{id}/routed") + public String routed(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "routed", "consumers"); + showDetail(id, request, response, model); + return "governance/screen/consumers/routed"; + } + + @RequestMapping("/{id}/notified") + public String notified(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "notified", "consumers"); + showDetail(id, request, response, model); + return "governance/screen/consumers/notified"; + } + + @RequestMapping("/{id}/overrided") + public String overrided(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "overrided", "consumers"); + showDetail(id, request, response, model); + return "governance/screen/consumers/overrided"; + } + + @RequestMapping("/{ids}/shield") + public String shield(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "force:return null", "shield", request, response, model); + } + + @RequestMapping("/{ids}/tolerant") + public String tolerant(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "fail:return null", "tolerant", request, response, model); + } + + @RequestMapping("/{ids}/recover") + public String recover(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "", "recover", request, response, model); + } + + private String mock(Long[] ids, String mock, String methodName, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, methodName, "consumers"); + boolean success = true; + if (ids == null || ids.length == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../consumers"); + return "governance/screen/redirect"; + } + List consumers = new ArrayList(); + for (Long id : ids) { + Consumer c = consumerService.findConsumer(id); + if (c != null) { + consumers.add(c); + if (!super.currentUser.hasServicePrivilege(c.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", c.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../consumers"); + return "governance/screen/redirect"; + } + } + } + for (Consumer consumer : consumers) { + String service = consumer.getService(); + String address = Tool.getIP(consumer.getAddress()); + List overrides = overrideService.findByServiceAndAddress(service, address); + if (overrides != null && overrides.size() > 0) { + for (Override override : overrides) { + Map map = StringUtils.parseQueryString(override.getParams()); + if (mock == null || mock.length() == 0) { + map.remove("mock"); + } else { + map.put("mock", URL.encode(mock)); + } + if (map.size() > 0) { + override.setParams(StringUtils.toQueryString(map)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.updateOverride(override); + } else { + overrideService.deleteOverride(override.getId()); + } + } + } else if (mock != null && mock.length() > 0) { + Override override = new Override(); + override.setService(service); + override.setAddress(address); + override.setParams("mock=" + URL.encode(mock)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.saveOverride(override); + } + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../consumers"); + return "governance/screen/redirect"; + } + + private void showDetail( Long id, + HttpServletRequest request, HttpServletResponse response, Model model) { + Consumer consumer = consumerService.findConsumer(id); + List providers = providerService.findByService(consumer.getService()); + List routes = routeService.findByService(consumer.getService()); + List overrides = overrideService.findByService(consumer.getService()); + List routed = new ArrayList(); + consumer.setProviders(RouteUtils.route(consumer.getService(), consumer.getAddress(), consumer.getParameters(), providers, overrides, routes, null, routed)); + consumer.setRoutes(routed); + OverrideUtils.setConsumerOverrides(consumer, overrides); + model.addAttribute("consumer", consumer); + model.addAttribute("providers", consumer.getProviders()); + model.addAttribute("routes", consumer.getRoutes()); + model.addAttribute("overrides", consumer.getOverrides()); + } + + @RequestMapping("/allshield") + public String allshield(@RequestParam(required = false) String service, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + return allmock(service, "force:return null", "allshield",request, response, model); + } + + @RequestMapping("/alltolerant") + public String alltolerant(@RequestParam(required = false) String service, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + return allmock(service, "fail:return null", "alltolerant", request, response, model); + } + + @RequestMapping("/allrecover") + public String allrecover(@RequestParam(required = false) String service, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + return allmock(service, "", "allrecover", request, response, model); + } + + private String allmock(String service, String mock, String methodName, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, methodName,"consumers"); + boolean success = true; + if (service == null || service.length() == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../consumers"); + return "governance/screen/redirect"; + } + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../consumers"); + return "governance/screen/redirect"; + } + List overrides = overrideService.findByService(service); + Override allOverride = null; + if (overrides != null && overrides.size() > 0) { + for (Override override : overrides) { + if (override.isDefault()) { + allOverride = override; + break; + } + } + } + if (allOverride != null) { + Map map = StringUtils.parseQueryString(allOverride.getParams()); + if (mock == null || mock.length() == 0) { + map.remove("mock"); + } else { + map.put("mock", URL.encode(mock)); + } + if (map.size() > 0) { + allOverride.setParams(StringUtils.toQueryString(map)); + allOverride.setEnabled(true); + allOverride.setOperator(operator); + allOverride.setOperatorAddress(operatorAddress); + overrideService.updateOverride(allOverride); + } else { + overrideService.deleteOverride(allOverride.getId()); + } + } else if (mock != null && mock.length() > 0) { + Override override = new Override(); + override.setService(service); + override.setParams("mock=" + URL.encode(mock)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.saveOverride(override); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../consumers"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/allow") + public String allow(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return access(request, response, ids, model, true, false, "allow"); + } + + @RequestMapping("/{ids}/forbid") + public String forbid(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return access(request, response, ids, model, false, false, "forbid"); + } + + @RequestMapping("/{ids}/onlyallow") + public String onlyallow(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return access(request, response, ids, model, true, true, "onlyallow"); + } + + @RequestMapping("/{ids}/onlyforbid") + public String onlyforbid(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return access(request, response, ids, model, false, true, "onlyforbid"); + } + + private String access(HttpServletRequest request, HttpServletResponse response, Long[] ids, + Model model, boolean allow, boolean only, String methodName) throws Exception { + prepare(request, response, model, methodName, "consumers"); + boolean success = true; + if (ids == null || ids.length == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../consumers"); + return "governance/screen/redirect"; + } + List consumers = new ArrayList(); + for (Long id : ids) { + Consumer c = consumerService.findConsumer(id); + if (c != null) { + consumers.add(c); + if (!super.currentUser.hasServicePrivilege(c.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", c.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../consumers"); + return "governance/screen/redirect"; + } + } + } + Map> serviceAddresses = new HashMap>(); + for (Consumer consumer : consumers) { + String service = consumer.getService(); + String address = Tool.getIP(consumer.getAddress()); + Set addresses = serviceAddresses.get(service); + if (addresses == null) { + addresses = new HashSet(); + serviceAddresses.put(service, addresses); + } + addresses.add(address); + } + for (Map.Entry> entry : serviceAddresses.entrySet()) { + String service = entry.getKey(); + boolean isFirst = false; + List routes = routeService.findForceRouteByService(service); + Route route = null; + if (routes == null || routes.size() == 0) { + isFirst = true; + route = new Route(); + route.setService(service); + route.setForce(true); + route.setName(service + " blackwhitelist"); + route.setFilterRule("false"); + route.setEnabled(true); + } else { + route = routes.get(0); + } + Map when = null; + MatchPair matchPair = null; + if (isFirst) { + when = new HashMap(); + matchPair = new MatchPair(new HashSet(), new HashSet()); + when.put("consumer.host", matchPair); + } else { + when = RouteRule.parseRule(route.getMatchRule()); + matchPair = when.get("consumer.host"); + } + if (only) { + matchPair.getUnmatches().clear(); + matchPair.getMatches().clear(); + if (allow) { + matchPair.getUnmatches().addAll(entry.getValue()); + } else { + matchPair.getMatches().addAll(entry.getValue()); + } + } else { + for (String consumerAddress : entry.getValue()) { + if (matchPair.getUnmatches().size() > 0) { // whitelist take effect + matchPair.getMatches().remove(consumerAddress); // remove data in blacklist + if (allow) { // if allowed + matchPair.getUnmatches().add(consumerAddress); // add to whitelist + } else { // if not allowed + matchPair.getUnmatches().remove(consumerAddress); // remove from whitelist + } + } else { // blacklist take effect + if (allow) { // if allowed + matchPair.getMatches().remove(consumerAddress); // remove from blacklist + } else { // if not allowed + matchPair.getMatches().add(consumerAddress); // add to blacklist + } + } + } + } + StringBuilder sb = new StringBuilder(); + RouteRule.contidionToString(sb, when); + route.setMatchRule(sb.toString()); + route.setUsername(operator); + if (matchPair.getMatches().size() > 0 || matchPair.getUnmatches().size() > 0) { + if (isFirst) { + routeService.createRoute(route); + } else { + routeService.updateRoute(route); + } + } else if (!isFirst) { + routeService.deleteRoute(route.getId()); + } + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../consumers"); + return "governance/screen/redirect"; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/LoadbalancesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/LoadbalancesController.java new file mode 100644 index 0000000..7b19aa8 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/LoadbalancesController.java @@ -0,0 +1,191 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.utils.CollectionUtils; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.LoadBalance; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.util.OverrideUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * ProvidersController. + * URI: /services/$service/loadbalances + * + */ +@Controller +@RequestMapping("/governance/loadbalances") +public class LoadbalancesController extends BaseController { + + @Autowired + private OverrideService overrideService; + + @Autowired + private ProviderService providerService; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "loadbalances"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + service = StringUtils.trimToNull(service); + + List loadbalances; + if (service != null && service.length() > 0) { + loadbalances = OverrideUtils.overridesToLoadBalances(overrideService.findByService(service)); + } else { + loadbalances = OverrideUtils.overridesToLoadBalances(overrideService.findAll()); + } + model.addAttribute("loadbalances", loadbalances); + return "governance/screen/loadbalances/index"; + } + + @RequestMapping("/{id}") + public String show(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "show", "loadbalances"); + LoadBalance loadbalance = OverrideUtils.overrideToLoadBalance(overrideService.findById(id)); + model.addAttribute("loadbalance", loadbalance); + return "governance/screen/loadbalances/show"; + } + + @RequestMapping("/add") + public String add(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "add", "loadbalances"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + + if (service != null && service.length() > 0 && !service.contains("*")) { + List providerList = providerService.findByService(service); + List addressList = new ArrayList(); + for (Provider provider : providerList) { + addressList.add(provider.getUrl().split("://")[1].split("/")[0]); + } + model.addAttribute("addressList", addressList); + model.addAttribute("service", service); + model.addAttribute("methods", CollectionUtils.sort(providerService.findMethodsByService(service))); + } else { + List serviceList = Tool.sortSimpleName(providerService.findServices()); + model.addAttribute("serviceList", serviceList); + } + //if (input != null) model.addAttribute("input", input); + return "governance/screen/loadbalances/add"; + } + + @RequestMapping("/{id}/edit") + public String edit(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "edit", "loadbalances"); + String service = request.getParameter("service"); + String input = request.getParameter("input"); + + if (service != null && service.length() > 0 && !service.contains("*")) { + List providerList = providerService.findByService(service); + List addressList = new ArrayList(); + for (Provider provider : providerList) { + addressList.add(provider.getUrl().split("://")[1].split("/")[0]); + } + model.addAttribute("addressList", addressList); + model.addAttribute("service", service); + model.addAttribute("methods", CollectionUtils.sort(providerService.findMethodsByService(service))); + } else { + List serviceList = Tool.sortSimpleName(providerService.findServices()); + model.addAttribute("serviceList", serviceList); + } + if (input != null) model.addAttribute("input", input); + LoadBalance loadbalance = OverrideUtils.overrideToLoadBalance(overrideService.findById(id)); + model.addAttribute("loadbalance", loadbalance); + return "governance/screen/loadbalances/edit"; + } + + @RequestMapping("/create") + public String create(LoadBalance loadBalance, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "create", "loadbalances"); + boolean success = true; + if (!super.currentUser.hasServicePrivilege(loadBalance.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", loadBalance.getService())); + success = false; + } else { + loadBalance.setUsername((String) ((BindingAwareModelMap)model).get("operator")); + overrideService.saveOverride(OverrideUtils.loadBalanceToOverride(loadBalance)); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../loadbalances"); + return "governance/screen/redirect"; + } + + + @RequestMapping("/update") + public String update(LoadBalance loadBalance, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "update", "loadbalances"); + boolean success = true; + if (!super.currentUser.hasServicePrivilege(loadBalance.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", loadBalance.getService())); + success = false; + } else { + overrideService.updateOverride(OverrideUtils.loadBalanceToOverride(loadBalance)); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../loadbalances"); + return "governance/screen/redirect"; + + } + + /** + * + * @param ids + * @return + */ + @RequestMapping("/{ids}/delete") + public String delete(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "delete", "loadbalances"); + boolean success = true; + for (Long id : ids) { + LoadBalance lb = OverrideUtils.overrideToLoadBalance(overrideService.findById(id)); + if (!super.currentUser.hasServicePrivilege(lb.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", lb.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../loadbalances"); + return "governance/screen/redirect"; + } + } + + for (Long id : ids) { + overrideService.deleteOverride(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../loadbalances"); + return "governance/screen/redirect"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/NoServicePrivilegeController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/NoServicePrivilegeController.java new file mode 100644 index 0000000..f2a252d --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/NoServicePrivilegeController.java @@ -0,0 +1,36 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; + +/** + * TODO Comment of NoServicePrivilegeController + * + */ +@Controller +public class NoServicePrivilegeController { + + + public void execute(HttpServletRequest request, HttpServletResponse response, Model model) { + model.addAttribute("returnUrl", request.getParameter("returnUrl")); + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/OverridesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/OverridesController.java new file mode 100644 index 0000000..da7ead3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/OverridesController.java @@ -0,0 +1,441 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.CollectionUtils; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/governance/overrides") +public class OverridesController extends BaseController { + static final Pattern AND = Pattern.compile("\\&"); + static final Pattern EQUAL = Pattern.compile("([^=\\s]*)\\s*=\\s*(\\S*)"); + static final String DEFAULT_MOCK_JSON_KEY = "mock"; + static final String MOCK_JSON_KEY_POSTFIX = ".mock"; + static final String FORM_OVERRIDE_KEY = "overrideKey"; + static final String FORM_OVERRIDE_VALUE = "overrideValue"; + static final String FORM_DEFAULT_MOCK_METHOD_FORCE = "mockDefaultMethodForce"; + static final String FORM_DEFAULT_MOCK_METHOD_JSON = "mockDefaultMethodJson"; + static final String FORM_ORIGINAL_METHOD_FORCE_PREFIX = "mockMethodForce."; + static final String FORM_ORIGINAL_METHOD_PREFIX = "mockMethod."; + static final String FORM_DYNAMIC_METHOD_NAME_PREFIX = "mockMethodName"; + static final String FORM_DYNAMIC_METHOD_FORCE_PREFIX = "mockMethodForce"; + static final String FORM_DYNAMIC_METHOD_JSON_PREFIX = "mockMethodJson"; + @Autowired + private OverrideService overrideService; + + // FORM KEY + @Autowired + private ProviderService providerService; + @Autowired + private ConsumerService consumerService; + + static Map parseQueryString(String query) { + HashMap ret = new HashMap(); + if (query == null || (query = query.trim()).length() == 0) return ret; + + String[] kvs = AND.split(query); + for (String kv : kvs) { + Matcher matcher = EQUAL.matcher(kv); + if (!matcher.matches()) continue; + String key = matcher.group(1); + String value = matcher.group(2); + ret.put(key, value); + } + + return ret; + } + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "overrides"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + String application = (String)newModel.get("app"); + String address = (String)newModel.get("address"); + List overrides; + if (StringUtils.isNotEmpty(service)) { + overrides = overrideService.findByService(service); + } else if (StringUtils.isNotEmpty(application)) { + overrides = overrideService.findByApplication(application); + } else if (StringUtils.isNotEmpty(address)) { + overrides = overrideService.findByAddress(address); + } else { + overrides = overrideService.findAll(); + } + model.addAttribute("overrides", overrides); + return "governance/screen/overrides/index"; + } + + @RequestMapping("/{id}") + public String show(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response, + Model model) { + prepare(request, response, model, "show", "overrides"); + Override override = overrideService.findById(id); + + Map parameters = parseQueryString(override.getParams()); + + if (parameters.get(DEFAULT_MOCK_JSON_KEY) != null) { + String mock = URL.decode(parameters.get(DEFAULT_MOCK_JSON_KEY)); + String[] tokens = parseMock(mock); + model.addAttribute(FORM_DEFAULT_MOCK_METHOD_FORCE, tokens[0]); + model.addAttribute(FORM_DEFAULT_MOCK_METHOD_JSON, tokens[1]); + parameters.remove(DEFAULT_MOCK_JSON_KEY); + } + + Map method2Force = new LinkedHashMap(); + Map method2Json = new LinkedHashMap(); + + for (Iterator> iterator = parameters.entrySet().iterator(); iterator.hasNext(); ) { + Map.Entry e = iterator.next(); + String key = e.getKey(); + + if (key.endsWith(MOCK_JSON_KEY_POSTFIX)) { + String m = key.substring(0, key.length() - MOCK_JSON_KEY_POSTFIX.length()); + parseMock(m, e.getValue(), method2Force, method2Json); + iterator.remove(); + } + } + + model.addAttribute("methodForces", method2Force); + model.addAttribute("methodJsons", method2Json); + model.addAttribute("parameters", parameters); + model.addAttribute("override", override); + return "governance/screen/overrides/show"; + } + + @RequestMapping("/add") + public String add(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model,"add", "overrides"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String application = (String)newModel.get("app"); + String service = (String)newModel.get("service"); + List serviceList = new ArrayList(); + List applicationList = new ArrayList(); + if (StringUtils.isNotEmpty(application)) { + serviceList.addAll(providerService.findServicesByApplication(application)); + serviceList.addAll(consumerService.findServicesByApplication(application)); + model.addAttribute("serviceList", serviceList); + } else if (StringUtils.isNotEmpty(service)) { + applicationList.addAll(providerService.findApplicationsByServiceName(service)); + applicationList.addAll(consumerService.findApplicationsByServiceName(service)); + model.addAttribute("applicationList", applicationList); + } else { + serviceList.addAll(providerService.findServices()); + serviceList.addAll(consumerService.findServices()); + providerService.findServicesByApplication(application); + consumerService.findServicesByApplication(application); + } + model.addAttribute("serviceList", serviceList); + + if (StringUtils.isNotEmpty(service) && !service.contains("*")) { + model.addAttribute("methods", CollectionUtils.sort(new ArrayList(providerService.findMethodsByService(service)))); + } + return "governance/screen/overrides/add"; + } + + @RequestMapping("/{id}/edit") + public String edit(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, + Model model) { + prepare(request, response, model, "edit", "overrides"); + Override override = overrideService.findById(id); + + Map parameters = parseQueryString(override.getParams()); + + if (parameters.get(DEFAULT_MOCK_JSON_KEY) != null) { + String mock = URL.decode(parameters.get(DEFAULT_MOCK_JSON_KEY)); + String[] tokens = parseMock(mock); + model.addAttribute(FORM_DEFAULT_MOCK_METHOD_FORCE, tokens[0]); + model.addAttribute(FORM_DEFAULT_MOCK_METHOD_JSON, tokens[1]); + parameters.remove(DEFAULT_MOCK_JSON_KEY); + } + + Map method2Force = new LinkedHashMap(); + Map method2Json = new LinkedHashMap(); + + List methods = CollectionUtils.sort(new ArrayList(providerService.findMethodsByService(override.getService()))); + if (methods != null && methods.isEmpty()) { + for (String m : methods) { + parseMock(m, parameters.get(m + MOCK_JSON_KEY_POSTFIX), method2Force, method2Json); + parameters.remove(m + MOCK_JSON_KEY_POSTFIX); + } + } + for (Iterator> iterator = parameters.entrySet().iterator(); iterator.hasNext(); ) { + Map.Entry e = iterator.next(); + String key = e.getKey(); + + if (key.endsWith(MOCK_JSON_KEY_POSTFIX)) { + String m = key.substring(0, key.length() - MOCK_JSON_KEY_POSTFIX.length()); + parseMock(m, e.getValue(), method2Force, method2Json); + iterator.remove(); + } + } + + model.addAttribute("methods", methods); + model.addAttribute("methodForces", method2Force); + model.addAttribute("methodJsons", method2Json); + model.addAttribute("parameters", parameters); + model.addAttribute("override", override); + return "governance/screen/overrides/edit"; + } + + private void parseMock(String m, String mock, Map method2Force, Map method2Json) { + String[] tokens = parseMock(mock); + method2Force.put(m, tokens[0]); + method2Json.put(m, tokens[1]); + } + + private String[] parseMock(String mock) { + mock = URL.decode(mock); + String force; + if (mock.startsWith("force:")) { + force = "force"; + mock = mock.substring("force:".length()); + } else if (mock.startsWith("fail:")) { + force = "fail"; + mock = mock.substring("fail:".length()); + } else { + force = "fail"; + } + String[] tokens = new String[2]; + tokens[0] = force; + tokens[1] = mock; + return tokens; + } + + boolean catchParams(Override override, HttpServletRequest request, Model model) { + Map map = request.getParameterMap(); + String service = map.get("service")[0]; + if (service == null || service.trim().length() == 0) { + model.addAttribute("message", getMessage("service is blank!")); + return false; + } + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + return false; + } + + String defaultMockMethodForce = map.get(FORM_DEFAULT_MOCK_METHOD_FORCE)[0]; + String defaultMockMethodJson = map.get(FORM_DEFAULT_MOCK_METHOD_JSON)[0]; + + Map override2Value = new HashMap(); + Map method2Json = new HashMap(); + + for (Map.Entry param : map.entrySet()) { + String key = param.getKey().trim(); + if(param.getValue().length != 1) continue;; + + String value = param.getValue()[0]; + + if (key.startsWith(FORM_OVERRIDE_KEY) && value != null && value.trim().length() > 0) { + String index = key.substring(FORM_OVERRIDE_KEY.length()); + String overrideValue = map.get(FORM_OVERRIDE_VALUE + index)[0]; + if (overrideValue != null && overrideValue.trim().length() > 0) { + override2Value.put(value.trim(), overrideValue.trim()); + } + } + + if (key.startsWith(FORM_ORIGINAL_METHOD_PREFIX) && value != null && value.trim().length() > 0) { + String method = key.substring(FORM_ORIGINAL_METHOD_PREFIX.length()); + String force = map.get(FORM_ORIGINAL_METHOD_FORCE_PREFIX + method)[0]; + method2Json.put(method, force + ":" + value.trim()); + } + + if (key.startsWith(FORM_DYNAMIC_METHOD_NAME_PREFIX) && value != null && value.trim().length() > 0) { + String index = key.substring(FORM_DYNAMIC_METHOD_NAME_PREFIX.length()); + String force = map.get(FORM_DYNAMIC_METHOD_FORCE_PREFIX + index)[0]; + String json = map.get(FORM_DYNAMIC_METHOD_JSON_PREFIX + index)[0]; + + if (json != null && json.trim().length() > 0) { + method2Json.put(value.trim(), force + ":" + json.trim()); + } + } + } + + StringBuilder paramters = new StringBuilder(); + boolean isFirst = true; + if (defaultMockMethodJson != null && defaultMockMethodJson.trim().length() > 0) { + paramters.append("mock=").append(URL.encode(defaultMockMethodForce + ":" + defaultMockMethodJson.trim())); + isFirst = false; + } + for (Map.Entry e : method2Json.entrySet()) { + if (isFirst) isFirst = false; + else paramters.append("&"); + + paramters.append(e.getKey()).append(MOCK_JSON_KEY_POSTFIX).append("=").append(URL.encode(e.getValue())); + } + for (Map.Entry e : override2Value.entrySet()) { + if (isFirst) isFirst = false; + else paramters.append("&"); + + paramters.append(e.getKey()).append("=").append(URL.encode(e.getValue())); + } + + String p = paramters.toString(); + if (p.trim().length() == 0) { + model.addAttribute("message", getMessage("Please enter Parameters!")); + return false; + } + + override.setParams(p); + return true; + } + + + @RequestMapping("/create") + public String create(Override override, HttpServletRequest request, + HttpServletResponse response, Model model) { + prepare(request,response,model,"update", "overrides"); + boolean success = true; + if (!catchParams(override, request, model)) { + success =false; + } else { + overrideService.saveOverride(override); + } + + model.addAttribute("success", success); + model.addAttribute("redirect", "../overrides"); + return "governance/screen/redirect"; + } + + @RequestMapping("/update") + public String update(Override override, HttpServletRequest request, + HttpServletResponse response, Model model) { + prepare(request, response, model, "update", "overrides"); + boolean succcess = true; + Override o = overrideService.findById(override.getId()); + override.setService(o.getService()); + override.setAddress(o.getAddress()); + override.setApplication(o.getApplication()); + + if (!catchParams(override, request, model)) { + succcess = false; + } else { + overrideService.updateOverride(override); + } + + model.addAttribute("success", succcess); + model.addAttribute("redirect", "../overrides"); + return "governance/screen/redirect"; + + } + + @RequestMapping("/{ids}/delete") + public String delete(@PathVariable("ids") Long[] ids, HttpServletRequest request, + HttpServletResponse response, Model model) { + prepare(request, response, model, "delete", "overrides"); + for (Long id : ids) { + overrideService.deleteOverride(id); + } + + model.addAttribute("success", true); + model.addAttribute("redirect", "../../overrides"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/enable") + public String enable(@PathVariable("ids") Long[] ids, HttpServletRequest request, + HttpServletResponse response, Model model) { + prepare(request, response, model, "enable", "overrides"); + boolean success = true; + for (Long id : ids) { + Override override = overrideService.findById(id); + if (override == null) { + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../overrides"); + return "governance/screen/redirect"; + } else { + if (!super.currentUser.hasServicePrivilege(override.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", override.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../overrides"); + return "governance/screen/redirect"; + } + } + } + + for (Long id : ids) { + overrideService.enableOverride(id); + } + + model.addAttribute("success", success); + model.addAttribute("redirect", "../../overrides"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/disable") + public String disable(@PathVariable("ids") Long[] ids, HttpServletRequest request, + HttpServletResponse response, Model model) { + prepare(request, response, model, "disable", "overrides"); + boolean success = true; + for (Long id : ids) { + Override override = overrideService.findById(id); + if (override == null) { + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../overrides"); + return "governance/screen/redirect"; + } else { + if (!super.currentUser.hasServicePrivilege(override.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", override.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../overrides"); + return "governance/screen/redirect"; + } + } + } + + for (Long id : ids) { + overrideService.disableOverride(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../overrides"); + return "governance/screen/redirect"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/OwnersController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/OwnersController.java new file mode 100644 index 0000000..0bd75a0 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/OwnersController.java @@ -0,0 +1,132 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubboadmin.governance.service.OwnerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Owner; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * ProvidersController. URI: /services/$service/owners + * + */ +@Controller +@RequestMapping("/governance/owners") +public class OwnersController extends BaseController { + + @Autowired + private OwnerService ownerService; + + @Autowired + private ProviderService providerService; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "owners"); + List owners; + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + if (service != null && service.length() > 0) { + owners = ownerService.findByService(service); + } else { + owners = ownerService.findAll(); + } + model.addAttribute("owners", owners); + return "governance/screen/owners/index"; + } + + @RequestMapping("/add") + public String add(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "add", "owners"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + if (service == null || service.length() == 0) { + List serviceList = Tool.sortSimpleName(new ArrayList(providerService.findServices())); + model.addAttribute("serviceList", serviceList); + } + return "governance/screen/owners/add"; + } + + @RequestMapping(value = "/create", method = RequestMethod.POST) //post + public String create(Owner owner, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "create", "owners"); + String service = owner.getService(); + String username = owner.getUsername(); + if (service == null || service.length() == 0 + || username == null || username.length() == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../owners"); + return "governance/screen/redirect"; + } + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + model.addAttribute("success", false); + model.addAttribute("redirect", "../owners"); + return "governance/screen/redirect"; + } + ownerService.saveOwner(owner); + model.addAttribute("success", true); + model.addAttribute("redirect", "../owners"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/delete") + public String delete(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "delete", "owners"); + + String service = request.getParameter("service"); + String username = request.getParameter("username"); + Owner owner = new Owner(); + owner.setService(service); + owner.setUsername(username); + if (service == null || service.length() == 0 + || username == null || username.length() == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../owners"); + return "governance/screen/redirect"; + } + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../owners"); + return "governance/screen/redirect"; + } + ownerService.deleteOwner(owner); + model.addAttribute("success", true); + model.addAttribute("redirect", "../../owners"); + return "governance/screen/redirect"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ProvidersController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ProvidersController.java new file mode 100644 index 0000000..0344073 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ProvidersController.java @@ -0,0 +1,507 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.route.OverrideUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + *

ProvidersController.

+ * URI:
+ * GET /providers, show all providers
+ * GET /providers/add, show web form for add a static provider
+ * POST /provider/create, create a static provider, save form
+ * GET /providers/$id, show provider details
+ * GET /providers/$id/edit, web form for edit provider
+ * POST /providers/$id, update provider, save form
+ * GET /providers/$id/delete, delete a provider
+ * GET /providers/$id/tostatic, transfer to static
+ * GET /providers/$id/todynamic, transfer to dynamic
+ * GET /providers/$id/enable, enable a provider
+ * GET /providers/$id/disable, disable a provider
+ * GET /providers/$id/reconnect, reconnect
+ * GET /providers/$id/recover, recover
+ *
+ * GET /services/$service/providers, show all provider of a specific service
+ * GET /services/$service/providers/add, show web form for add a static provider
+ * POST /services/$service/providers, save a static provider
+ * GET /services/$service/providers/$id, show provider details
+ * GET /services/$service/providers/$id/edit, show web form for edit provider
+ * POST /services/$service/providers/$id, save changes of provider
+ * GET /services/$service/providers/$id/delete, delete provider
+ * GET /services/$service/providers/$id/tostatic, transfer to static
+ * GET /services/$service/providers/$id/todynamic, transfer to dynamic
+ * GET /services/$service/providers/$id/enable, enable
+ * GET /services/$service/providers/$id/disable, diable
+ * GET /services/$service/providers/$id/reconnect, reconnect
+ * GET /services/$service/providers/$id/recover, recover
+ * + */ +@Controller +@RequestMapping("/governance/providers") +public class ProvidersController extends BaseController { + + @Autowired + private ProviderService providerService; + + @Autowired + private OverrideService overrideService; + + + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + + + prepare(request, response, model, "index", "providers"); + + String value = ""; + String separators = "...."; + + List providers = null; + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + String address = (String)newModel.get("address"); + String application = (String)newModel.get("app"); + + // service + if (service != null && service.length() > 0) { + providers = providerService.findByService(service); + + value = service + separators + request.getRequestURI(); + } + // address + else if (address != null && address.length() > 0) { + providers = providerService.findByAddress(address); + + value = address + separators + request.getRequestURI(); + } + // application + else if (application != null && application.length() > 0) { + providers = providerService.findByApplication(application); + + value = application + separators + request.getRequestURI(); + } + // all + else { + providers = providerService.findAll(); + } + + model.addAttribute("providers", providers); + model.addAttribute("serviceAppMap", getServiceAppMap(providers)); + + // record search history to cookies + try { + setSearchHistroy(value, request, response); + } catch (Exception e) { + // + } + return "governance/screen/providers/index"; + } + + /** + * + * Calculate the application list corresponding to each service, to facilitate the "repeat" prompt on service page + * @param providers app services + */ + private Map> getServiceAppMap(List providers) { + Map> serviceAppMap = new HashMap>(); + if (providers != null && providers.size() > 0) { + for (Provider provider : providers) { + Set appSet; + String service = provider.getService(); + if (serviceAppMap.get(service) == null) { + appSet = new HashSet(); + } else { + appSet = serviceAppMap.get(service); + } + appSet.add(provider.getApplication()); + serviceAppMap.put(service, appSet); + } + } + return serviceAppMap; + } + + /** + * Record search history to cookies, steps: + * Check whether the added record exists in the cookie, and if so, update the list order; if it does not exist, insert it to the front + * + * @param value + */ + private void setSearchHistroy(String value, HttpServletRequest request, HttpServletResponse response) { + //System.out.println("add new cookie: " + value); + // Analyze existing cookies + String separatorsB = "\\.\\.\\.\\.\\.\\."; + String newCookiev = value; + Cookie[] cookies = request.getCookies(); + for (Cookie c : cookies) { + if (c.getName().equals("HISTORY")) { + String cookiev = c.getValue(); + String[] values = cookiev.split(separatorsB); + int count = 1; + for (String v : values) { + if (count <= 10) { + if (!value.equals(v)) { + newCookiev = newCookiev + separatorsB + v; + //System.out.println("new cookie: " + newCookiev); + } + } + count++; + } + break; + } + } + + Cookie _cookie = new Cookie("HISTORY", newCookiev); + _cookie.setMaxAge(60 * 60 * 24 * 7); // Set the cookie's lifetime to 30 minutes + _cookie.setPath("/"); + response.addCookie(_cookie); // Write to client hard disk + } + + @RequestMapping("/{id}") + public String show(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "show", "providers"); + Provider provider = providerService.findProvider(id); + if (provider != null && provider.isDynamic()) { + List overrides = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress()); + OverrideUtils.setProviderOverrides(provider, overrides); + } + model.addAttribute("provider", provider); + return "governance/screen/providers/show"; + + } + + /** + * Load new service page, get all the service name + */ + + @RequestMapping("/{id}/add") + public String add(@PathVariable("id") Long id, + HttpServletRequest request, HttpServletResponse response, Model model) { + model.addAttribute("id", id); + return add(request, response, model); + } + + @RequestMapping("/add") + public String add(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "add", "providers"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + Long id = (Long)newModel.get("id"); + String service = (String)newModel.get("service"); + if (service == null) { + List serviceList = Tool.sortSimpleName(new ArrayList(providerService.findServices())); + model.addAttribute("serviceList", serviceList); + } + if (id != null) { + Provider p = providerService.findProvider(id); + if (p != null) { + model.addAttribute("provider", p); + String parameters = p.getParameters(); + if (parameters != null && parameters.length() > 0) { + Map map = StringUtils.parseQueryString(parameters); + map.put("timestamp", String.valueOf(System.currentTimeMillis())); + map.remove("pid"); + p.setParameters(StringUtils.toQueryString(map)); + } + } + } + return "governance/screen/providers/add"; + } + + @RequestMapping("/{id}/edit") + public String edit(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model,"edit", "providers"); + Provider provider = providerService.findProvider(id); + if (provider != null && provider.isDynamic()) { + List overrides = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress()); + OverrideUtils.setProviderOverrides(provider, overrides); + } + model.addAttribute("provider", provider); + return "governance/screen/providers/edit"; + } + + @RequestMapping(value = "/create", method = RequestMethod.POST) //post + public String create(@ModelAttribute Provider provider, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model,"create" ,"providers"); + boolean success = true; + String service = provider.getService(); + if (service == null) { + service = (String)((BindingAwareModelMap)model).get("service"); + provider.setService(service); + } + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../providers"); + return "governance/screen/redirect"; + } + if (provider.getParameters() == null) { + String url = provider.getUrl(); + if (url != null) { + int i = url.indexOf('?'); + if (i > 0) { + provider.setUrl(url.substring(0, i)); + provider.setParameters(url.substring(i + 1)); + } + } + } + provider.setDynamic(false); // Provider add through web page must be static + providerService.create(provider); + model.addAttribute("success", success); + model.addAttribute("redirect", "../providers"); + return "governance/screen/redirect"; + } + + @RequestMapping(value = "/update", method = RequestMethod.POST) //post + public String update(@ModelAttribute Provider newProvider, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "update", "providers"); + boolean success = true; + Long id = newProvider.getId(); + String parameters = newProvider.getParameters(); + Provider provider = providerService.findProvider(id); + if (provider == null) { + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../providers"); + return "governance/screen/redirect"; + } + String service = provider.getService(); + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../providers"); + return "governance/screen/redirect"; + } + Map oldMap = StringUtils.parseQueryString(provider.getParameters()); + Map newMap = StringUtils.parseQueryString(parameters); + for (Map.Entry entry : oldMap.entrySet()) { + if (entry.getValue().equals(newMap.get(entry.getKey()))) { + newMap.remove(entry.getKey()); + } + } + if (provider.isDynamic()) { + String address = provider.getAddress(); + List overrides = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress()); + OverrideUtils.setProviderOverrides(provider, overrides); + Override override = provider.getOverride(); + if (override != null) { + if (newMap.size() > 0) { + override.setParams(StringUtils.toQueryString(newMap)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.updateOverride(override); + } else { + overrideService.deleteOverride(override.getId()); + } + } else { + override = new Override(); + override.setService(service); + override.setAddress(address); + override.setParams(StringUtils.toQueryString(newMap)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.saveOverride(override); + } + } else { + provider.setParameters(parameters); + providerService.updateProvider(provider); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../providers"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/delete") + public String delete(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "delete", "providers"); + boolean success = true; + for (Long id : ids) { + Provider provider = providerService.findProvider(id); + if (provider == null) { + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } else if (provider.isDynamic()) { + model.addAttribute("message", getMessage("CanNotDeleteDynamicData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } else if (!super.currentUser.hasServicePrivilege(provider.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", provider.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + } + for (Long id : ids) { + providerService.deleteStaticProvider(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/enable") + public String enable(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "enable", "providers"); + boolean success = true; + Map id2Provider = new HashMap(); + for (Long id : ids) { + Provider provider = providerService.findProvider(id); + if (provider == null) { + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } else if (!super.currentUser.hasServicePrivilege(provider.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", provider.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + id2Provider.put(id, provider); + } + for (Long id : ids) { + providerService.enableProvider(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/disable") + public String disable(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "disable", "providers"); + boolean success = true; + for (Long id : ids) { + Provider provider = providerService.findProvider(id); + if (provider == null) { + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } else if (!super.currentUser.hasServicePrivilege(provider.getService())) { + success = false; + model.addAttribute("message", getMessage("HaveNoServicePrivilege", provider.getService())); + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + } + for (Long id : ids) { + providerService.disableProvider(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/doubling") + public String doubling(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "doubling","providers"); + boolean success = true; + for (Long id : ids) { + Provider provider = providerService.findProvider(id); + if (provider == null) { + success = false; + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } else if (!super.currentUser.hasServicePrivilege(provider.getService())) { + success = false; + model.addAttribute("message", getMessage("HaveNoServicePrivilege", provider.getService())); + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + } + for (Long id : ids) { + providerService.doublingProvider(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{ids}/halving") + public String halving(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "halving","providers"); + boolean success = true; + for (Long id : ids) { + Provider provider = providerService.findProvider(id); + if (provider == null) { + success = false; + model.addAttribute("message", getMessage("NoSuchOperationData", id)); + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } else if (!super.currentUser.hasServicePrivilege(provider.getService())) { + success = false; + model.addAttribute("message", getMessage("HaveNoServicePrivilege", provider.getService())); + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + } + for (Long id : ids) { + providerService.halvingProvider(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../providers"); + return "governance/screen/redirect"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/RoutesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/RoutesController.java new file mode 100644 index 0000000..0f95a3e --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/RoutesController.java @@ -0,0 +1,644 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.utils.CollectionUtils; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.OwnerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.governance.service.RouteService; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.domain.Route; +import com.alibaba.dubboadmin.registry.common.route.ParseUtils; +import com.alibaba.dubboadmin.registry.common.route.RouteRule; +import com.alibaba.dubboadmin.registry.common.route.RouteUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * ProvidersController. + * URI: /services/$service/routes + * + */ +@Controller +@RequestMapping("/governance/routes") +public class RoutesController extends BaseController { + + private static final int MAX_RULE_LENGTH = 1000; + static String[][] when_names = { + {"method", "method", "unmethod"}, + {"consumer.application", "consumerApplication", "unconsumerApplication"}, + {"consumer.cluster", "consumerCluster", "unconsumerCluster"}, + {"consumer.host", "consumerHost", "unconsumerHost"}, + {"consumer.version", "consumerVersion", "unconsumerVersion"}, + {"consumer.group", "consumerGroup", "unconsumerGroup"}, + }; + static String[][] then_names = { + {"provider.application", "providerApplication", "unproviderApplication"}, + {"provider.cluster", "providerCluster", "unproviderCluster"}, // Must check if Cluster exists + {"provider.host", "providerHost", "unproviderHost"}, + {"provider.protocol", "providerProtocol", "unproviderProtocol"}, + {"provider.port", "providerPort", "unproviderPort"}, + {"provider.version", "providerVersion", "unproviderVersion"}, + {"provider.group", "providerGroup", "unproviderGroup"} + }; + @Autowired + private RouteService routeService; + @Autowired + private ProviderService providerService; + @Autowired + private ConsumerService consumerService; + + static void checkService(String service) { + if (service.contains(",")) throw new IllegalStateException("service(" + service + ") contain illegale ','"); + + String interfaceName = service; + int gi = interfaceName.indexOf("/"); + if (gi != -1) interfaceName = interfaceName.substring(gi + 1); + int vi = interfaceName.indexOf(':'); + if (vi != -1) interfaceName = interfaceName.substring(0, vi); + + if (interfaceName.indexOf('*') != -1 && interfaceName.indexOf('*') != interfaceName.length() - 1) { + throw new IllegalStateException("service(" + service + ") only allow 1 *, and must be last char!"); + } + } + + /** + * add owners related with service + * + * @param usernames the usernames to add + * @param serviceName no wildcards + */ + public static void addOwnersOfService(Set usernames, String serviceName, + OwnerService ownerDAO) { + List serviceNamePatterns = ownerDAO.findAllServiceNames(); + for (String p : serviceNamePatterns) { + if (ParseUtils.isMatchGlobPattern(p, serviceName)) { + List list = ownerDAO.findUsernamesByServiceName(p); + usernames.addAll(list); + } + } + } + + /** + * add owners related with service pattern + * + * @param usernames the usernames to add + * @param serviceNamePattern service pattern, Glob + */ + public static void addOwnersOfServicePattern(Set usernames, String serviceNamePattern, + OwnerService ownerDAO) { + List serviceNamePatterns = ownerDAO.findAllServiceNames(); + for (String p : serviceNamePatterns) { + if (ParseUtils.hasIntersection(p, serviceNamePattern)) { + List list = ownerDAO.findUsernamesByServiceName(p); + usernames.addAll(list); + } + } + } + + /** + * Routing module home page + * + */ + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "routes"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String address = (String)newModel.get("address"); + String service = (String)newModel.get("service"); + address = Tool.getIP(address); + List routes; + if (service != null && service.length() > 0 + && address != null && address.length() > 0) { + routes = routeService.findByServiceAndAddress(service, address); + } else if (service != null && service.length() > 0) { + routes = routeService.findByService(service); + } else if (address != null && address.length() > 0) { + routes = routeService.findByAddress(address); + } else { + routes = routeService.findAll(); + } + model.addAttribute("routes", routes); + return "governance/screen/routes/index"; + } + + /** + * Display routing details + * + */ + @RequestMapping("/{id}") + public String show(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + try { + prepare(request, response, model, "show", "routes"); + Route route = routeService.findRoute(id); + + if (route == null) { + throw new IllegalArgumentException("The route is not existed."); + } + if (route.getService() != null && !route.getService().isEmpty()) { + model.addAttribute("service", route.getService()); + } + + RouteRule routeRule = RouteRule.parse(route); + + @SuppressWarnings("unchecked") + Map[] paramArray = new Map[]{ + routeRule.getWhenCondition(), routeRule.getThenCondition()}; + String[][][] namesArray = new String[][][]{when_names, then_names}; + + for (int i = 0; i < paramArray.length; ++i) { + Map param = paramArray[i]; + String[][] names = namesArray[i]; + for (String[] name : names) { + RouteRule.MatchPair matchPair = param.get(name[0]); + if (matchPair == null) { + continue; + } + + if (!matchPair.getMatches().isEmpty()) { + String m = RouteRule.join(matchPair.getMatches()); + model.addAttribute(name[1], m); + } + if (!matchPair.getUnmatches().isEmpty()) { + String u = RouteRule.join(matchPair.getUnmatches()); + model.addAttribute(name[2], u); + } + } + } + model.addAttribute("route", route); + model.addAttribute("methods", CollectionUtils.sort(new ArrayList(providerService.findMethodsByService(route.getService())))); + } catch (ParseException e) { + e.printStackTrace(); + } + return "governance/screen/routes/show"; + } + + /** + * Load new route page + * + */ + @RequestMapping("/add") + public String add(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "add", "routes"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + if (service != null && service.length() > 0 && !service.contains("*")) { + model.addAttribute("service", service); + model.addAttribute("methods", CollectionUtils.sort(new ArrayList(providerService.findMethodsByService(service)))); + } else { + List serviceList = Tool.sortSimpleName(new ArrayList(providerService.findServices())); + model.addAttribute("serviceList", serviceList); + } + + //if (input != null) model.addAttribute("input", input); + return "governance/screen/routes/add"; + } + + /** + * Load modified routing page + * + */ + + @RequestMapping("/{id}/edit") + public String edit(@PathVariable("id") Long id, @RequestParam(required = false) String service, + @RequestParam(required = false) String input, + HttpServletRequest request, HttpServletResponse response, Model model) { + + prepare(request, response, model, "edit", "routes"); + if (service != null && service.length() > 0 && !service.contains("*")) { + model.addAttribute("service", service); + model.addAttribute("methods", CollectionUtils.sort(new ArrayList(providerService.findMethodsByService(service)))); + } else { + List serviceList = Tool.sortSimpleName(new ArrayList(providerService.findServices())); + model.addAttribute("serviceList", serviceList); + } + + if (input != null) model.addAttribute("input", input); + Route route = routeService.findRoute(id); + + if (route == null) { + throw new IllegalArgumentException("The route is not existed."); + } + if (route.getService() != null && !route.getService().isEmpty()) { + model.addAttribute("service", route.getService()); + } + + RouteRule routeRule = null; + try { + routeRule = RouteRule.parse(route); + } catch (ParseException e) { + e.printStackTrace(); + } + + @SuppressWarnings("unchecked") + Map[] paramArray = new Map[]{ + routeRule.getWhenCondition(), routeRule.getThenCondition()}; + String[][][] namesArray = new String[][][]{when_names, then_names}; + + for (int i = 0; i < paramArray.length; ++i) { + Map param = paramArray[i]; + String[][] names = namesArray[i]; + for (String[] name : names) { + RouteRule.MatchPair matchPair = param.get(name[0]); + if (matchPair == null) { + continue; + } + + if (!matchPair.getMatches().isEmpty()) { + String m = RouteRule.join(matchPair.getMatches()); + model.addAttribute(name[1], m); + } + if (!matchPair.getUnmatches().isEmpty()) { + String u = RouteRule.join(matchPair.getUnmatches()); + model.addAttribute(name[2], u); + } + } + } + model.addAttribute("route", route); + model.addAttribute("methods", CollectionUtils.sort(new ArrayList(providerService.findMethodsByService(route.getService())))); + + return "governance/screen/routes/edit"; + } + + /** + * Save the routing information to the database + * + * @return + */ + + @RequestMapping("/create") + public String create(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "update", "routes"); + boolean success = true; + + String name = request.getParameter("name"); + String service = request.getParameter("service"); + if (StringUtils.isNotEmpty(service) + && StringUtils.isNotEmpty(name)) { + checkService(service); + + Map when_name2valueList = new HashMap(); + Map notWhen_name2valueList = new HashMap(); + for (String[] names : when_names) { + when_name2valueList.put(names[0], request.getParameter(names[1])); + notWhen_name2valueList.put(names[0], request.getParameter(names[2])); // TODO. We should guarantee value is never null in here, will be supported later + } + + Map then_name2valueList = new HashMap(); + Map notThen_name2valueList = new HashMap(); + for (String[] names : then_names) { + then_name2valueList.put(names[0], request.getParameter(names[1])); + notThen_name2valueList.put(names[0], request.getParameter(names[2])); + } + + RouteRule routeRule = RouteRule.createFromNameAndValueListString( + when_name2valueList, notWhen_name2valueList, + then_name2valueList, notThen_name2valueList); + + if (routeRule.getThenCondition().isEmpty()) { + model.addAttribute("message", getMessage("Add route error! then is empty.")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../routes"); + return "governance/screen/redirect"; + } + + String matchRule = routeRule.getWhenConditionString(); + String filterRule = routeRule.getThenConditionString(); + + // Limit the length of the expression + if (matchRule.length() > MAX_RULE_LENGTH) { + model.addAttribute("message", getMessage("When rule is too long!")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../routes"); + return "governance/screen/redirect"; + } + if (filterRule.length() > MAX_RULE_LENGTH) { + model.addAttribute("message", getMessage("Then rule is too long!")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../routes"); + return "governance/screen/redirect"; + } + + Route route = new Route(); + route.setService(service); + route.setName(name); + route.setUsername(request.getParameter("operator")); + route.setOperator(request.getParameter("operatorAddress")); + route.setRule(routeRule.toString()); + if (StringUtils.isNotEmpty(request.getParameter("priority"))) { + route.setPriority(Integer.parseInt(request.getParameter("priority"))); + } + routeService.createRoute(route); + + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../routes"); + return "governance/screen/redirect"; + } + + /** + * Save the update data to the database + * + * @return + */ + @RequestMapping("/{id}/update") + public String update(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "update", "routes"); + boolean success = true; + String idStr = String.valueOf(id); + if (idStr != null && idStr.length() > 0) { + String[] blacks = request.getParameterMap().get("black"); + //String[] blacks = (String[]) context.get("black"); + boolean black = false; + if (blacks != null && blacks.length > 0) { + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + + Route oldRoute = routeService.findRoute(Long.valueOf(idStr)); + if (null == oldRoute) { + model.addAttribute("message", getMessage("NoSuchRecord")); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + // Check parameters, patchwork rule + if (StringUtils.isNotEmpty((String) request.getParameter("name"))) { + String service = oldRoute.getService(); + if (((BindingAwareModelMap)model).get("operator") == null) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + + Map when_name2valueList = new HashMap(); + Map notWhen_name2valueList = new HashMap(); + for (String[] names : when_names) { + when_name2valueList.put(names[0], (String) request.getParameter(names[1])); + notWhen_name2valueList.put(names[0], (String) request.getParameter(names[2])); + } + + Map then_name2valueList = new HashMap(); + Map notThen_name2valueList = new HashMap(); + for (String[] names : then_names) { + then_name2valueList.put(names[0], (String) request.getParameter(names[1])); + notThen_name2valueList.put(names[0], (String) request.getParameter(names[2])); + } + + RouteRule routeRule = RouteRule.createFromNameAndValueListString( + when_name2valueList, notWhen_name2valueList, + then_name2valueList, notThen_name2valueList); + + RouteRule result = null; + if (black) { + RouteRule.MatchPair matchPair = routeRule.getThenCondition().get("black"); + Map then = null; + if (null == matchPair) { + matchPair = new RouteRule.MatchPair(); + then = new HashMap(); + then.put("black", matchPair); + } else { + matchPair.getMatches().clear(); + } + matchPair.getMatches().add(String.valueOf(black)); + result = RouteRule.copyWithReplace(routeRule, null, then); + } + + if (result == null) { + result = routeRule; + } + + if (result.getThenCondition().isEmpty()) { + model.addAttribute("message", getMessage("Update route error! then is empty.")); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + + String matchRule = result.getWhenConditionString(); + String filterRule = result.getThenConditionString(); + + // Limit the length of the expression + if (matchRule.length() > MAX_RULE_LENGTH) { + model.addAttribute("message", getMessage("When rule is too long!")); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + if (filterRule.length() > MAX_RULE_LENGTH) { + model.addAttribute("message", getMessage("Then rule is too long!")); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + + int priority = 0; + if (StringUtils.isNotEmpty((String) request.getParameter("priority"))) { + priority = Integer.parseInt((String) request.getParameter("priority")); + } + + Route route = new Route(); + route.setRule(result.toString()); + route.setService(service); + route.setPriority(priority); + route.setName((String) request.getParameter("name")); + route.setUsername((String) request.getParameter("operator")); + route.setOperator((String) request.getParameter("operatorAddress")); + route.setId(Long.valueOf(idStr)); + route.setPriority(Integer.parseInt((String) request.getParameter("priority"))); + route.setEnabled(oldRoute.isEnabled()); + routeService.updateRoute(route); + + Set usernames = new HashSet(); + usernames.add((String) request.getParameter("operator")); + usernames.add(route.getUsername()); + //RelateUserUtils.addOwnersOfService(usernames, route.getService(), ownerDAO); + + Map params = new HashMap(); + params.put("action", "update"); + params.put("route", route); + + } else { + model.addAttribute("message", getMessage("MissRequestParameters", "name")); + } + } else { + model.addAttribute("message", getMessage("MissRequestParameters", "id")); + } + + model.addAttribute("success", success); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + + /** + * Remove the route rule for the specified ID + * + * @param ids + * @return + */ + @RequestMapping("/{ids}/delete") + public String delete(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, + Model model) { + prepare(request, response, model, "delete", "routes"); + for (Long id : ids) { + routeService.deleteRoute(id); + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + + } + + /** + * Enable the specified route ID rules (batch processing) + * + * @param ids + * @return + */ + @RequestMapping("/{ids}/enable") + public String enable(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, + Model model) { + prepare(request, response, model, "enable", "routes"); + for (Long id : ids) { + routeService.enableRoute(id); + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + + /** + * Disabling route rules for specified IDs (can be batch processed) + * + * @param ids + * @return + */ + @RequestMapping("/{ids}/disable") + public String disable(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, + Model model) { + prepare(request, response, model, "disable", "routes"); + for (Long id : ids) { + routeService.disableRoute(id); + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../../routes"); + return "governance/screen/redirect"; + } + + /** + * Choose consumers + * + * @param context + */ + public void routeselect(Map context) { + long rid = Long.valueOf((String) context.get("id")); + context.put("id", rid); + + Route route = routeService.findRoute(rid); + if (route == null) { + throw new IllegalStateException("Route(id=" + rid + ") is not existed!"); + } + + context.put("route", route); + // retrieve data + List consumers = consumerService.findByService(route.getService()); + context.put("consumers", consumers); + + Map matchRoute = new HashMap(); + for (Consumer c : consumers) { + matchRoute.put(c.getAddress(), RouteUtils.matchRoute(c.getAddress(), null, route, null)); + } + context.put("matchRoute", matchRoute); + } + + public void preview(Map context) throws Exception { + String rid = (String) context.get("id"); + String consumerid = (String) context.get("cid"); + + + if (StringUtils.isEmpty(rid)) { + context.put("message", getMessage("MissRequestParameters", "id")); + } + + Map serviceUrls = new HashMap(); + Route route = routeService.findRoute(Long.valueOf(rid)); + if (null == route) { + context.put("message", getMessage("NoSuchRecord")); + } + List providers = providerService.findByService(route.getService()); + if (providers != null) { + for (Provider p : providers) { + serviceUrls.put(p.getUrl(), p.getParameters()); + } + } + if (StringUtils.isNotEmpty(consumerid)) { + Consumer consumer = consumerService.findConsumer(Long.valueOf(consumerid)); + if (null == consumer) { + context.put("message", getMessage("NoSuchRecord")); + } + Map result = RouteUtils.previewRoute(consumer.getService(), consumer.getAddress(), consumer.getParameters(), serviceUrls, + route, null, null); + context.put("route", route); + context.put("consumer", consumer); + context.put("result", result); + } else { + String address = (String) context.get("address"); + String service = (String) context.get("service"); + + Map result = RouteUtils.previewRoute(service, address, null, serviceUrls, + route, null, null); + context.put("route", route); + + Consumer consumer = new Consumer(); + consumer.setService(service); + consumer.setAddress(address); + context.put("consumer", consumer); + context.put("result", result); + } + + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ServicesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ServicesController.java new file mode 100644 index 0000000..8d3f181 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/ServicesController.java @@ -0,0 +1,236 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.route.OverrideUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * ProvidersController. URI: /services/$service/providers /addresses/$address/services /application/$application/services + * + */ +@Controller +@RequestMapping("/governance/services") +public class ServicesController extends BaseController { + + @Autowired + private ProviderService providerService; + + @Autowired + private ConsumerService consumerService; + + @Autowired + private OverrideService overrideService; + + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "services"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + String application = (String)newModel.get("app"); + String address = (String)newModel.get("address"); + String keyword = request.getParameter("keyword"); + + if (service == null + && application == null + && address == null) { + model.addAttribute("service", "*"); + } + + List providerServices = null; + List consumerServices = null; + List overrides = null; + if (application != null && application.length() > 0) { + model.addAttribute("app", application); + providerServices = providerService.findServicesByApplication(application); + consumerServices = consumerService.findServicesByApplication(application); + overrides = overrideService.findByApplication(application); + } else if (address != null && address.length() > 0) { + providerServices = providerService.findServicesByAddress(address); + consumerServices = consumerService.findServicesByAddress(address); + overrides = overrideService.findByAddress(Tool.getIP(address)); + } else { + providerServices = providerService.findServices(); + consumerServices = consumerService.findServices(); + overrides = overrideService.findAll(); + } + + Set services = new TreeSet(); + if (providerServices != null) { + services.addAll(providerServices); + } + if (consumerServices != null) { + services.addAll(consumerServices); + } + + Map> service2Overrides = new HashMap>(); + if (overrides != null && overrides.size() > 0 + && services != null && services.size() > 0) { + for (String s : services) { + if (overrides != null && overrides.size() > 0) { + for (Override override : overrides) { + List serOverrides = new ArrayList(); + if (override.isMatch(s, address, application)) { + serOverrides.add(override); + } + Collections.sort(serOverrides, OverrideUtils.OVERRIDE_COMPARATOR); + service2Overrides.put(s, serOverrides); + } + } + } + } + + model.addAttribute("providerServices", providerServices); + model.addAttribute("consumerServices", consumerServices); + model.addAttribute("services", services); + model.addAttribute("overrides", service2Overrides); + + + if (keyword != null && !"*".equals(keyword)) { + keyword = keyword.toLowerCase(); + Set newList = new HashSet(); + Set newProviders = new HashSet(); + Set newConsumers = new HashSet(); + + for (String o : services) { + if (o.toLowerCase().toLowerCase().indexOf(keyword) != -1) { + newList.add(o); + } + if (o.toLowerCase().toLowerCase().equals(keyword.toLowerCase())) { + service = o; + } + } + for (String o : providerServices) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newProviders.add(o); + } + } + for (String o : consumerServices) { + if (o.toLowerCase().indexOf(keyword) != -1) { + newConsumers.add(o); + } + } + model.addAttribute("services", newList); + model.addAttribute("keyword", keyword); + model.addAttribute("providerServices", newProviders); + model.addAttribute("consumerServices", newConsumers); + } + return "governance/screen/services/index"; + } + + + @RequestMapping("/{ids}/shield") + public String shield(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "force:return null", "shield", request, response, model); + } + + @RequestMapping("/{ids}/tolerant") + public String tolerant(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "fail:return null", "tolerant", request, response, model); + } + + @RequestMapping("/{ids}/recover") + public String recover(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + return mock(ids, "", "recover", request, response, model); + } + + private String mock(Long[] ids, String mock, String methodName, HttpServletRequest request, + HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, methodName, "services"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String services = (String) newModel.get("service"); + String application = (String) newModel.get("app"); + + if (services == null || services.length() == 0 + || application == null || application.length() == 0) { + model.addAttribute("message", getMessage("NoSuchOperationData")); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../services"); + return "governance/screen/redirect"; + } + for (String service : SPACE_SPLIT_PATTERN.split(services)) { + if (!super.currentUser.hasServicePrivilege(service)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", service)); + model.addAttribute("success", false); + model.addAttribute("redirect", "../../services"); + return "governance/screen/redirect"; + } + } + for (String service : SPACE_SPLIT_PATTERN.split(services)) { + List overrides = overrideService.findByServiceAndApplication(service, application); + if (overrides != null && overrides.size() > 0) { + for (Override override : overrides) { + Map map = StringUtils.parseQueryString(override.getParams()); + if (mock == null || mock.length() == 0) { + map.remove("mock"); + } else { + map.put("mock", URL.encode(mock)); + } + if (map.size() > 0) { + override.setParams(StringUtils.toQueryString(map)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.updateOverride(override); + } else { + overrideService.deleteOverride(override.getId()); + } + } + } else if (mock != null && mock.length() > 0) { + Override override = new Override(); + override.setService(service); + override.setApplication(application); + override.setParams("mock=" + URL.encode(mock)); + override.setEnabled(true); + override.setOperator(operator); + override.setOperatorAddress(operatorAddress); + overrideService.saveOverride(override); + } + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../../services"); + return "governance/screen/redirect"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/WeightsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/WeightsController.java new file mode 100644 index 0000000..d94428a --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/governance/WeightsController.java @@ -0,0 +1,305 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.governance; + +import java.io.BufferedReader; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.utils.CollectionUtils; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.domain.Weight; +import com.alibaba.dubboadmin.registry.common.util.OverrideUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.support.BindingAwareModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +/** + * ProvidersController. + * URI: /services/$service/weights + * + */ +@Controller +@RequestMapping("/governance/weights") +public class WeightsController extends BaseController { + + private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3}$"); + private static final Pattern LOCAL_IP_PATTERN = Pattern.compile("127(\\.\\d{1,3}){3}$"); + private static final Pattern ALL_IP_PATTERN = Pattern.compile("0{1,3}(\\.0{1,3}){3}$"); + @Autowired + private OverrideService overrideService; + @Autowired + private ProviderService providerService; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "weights"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + String address = (String)newModel.get("address"); + service = StringUtils.trimToNull(service); + address = Tool.getIP(address); + List weights; + if (service != null && service.length() > 0) { + weights = OverrideUtils.overridesToWeights(overrideService.findByService(service)); + } else if (address != null && address.length() > 0) { + weights = OverrideUtils.overridesToWeights(overrideService.findByAddress(address)); + } else { + weights = OverrideUtils.overridesToWeights(overrideService.findAll()); + } + model.addAttribute("weights", weights); + return "governance/screen/weights/index"; + } + + /** + * load page for the adding + * + */ + @RequestMapping("/add") + public String add(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "add", "weights"); + BindingAwareModelMap newModel = (BindingAwareModelMap)model; + String service = (String)newModel.get("service"); + String input = request.getParameter("input"); + if (service != null && service.length() > 0 && !service.contains("*")) { + List providerList = providerService.findByService(service); + List addressList = new ArrayList(); + for (Provider provider : providerList) { + addressList.add(provider.getUrl().split("://")[1].split("/")[0]); + } + model.addAttribute("addressList", addressList); + model.addAttribute("service", service); + model.addAttribute("methods", CollectionUtils.sort(providerService.findMethodsByService(service))); + } else { + List serviceList = Tool.sortSimpleName(providerService.findServices()); + model.addAttribute("serviceList", serviceList); + } + if (input != null) model.addAttribute("input", input); + return "governance/screen/weights/add"; + } + + /** + * load page for the multi adding + * + * @param context + */ + public void multiadd(Map context) { + List serviceList = Tool.sortSimpleName(providerService.findServices()); + context.put("serviceList", serviceList); + } + + @RequestMapping("/create") + public String create(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, "create", "weights"); + String addr = request.getParameter("address"); + String services = request.getParameter("multiservice"); + if (services == null || services.trim().length() == 0) { + services = request.getParameter("service"); + } + String weight = request.getParameter("weight"); + + int w = Integer.parseInt(weight); + + Set addresses = new HashSet(); + BufferedReader reader = new BufferedReader(new StringReader(addr)); + while (true) { + String line = reader.readLine(); + if (null == line) + break; + + String[] split = line.split("[\\s,;]+"); + for (String s : split) { + if (s.length() == 0) + continue; + + String ip = s; + String port = null; + if (s.indexOf(":") != -1) { + ip = s.substring(0, s.indexOf(":")); + port = s.substring(s.indexOf(":") + 1, s.length()); + if (port.trim().length() == 0) port = null; + } + if (!IP_PATTERN.matcher(ip).matches()) { + model.addAttribute("message", "illegal IP: " + s); + model.addAttribute("success", false); + model.addAttribute("redirect", "../weights"); + return "governance/screen/redirect"; + } + if (LOCAL_IP_PATTERN.matcher(ip).matches() || ALL_IP_PATTERN.matcher(ip).matches()) { + model.addAttribute("message", "local IP or any host ip is illegal: " + s); + model.addAttribute("success", false); + model.addAttribute("redirect", "../weights"); + return "governance/screen/redirect"; + } + if (port != null) { + if (!NumberUtils.isDigits(port)) { + model.addAttribute("message", "illegal port: " + s); + model.addAttribute("success", false); + model.addAttribute("redirect", "../weights"); + return "governance/screen/redirect"; + } + } + addresses.add(s); + } + } + + Set aimServices = new HashSet(); + reader = new BufferedReader(new StringReader(services)); + while (true) { + String line = reader.readLine(); + if (null == line) + break; + + String[] split = line.split("[\\s,;]+"); + for (String s : split) { + if (s.length() == 0) + continue; + if (!super.currentUser.hasServicePrivilege(s)) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", s)); + model.addAttribute("success", false); + model.addAttribute("redirect", "../weights"); + return "governance/screen/redirect"; + } + aimServices.add(s); + } + } + + for (String aimService : aimServices) { + for (String a : addresses) { + Weight wt = new Weight(); + wt.setUsername((String) ((BindingAwareModelMap)model).get("operator")); + wt.setAddress(Tool.getIP(a)); + wt.setService(aimService); + wt.setWeight(w); + overrideService.saveOverride(OverrideUtils.weightToOverride(wt)); + } + } + model.addAttribute("success", true); + model.addAttribute("redirect", "../weights"); + return "governance/screen/redirect"; + } + + @RequestMapping("/{id}/edit") + public String edit(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "edit", "weights"); + String service = request.getParameter("service"); + String input = request.getParameter("input"); + + if (service != null && service.length() > 0 && !service.contains("*")) { + List providerList = providerService.findByService(service); + List addressList = new ArrayList(); + for (Provider provider : providerList) { + addressList.add(provider.getUrl().split("://")[1].split("/")[0]); + } + model.addAttribute("addressList", addressList); + model.addAttribute("service", service); + model.addAttribute("methods", CollectionUtils.sort(providerService.findMethodsByService(service))); + } else { + List serviceList = Tool.sortSimpleName(providerService.findServices()); + model.addAttribute("serviceList", serviceList); + } + if (input != null) model.addAttribute("input", input); + Weight weight = OverrideUtils.overrideToWeight(overrideService.findById(id)); + model.addAttribute("weight", weight); + model.addAttribute("service", overrideService.findById(id).getService()); + return "governance/screen/weights/edit"; + } + + //public void sameSeviceEdit(Long id, Map context) { + // add(context); + // show(id, context); + //} + + /** + * load weight for editing + * + * @param id + + */ + @RequestMapping("/{id}") + public String show(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "show", "weights"); + Weight weight = OverrideUtils.overrideToWeight(overrideService.findById(id)); + model.addAttribute("weight", weight); + return "governance/screen/weights/show"; + } + + @RequestMapping(value = "/update", method = RequestMethod.POST) //post + public String update(Weight weight, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "update", "weights"); + boolean success = true; + if (!super.currentUser.hasServicePrivilege(weight.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", weight.getService())); + success = false; + } else { + weight.setAddress(Tool.getIP(weight.getAddress())); + overrideService.updateOverride(OverrideUtils.weightToOverride(weight)); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "governance/weights"); + return "governance/screen/redirect"; + } + + /** + * delete + * + * @param ids + * @return + */ + @RequestMapping("/{ids}/delete") + public String delete(@PathVariable("ids") Long[] ids, HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "delete", "weights"); + boolean success = true; + for (Long id : ids) { + Weight w = OverrideUtils.overrideToWeight(overrideService.findById(id)); + if (!super.currentUser.hasServicePrivilege(w.getService())) { + model.addAttribute("message", getMessage("HaveNoServicePrivilege", w.getService())); + success = false; + model.addAttribute("success", success); + model.addAttribute("redirect", "../../weights"); + return "governance/screen/redirect"; + } + } + + for (Long id : ids) { + overrideService.deleteOverride(id); + } + model.addAttribute("success", success); + model.addAttribute("redirect", "../../weights"); + return "governance/screen/redirect"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/DisableController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/DisableController.java new file mode 100644 index 0000000..14453a3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/DisableController.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.home; + +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Provider; + +import org.springframework.beans.factory.annotation.Autowired; + +public class DisableController extends ShellController { + + @Autowired + private ProviderService providerService; + + @Autowired + private HttpServletRequest request; + + public void setProviderDAO(ProviderService providerDAO) { + this.providerService = providerDAO; + } + + protected String doExecute(Map context) throws Exception { + String address = request.getParameter("provider"); + if (address == null || address.length() == 0) { + address = request.getParameter("client"); + } + if (address == null || address.length() == 0) { + throw new IllegalArgumentException("The url provider parameter is null! Usage: " + request.getRequestURL().toString() + "?provider=" + operatorAddress); + } + List providers = providerService.findByAddress(address); + if (providers != null && providers.size() > 0) { + for (Provider provider : providers) { + if (!currentUser.hasServicePrivilege(provider.getService())) { + throw new IllegalStateException("The user " + currentUser.getUsername() + " have no privilege of service " + provider.getService()); + } + } + for (Provider provider : providers) { + provider.setUsername(operator); + provider.setOperatorAddress(operatorAddress); + providerService.disableProvider(provider.getId()); + } + } + return "DisableController " + (providers == null ? 0 : providers.size()) + " services."; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/IndexController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/IndexController.java new file mode 100644 index 0000000..b6bb565 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/IndexController.java @@ -0,0 +1,87 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.home; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.governance.util.WebConstants; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.web.pulltool.RootContextPath; +import com.alibaba.dubboadmin.web.pulltool.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class IndexController { + + private static final Logger logger = LoggerFactory.getLogger(IndexController.class); + @Autowired + private ProviderService providerService; + + @Autowired + private ConsumerService consumerService; + + @RequestMapping("/") + public String indexRequest(HttpServletRequest request, Model model) { + Set applications = new HashSet(); + Set services = new HashSet(); + List pList = new ArrayList(); + try { + pList = providerService.findAll(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + for (Provider p : pList) { + applications.add(p.getApplication()); + services.add(p.getService()); + } + List cList = new ArrayList(); + try { + cList = consumerService.findAll(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + for (Consumer c : cList) { + applications.add(c.getApplication()); + services.add(c.getService()); + } + model.addAttribute("rootContextPath", new RootContextPath(request.getContextPath())); + model.addAttribute("services", services.size()); + model.addAttribute("providers", pList.size()); + model.addAttribute("consumers", cList.size()); + model.addAttribute("applications", applications.size()); + model.addAttribute("helpUrl", WebConstants.HELP_URL); + model.addAttribute("tool", new Tool()); + return "home/screen/index"; + + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/LookupController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/LookupController.java new file mode 100644 index 0000000..df8a795 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/LookupController.java @@ -0,0 +1,83 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.home; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.registry.RegistryService; +import com.alibaba.dubboadmin.governance.service.ConsumerService; + +import org.springframework.beans.factory.annotation.Autowired; + +public class LookupController extends RestfulController { + + @Autowired + ConsumerService consumerDAO; + + @Autowired + private RegistryService registryService; + + public ResultController doExecute(Map context) throws Exception { + String inf = request.getParameter("interface"); + if (inf == null || inf.isEmpty()) { + throw new IllegalArgumentException("please give me the interface"); + } + String group = null; + if (inf.contains("/")) { + int idx = inf.indexOf('/'); + group = inf.substring(idx); + inf = inf.substring(idx + 1, inf.length()); + } + String version = null; + if (inf.contains(":")) { + int idx = inf.lastIndexOf(':'); + version = inf.substring(idx + 1, inf.length()); + inf = inf.substring(idx); + } + + String parameters = request.getParameter("parameters"); + String url = "subscribe://" + operatorAddress + "/" + request.getParameter("interface"); + if (parameters != null && parameters.trim().length() > 0) { + url += parameters.trim(); + } + + URL u = URL.valueOf(url); + if (group != null) { + u.addParameter("group", group); + } + + if (version != null) u.addParameter("version", version); + + List lookup = registryService.lookup(u); + + Map> serviceUrl = new HashMap>(); + Map urls = new HashMap(); + serviceUrl.put(request.getParameter("interface").trim(), urls); + + for (URL u2 : lookup) { + urls.put(u2.toIdentityString(), u2.toParameterString()); + } + + ResultController resultController = new ResultController(); + resultController.setMessage(serviceUrl); + return resultController; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RegController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RegController.java new file mode 100644 index 0000000..cf967a4 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RegController.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.home; + +import java.util.HashMap; +import java.util.Map; + +public class RegController extends RestfulController { + + public ResultController doExecute(Map context) throws Exception { + if (url == null) { + throw new IllegalArgumentException("please give me the url"); + } + if (url.getPath().isEmpty()) { + throw new IllegalArgumentException("please use interface as your url path"); + } + Map tmp = new HashMap(); + tmp.put(url.toIdentityString(), url.toParameterString()); + Map> register = new HashMap>(); + register.put(url.getPath(), tmp); +// Map> newRegister = RegistryUtils.convertRegister(register); +// registryService.register(operatorAddress, newRegister, false); + ResultController resultController = new ResultController(); + resultController.setMessage("RegisterController Successfully!"); + return resultController; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RegisterController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RegisterController.java new file mode 100644 index 0000000..fdcc59d --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RegisterController.java @@ -0,0 +1,75 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.home; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.dubbo.common.utils.CollectionUtils; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ProviderService; + +import org.springframework.beans.factory.annotation.Autowired; + +public class RegisterController extends ShellController { + + @Autowired + private ProviderService providerDAO; + + @Autowired + private HttpServletRequest request; + +// @Autowired +// private RegistryCache registryCache; + + @SuppressWarnings("unchecked") + protected String doExecute(Map context) throws Exception { + Map params = request.getParameterMap(); + if (params == null || params.size() == 0) { + throw new IllegalArgumentException("The url parameters is null! Usage: " + request.getRequestURL().toString() + "?com.xxx.XxxService=http://" + request.getRemoteAddr() + "/xxxService?application=xxx&foo1=123"); + } + Map> map = new HashMap>(); + for (Map.Entry entry : params.entrySet()) { + if (entry.getKey() != null && entry.getKey().length() > 0 + && entry.getValue() != null && entry.getValue().length > 0 + && entry.getValue()[0] != null && entry.getValue()[0].length() > 0) { + if (!currentUser.hasServicePrivilege(entry.getKey())) { + throw new IllegalStateException("The user " + currentUser.getUsername() + " have no privilege of service " + entry.getKey()); + } + String serviceName = entry.getKey(); + Map url2query = CollectionUtils.split(Arrays.asList(entry.getValue()), "?"); + // check whether url contain application info + for (Map.Entry e : url2query.entrySet()) { + Map query = StringUtils.parseQueryString(e.getValue()); + String app = query.get("application"); + if (StringUtils.isBlank(app)) { + throw new IllegalStateException("No application for service(" + serviceName + "): " + + e.getKey() + "?" + e.getValue()); + } + } + map.put(serviceName, url2query); + } + } + if (map.size() > 0) { +// providerDAO.register(registryCache.getCurrentRegistry(), request.getRemoteAddr(), operatorAddress, operator, map, false, true); + } + return "RegisterController " + map.size() + " services."; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RestfulController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RestfulController.java new file mode 100644 index 0000000..f9c208f --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/RestfulController.java @@ -0,0 +1,99 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.home; + +import java.util.Map; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubboadmin.governance.util.WebConstants; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.fastjson.JSON; + +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class RestfulController { + + protected String role = null; + protected String operator = null; + + // @Autowired +// RegistryValidator registryService; + protected User currentUser = null; + protected String operatorAddress = null; + protected URL url = null; + @Autowired + HttpServletRequest request; + @Autowired + private HttpServletResponse response; + + public void execute(Map context) throws Exception { + ResultController resultController = new ResultController(); + if (request.getParameter("url") != null) { + url = URL.valueOf(URL.decode(request.getParameter("url"))); + } + if (context.get(WebConstants.CURRENT_USER_KEY) != null) { + User user = (User) context.get(WebConstants.CURRENT_USER_KEY); + currentUser = user; + operator = user.getUsername(); + role = user.getRole(); + context.put(WebConstants.CURRENT_USER_KEY, user); + } + operatorAddress = (String) context.get("clientid"); + if (operatorAddress == null || operatorAddress.isEmpty()) { + operatorAddress = (String) context.get("request.remoteHost"); + } + context.put("operator", operator); + context.put("operatorAddress", operatorAddress); + String jsonResult = null; + try { + resultController = doExecute(context); + resultController.setStatus("OK"); + } catch (IllegalArgumentException t) { + resultController.setStatus("ERROR"); + resultController.setCode(3); + resultController.setMessage(t.getMessage()); + } +// catch (InvalidRequestException t) { +// resultController.setStatus("ERROR"); +// resultController.setCode(2); +// resultController.setMessage(t.getMessage()); +// } + catch (Throwable t) { + resultController.setStatus("ERROR"); + resultController.setCode(1); + resultController.setMessage(t.getMessage()); + } + response.setContentType("application/javascript"); + ServletOutputStream os = response.getOutputStream(); + try { + jsonResult = JSON.toJSONString(resultController); + os.print(jsonResult); + } catch (Exception e) { + response.setStatus(500); + os.print(e.getMessage()); + } finally { + os.flush(); + } + } + + protected abstract ResultController doExecute(Map context) throws Exception; + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ResultController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ResultController.java new file mode 100644 index 0000000..6b5e667 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ResultController.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.home; + +import java.io.Serializable; + +public class ResultController implements Serializable { + + private static final long serialVersionUID = 4922467873471920132L; + private String status; + private Object message; + private int code; + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Object getMessage() { + return message; + } + + public void setMessage(Object message) { + this.message = message; + } + + public int getCode() { + return code; + } + + + public void setCode(int code) { + this.code = code; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + code; + result = prime * result + ((message == null) ? 0 : message.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + ResultController other = (ResultController) obj; + if (code != other.code) return false; + if (message == null) { + if (other.message != null) return false; + } else if (!message.equals(other.message)) return false; + if (status == null) { + if (other.status != null) return false; + } else if (!status.equals(other.status)) return false; + return true; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ServicestatusController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ServicestatusController.java new file mode 100644 index 0000000..4aacb22 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ServicestatusController.java @@ -0,0 +1,66 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.home; + +import java.io.PrintWriter; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubboadmin.governance.service.ProviderService; + +import org.springframework.beans.factory.annotation.Autowired; + +public class ServicestatusController { +// @Autowired +// private RegistryCache registryCache; + + @Autowired + private HttpServletRequest request; + + @Autowired + private ProviderService providerDAO; + + @Autowired + private HttpServletResponse response; + + public void execute(Map context) throws Exception { + String uri = request.getRequestURI(); + String contextPath = request.getContextPath(); + if (contextPath != null && !"/".equals(contextPath)) { + uri = uri.substring(contextPath.length()); + } + if (uri.startsWith("/status/")) { + uri = uri.substring("/status/".length()); + } +// Map providers = registryCache.getServices().get(uri); +// if (providers == null || providers.size() == 0) { +// providers = providerDAO.lookup(uri); +// } +// if (providers == null || providers.size() == 0) { +// context.put("message", "ERROR" +// + new SimpleDateFormat(" [yyyy-MM-dd HH:mm:ss] ").format(new Date()) +// + StatusController.filterOK("No such any provider for service " + uri)); +// } else { +// context.put("message", "OK"); +// } + PrintWriter writer = response.getWriter(); + writer.print(context.get("message").toString()); + writer.flush(); + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ShellController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ShellController.java new file mode 100644 index 0000000..06cc90e --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/ShellController.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.home; + +import java.io.PrintWriter; +import java.util.Map; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubboadmin.governance.util.WebConstants; +import com.alibaba.dubboadmin.registry.common.domain.User; + +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class ShellController { + private static final Pattern OK_PATTERN = Pattern.compile("ok", Pattern.CASE_INSENSITIVE); + private static final Pattern ERROR_PATTERN = Pattern.compile("error", Pattern.CASE_INSENSITIVE); + protected String role = null; + protected String operator = null; + protected User currentUser = null; + protected String operatorAddress = null; + @Autowired + private HttpServletResponse response; + + private static String filterOK(String value) { + if (value == null || value.length() == 0) { + return value; + } + return OK_PATTERN.matcher(value).replaceAll("0k"); + } + + private static String filterERROR(String value) { + if (value == null || value.length() == 0) { + return value; + } + return ERROR_PATTERN.matcher(value).replaceAll("err0r"); + } + + public void execute(Map context) throws Exception { + if (context.get(WebConstants.CURRENT_USER_KEY) != null) { + User user = (User) context.get(WebConstants.CURRENT_USER_KEY); + currentUser = user; + operator = user.getUsername(); + role = user.getRole(); + context.put(WebConstants.CURRENT_USER_KEY, user); + } + operatorAddress = (String) context.get("request.remoteHost"); + context.put("operator", operator); + context.put("operatorAddress", operatorAddress); + try { + String message = doExecute(context); + context.put("message", "OK: " + filterERROR(message)); + } catch (Throwable t) { + context.put("message", "ERROR: " + filterOK(t.getMessage())); + } + PrintWriter writer = response.getWriter(); + writer.print(context.get("message")); + writer.flush(); + } + + protected abstract String doExecute(Map context) throws Exception; + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/StatusController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/StatusController.java new file mode 100644 index 0000000..fabeff7 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/StatusController.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.home; + +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Map; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.status.Status.Level; +import com.alibaba.dubbo.common.status.StatusChecker; +import com.alibaba.dubboadmin.registry.common.StatusManager; + +import org.springframework.beans.factory.annotation.Autowired; + +public class StatusController { + private static final Pattern OK_PATTERN = Pattern.compile("o(k)", Pattern.CASE_INSENSITIVE); + @Autowired + private HttpServletResponse response; + + public static String filterOK(String message) { + if (message == null) + return ""; + // Avoid the ok keyword, use the number 0 instead of the letter o + return OK_PATTERN.matcher(message).replaceAll("0$1"); + } + + public void execute(Map context) throws Exception { + //FIXME cache monitoring has bad performance, should be removed from summary page. + Map + statuses = StatusManager.getInstance().getStatusList(new String[]{"cache"}); + com.alibaba.dubbo.common.status.Status status = StatusManager.getInstance().getStatusSummary(statuses); + Level level = status.getLevel(); + if (!com.alibaba.dubbo.common.status.Status.Level.OK.equals(level)) { + context.put("message", level + + new SimpleDateFormat(" [yyyy-MM-dd HH:mm:ss] ").format(new Date()) + + filterOK(status.getMessage())); + } else { + context.put("message", level.toString()); + } + PrintWriter writer = response.getWriter(); + writer.print(context.get("message").toString()); + writer.flush(); + } + + public void setStatusHandlers(Collection statusHandlers) { + StatusManager.getInstance().addStatusHandlers(statusHandlers); + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregController.java new file mode 100644 index 0000000..3f76318 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregController.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.home; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * UnReg.java + * + */ +public class UnregController extends RestfulController { + + public ResultController doExecute(Map context) throws Exception { + if (url == null) { + throw new IllegalArgumentException("please give me the url"); + } + if (url.getPath().isEmpty()) { + throw new IllegalArgumentException("please use interface as your url path"); + } + HashMap> services = new HashMap>(); + Set serviceUrl = new HashSet(); + serviceUrl.add(url.toIdentityString()); + String name = url.getPath(); + String version = url.getParameter("version"); + if (version != null) { + name = name + ":" + version; + } + String group = url.getParameter("group"); + if (group != null) { + name = group + "/" + name; + } + services.put(name, serviceUrl); +// registryService.unregister(operatorAddress,services); + ResultController resultController = new ResultController(); + resultController.setMessage("UnregisterController Successfully!"); + return resultController; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregisterController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregisterController.java new file mode 100644 index 0000000..aae1858 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregisterController.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.home; + +import java.util.Arrays; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.dubbo.common.utils.CollectionUtils; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Provider; + +import org.springframework.beans.factory.annotation.Autowired; + +public class UnregisterController extends ShellController { + + @Autowired + private ProviderService providervice; + + @Autowired + private HttpServletRequest request; + + @SuppressWarnings("unchecked") + protected String doExecute(Map context) throws Exception { + Map params = request.getParameterMap(); + if (params == null || params.size() == 0) { + throw new IllegalArgumentException("The url parameters is null! Usage: " + request.getRequestURL().toString() + "?com.xxx.XxxService=http://" + operatorAddress + "/xxxService"); + } + for (Map.Entry entry : params.entrySet()) { + if (entry.getKey() != null && entry.getKey().length() > 0 + && entry.getValue() != null && entry.getValue().length > 0 + && entry.getValue()[0] != null && entry.getValue()[0].length() > 0) { + if (!currentUser.hasServicePrivilege(entry.getKey())) { + throw new IllegalStateException("The user " + operator + " have no privilege of service " + entry.getKey()); + } + for (Entry e : CollectionUtils.split(Arrays.asList(entry.getValue()), "?").entrySet()) { + Provider provider = providervice.findByServiceAndAddress(entry.getKey(), e.getKey()); + if (provider != null) { + providervice.deleteStaticProvider(provider.getId()); + } + } + } + } + + return "UnregisterController " + params.size() + " services."; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregisterallController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregisterallController.java new file mode 100644 index 0000000..d4138c1 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/home/UnregisterallController.java @@ -0,0 +1,61 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.home; + +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Provider; + +import org.springframework.beans.factory.annotation.Autowired; + +public class UnregisterallController extends ShellController { + + @Autowired + private ProviderService providerService; + + @Autowired + private HttpServletRequest request; + + protected String doExecute(Map context) throws Exception { + String address = request.getParameter("provider"); + if (address == null || address.length() == 0) { + address = request.getParameter("client"); + } + if (address == null || address.length() == 0) { + throw new IllegalArgumentException("The url provider parameter is null! Usage: " + request.getRequestURL().toString() + "?provider=" + operatorAddress); + } + List providers = providerService.findByAddress(address); + if (providers != null && providers.size() > 0) { + for (Provider provider : providers) { + if (!currentUser.hasServicePrivilege(provider.getService())) { + throw new IllegalStateException("The user " + currentUser + " have no privilege of service " + provider.getService()); + } + } + for (Provider provider : providers) { + provider.setUsername(operator); + provider.setOperatorAddress(operatorAddress); + providerService.deleteStaticProvider(provider.getId()); + } + } + return "UnregisterController " + (providers == null ? 0 : providers.size()) + " services."; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/personal/InfosController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/personal/InfosController.java new file mode 100644 index 0000000..e7808a2 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/personal/InfosController.java @@ -0,0 +1,51 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.personal; + +import java.util.Map; + +import com.alibaba.dubboadmin.governance.service.UserService; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; + +public class InfosController extends BaseController { + @Autowired + private UserService userDAO; + + public void index(Map context) { + User user = userDAO.findById(currentUser.getId()); + context.put("user", user); + } + + public boolean update(Map context) { + User user = new User(); + user.setId(currentUser.getId()); + user.setUsername(currentUser.getUsername()); + user.setOperatorAddress(operatorAddress); + user.setName((String) context.get("name")); + user.setDepartment((String) context.get("department")); + user.setEmail((String) context.get("email")); + user.setPhone((String) context.get("phone")); + user.setAlitalk((String) context.get("alitalk")); + user.setLocale((String) context.get("locale")); + userDAO.modifyUser(user); + context.put("redirect", "../" + getClass().getSimpleName().toLowerCase()); + return true; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/personal/PasswdsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/personal/PasswdsController.java new file mode 100644 index 0000000..6dfcd6a --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/personal/PasswdsController.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.mvc.personal; + +import java.util.Map; + +import com.alibaba.dubboadmin.governance.service.UserService; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; + +public class PasswdsController extends BaseController { + + @Autowired + private UserService userDAO; + + public void index(Map context) { + + } + + public boolean create(Map context) { + User user = new User(); + user.setOperator(operator); + user.setOperatorAddress(operatorAddress); + user.setPassword((String) context.get("newPassword")); + user.setUsername(operator); + + boolean sucess = userDAO.updatePassword(user, (String) context.get("oldPassword")); + if (!sucess) + context.put("message", getMessage("passwd.oldwrong")); + return sucess; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/DumpController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/DumpController.java new file mode 100644 index 0000000..64cfae3 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/DumpController.java @@ -0,0 +1,164 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysinfo; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/sysinfo/dump") +public class DumpController extends BaseController { + + @Autowired + ProviderService providerDAO; + + @Autowired + ConsumerService consumerDAO; + + + @RequestMapping("/noProviders") + public void noProviders(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException { + prepare(request, response, model, "noProviders", "dump"); + PrintWriter writer = response.getWriter(); + List sortedService = getNoProviders(); + Collections.sort(sortedService); + writer.println(sortedService.size() + " services don't have provider"); + for (String noProvider : sortedService) { + writer.println(noProvider); + } + writer.flush(); + response.setContentType("text/plain"); + } + + @RequestMapping("/services") + public void services(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException { + prepare(request, response, model, "noProviders", "services"); + PrintWriter writer = response.getWriter(); + List sortedService = providerDAO.findServices(); + Collections.sort(sortedService); + writer.println(sortedService.size() + " services"); + for (String service : sortedService) { + writer.println(service + (providerDAO.findByService(service).size())); + } + writer.flush(); + response.setContentType("text/plain"); + } + + @RequestMapping("/providers") + public void providers(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException { + PrintWriter writer = response.getWriter(); + List providers = providerDAO.findAll(); + List sortedProviders = new ArrayList(); + for (Provider provider : providers) { + sortedProviders.add(provider.getUrl() + " " + provider.getService()); + } + Collections.sort(sortedProviders); + writer.println(sortedProviders.size() + " provider instance"); + for (String provider : sortedProviders) { + writer.println(provider); + } + writer.flush(); + response.setContentType("text/plain"); + } + + @RequestMapping("/consumers") + public void consumers(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException { + PrintWriter writer = response.getWriter(); + List consumers = consumerDAO.findAll(); + List sortedConsumerss = new ArrayList(); + for (Consumer consumer : consumers) { + sortedConsumerss.add(consumer.getAddress() + " " + consumer.getService()); + } + Collections.sort(sortedConsumerss); + writer.println(sortedConsumerss.size() + " consumer instance"); + for (String consumer : sortedConsumerss) { + writer.println(consumer); + } + writer.flush(); + response.setContentType("text/plain"); + } + + @RequestMapping("/versions") + public void versions(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException { + PrintWriter writer = response.getWriter(); + List providers = providerDAO.findAll(); + List consumers = consumerDAO.findAll(); + Set parametersSet = new HashSet(); + Map> versions = new HashMap>(); + for (Provider provider : providers) { + parametersSet.add(provider.getParameters()); + } + for (Consumer consumer : consumers) { + parametersSet.add(consumer.getParameters()); + } + Iterator temp = parametersSet.iterator(); + while (temp.hasNext()) { + Map parameter = StringUtils.parseQueryString(temp.next()); + if (parameter != null) { + String dubboversion = parameter.get("dubbo"); + String app = parameter.get("application"); + if (versions.get(dubboversion) == null) { + Set apps = new HashSet(); + versions.put(dubboversion, apps); + } + versions.get(dubboversion).add(app); + } + } + for (String version : versions.keySet()) { + writer.println("dubbo version: " + version); + writer.println(StringUtils.join(versions.get(version), "\n")); + writer.println("\n"); + } + model.addAttribute("versions", versions); + writer.flush(); + response.setContentType("text/plain"); + } + + private List getNoProviders() { + List providerServices = providerDAO.findServices(); + List consumerServices = consumerDAO.findServices(); + List noProviderServices = new ArrayList(); + if (consumerServices != null) { + noProviderServices.addAll(consumerServices); + noProviderServices.removeAll(providerServices); + } + return noProviderServices; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/DumpsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/DumpsController.java new file mode 100644 index 0000000..d7b4ff0 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/DumpsController.java @@ -0,0 +1,67 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysinfo; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/sysinfo/dumps") +public class DumpsController extends BaseController { + + @Autowired + ProviderService providerDAO; + + @Autowired + ConsumerService consumerDAO; + + @Autowired + HttpServletResponse response; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "dumps"); + model.addAttribute("noProviderServices", getNoProviders()); + model.addAttribute("services", providerDAO.findServices()); + model.addAttribute("providers", providerDAO.findAll()); + model.addAttribute("consumers", consumerDAO.findAll()); + return "sysinfo/screen/dumps/index"; + } + + private List getNoProviders() { + List providerServices = providerDAO.findServices(); + List consumerServices = consumerDAO.findServices(); + List noProviderServices = new ArrayList(); + if (consumerServices != null) { + noProviderServices.addAll(consumerServices); + noProviderServices.removeAll(providerServices); + } + return noProviderServices; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/EnvsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/EnvsController.java new file mode 100644 index 0000000..839b413 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/EnvsController.java @@ -0,0 +1,117 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysinfo; + +import java.lang.management.ManagementFactory; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.Version; +import com.alibaba.dubbo.common.utils.NetUtils; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/sysinfo/envs") +public class EnvsController extends BaseController { + + private static final long SECOND = 1000; + private static final long MINUTE = 60 * SECOND; + private static final long HOUR = 60 * MINUTE; + private static final long DAY = 24 * HOUR; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, "index", "envs"); + Map properties = new TreeMap(); + StringBuilder msg = new StringBuilder(); + msg.append("Version: "); + msg.append(Version.getVersion(EnvsController.class, "2.2.0")); + properties.put("Registry", msg.toString()); + String address = NetUtils.getLocalHost(); + properties.put("Host", NetUtils.getHostName(address) + "/" + address); + properties.put("Java", System.getProperty("java.runtime.name") + " " + System.getProperty("java.runtime.version")); + properties.put("OS", System.getProperty("os.name") + " " + + System.getProperty("os.version")); + properties.put("CPU", System.getProperty("os.arch", "") + ", " + + String.valueOf(Runtime.getRuntime().availableProcessors()) + " cores"); + properties.put("Locale", Locale.getDefault().toString() + "/" + + System.getProperty("file.encoding")); + properties.put("Uptime", formatUptime(ManagementFactory.getRuntimeMXBean().getUptime()) + + " From " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z").format(new Date( + ManagementFactory.getRuntimeMXBean().getStartTime())) + + " To " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z").format(new Date())); + model.addAttribute("properties", properties); + return "sysinfo/screen/envs/index"; + } + + private String formatUptime(long uptime) { + StringBuilder buf = new StringBuilder(); + if (uptime > DAY) { + long days = (uptime - uptime % DAY) / DAY; + buf.append(days); + buf.append(" Days"); + uptime = uptime % DAY; + } + if (uptime > HOUR) { + long hours = (uptime - uptime % HOUR) / HOUR; + if (buf.length() > 0) { + buf.append(", "); + } + buf.append(hours); + buf.append(" Hours"); + uptime = uptime % HOUR; + } + if (uptime > MINUTE) { + long minutes = (uptime - uptime % MINUTE) / MINUTE; + if (buf.length() > 0) { + buf.append(", "); + } + buf.append(minutes); + buf.append(" Minutes"); + uptime = uptime % MINUTE; + } + if (uptime > SECOND) { + long seconds = (uptime - uptime % SECOND) / SECOND; + if (buf.length() > 0) { + buf.append(", "); + } + buf.append(seconds); + buf.append(" Seconds"); + uptime = uptime % SECOND; + } + if (uptime > 0) { + if (buf.length() > 0) { + buf.append(", "); + } + buf.append(uptime); + buf.append(" Milliseconds"); + } + return buf.toString(); + } + + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/LogsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/LogsController.java new file mode 100644 index 0000000..0e24af4 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/LogsController.java @@ -0,0 +1,99 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysinfo; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.logger.Level; +import com.alibaba.dubbo.common.logger.LoggerFactory; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/sysinfo/logs") +public class LogsController extends BaseController { + + private static final int SHOW_LOG_LENGTH = 30000; + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + prepare(request, response, model, "index", "logs"); + long size; + String content; + String modified; + File file = LoggerFactory.getFile(); + if (file != null && file.exists()) { + FileInputStream fis = new FileInputStream(file); + FileChannel channel = fis.getChannel(); + size = channel.size(); + ByteBuffer bb; + if (size <= SHOW_LOG_LENGTH) { + bb = ByteBuffer.allocate((int) size); + channel.read(bb, 0); + } else { + int pos = (int) (size - SHOW_LOG_LENGTH); + bb = ByteBuffer.allocate(SHOW_LOG_LENGTH); + channel.read(bb, pos); + } + bb.flip(); + content = new String(bb.array()).replace("<", "<").replace(">", ">"); + modified = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified())); + } else { + size = 0; + content = ""; + modified = "Not exist"; + } + Level level = LoggerFactory.getLevel(); + model.addAttribute("name", file == null ? "" : file.getAbsoluteFile()); + model.addAttribute("size", String.valueOf(size)); + model.addAttribute("level", level == null ? "" : level); + model.addAttribute("modified", modified); + model.addAttribute("content", content); + return "sysinfo/screen/logs/index"; + } + + public boolean change(Map context) throws Exception { + String contextLevel = (String) context.get("level"); + if (contextLevel == null || contextLevel.length() == 0) { + context.put("message", getMessage("MissRequestParameters", "level")); + return false; + } + if (!User.ROOT.equals(role)) { + context.put("message", getMessage("HaveNoRootPrivilege")); + return false; + } + Level level = Level.valueOf(contextLevel); + if (level != LoggerFactory.getLevel()) { + LoggerFactory.setLevel(level); + } + context.put("redirect", "/sysinfo/logs"); + return true; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/StatusesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/StatusesController.java new file mode 100644 index 0000000..ad2b2fb --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/StatusesController.java @@ -0,0 +1,55 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysinfo; + +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.extension.ExtensionLoader; +import com.alibaba.dubbo.common.status.Status; +import com.alibaba.dubbo.common.status.StatusChecker; +import com.alibaba.dubboadmin.registry.common.StatusManager; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/sysinfo/statuses") +public class StatusesController extends BaseController { + + @RequestMapping("") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception { + + prepare(request, response, model, "index", "status"); + ExtensionLoader loader = ExtensionLoader.getExtensionLoader(StatusChecker.class); + Map statusList = new LinkedHashMap(); + for (String name : loader.getSupportedExtensions()) { + com.alibaba.dubbo.common.status.Status status = loader.getExtension(name).check(); + if (status.getLevel() != null && status.getLevel() != com.alibaba.dubbo.common.status.Status.Level.UNKNOWN) { + statusList.put(name, status); + } + } + statusList.put("summary", StatusManager.getStatusSummary(statusList)); + model.addAttribute("statusList", statusList); + return "sysinfo/screen/statuses/index"; + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/VersionsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/VersionsController.java new file mode 100644 index 0000000..711d2ff --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysinfo/VersionsController.java @@ -0,0 +1,114 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysinfo; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.ConsumerService; +import com.alibaba.dubboadmin.governance.service.ProviderService; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/sysinfo") +public class VersionsController extends BaseController { + @Autowired + private ProviderService providerService; + + @Autowired + private ConsumerService consumerService; + + @RequestMapping("/versions") + public String index(HttpServletRequest request, HttpServletResponse response, Model model) { + prepare(request, response, model, "index", "versions"); + List providers = providerService.findAll(); + List consumers = consumerService.findAll(); + Set parametersSet = new HashSet(); + for (Provider provider : providers) { + parametersSet.add(provider.getParameters()); + } + for (Consumer consumer : consumers) { + parametersSet.add(consumer.getParameters()); + } + Map> versions = new HashMap>(); + Iterator temp = parametersSet.iterator(); + while (temp.hasNext()) { + Map parameter = StringUtils.parseQueryString(temp.next()); + if (parameter != null) { + String dubbo = parameter.get("dubbo"); + if (dubbo == null) dubbo = "0.0.0"; + String application = parameter.get("application"); + if (versions.get(dubbo) == null) { + Set apps = new HashSet(); + versions.put(dubbo, apps); + } + versions.get(dubbo).add(application); + } + } + model.addAttribute("versions", versions); + return "sysinfo/screen/versions/index"; + } + + @RequestMapping("/version/{version}/versions/show") + public String show(@PathVariable("version") String version, HttpServletRequest request, HttpServletResponse response, + Model model) { + prepare(request, response, model, "show", "versions"); + if (version != null && version.length() > 0) { + List providers = providerService.findAll(); + List consumers = consumerService.findAll(); + Set parametersSet = new HashSet(); + Set applications = new HashSet(); + for (Provider provider : providers) { + parametersSet.add(provider.getParameters()); + } + for (Consumer consumer : consumers) { + parametersSet.add(consumer.getParameters()); + } + Iterator temp = parametersSet.iterator(); + while (temp.hasNext()) { + Map parameter = StringUtils.parseQueryString(temp.next()); + if (parameter != null) { + String dubbo = parameter.get("dubbo"); + if (dubbo == null) dubbo = "0.0.0"; + String application = parameter.get("application"); + if (version.equals(dubbo)) { + applications.add(application); + } + } + } + model.addAttribute("applications", applications); + } + return "sysinfo/screen/versions/show"; + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/ConfigsController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/ConfigsController.java new file mode 100644 index 0000000..e7207a2 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/ConfigsController.java @@ -0,0 +1,89 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysmanage; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; + +import com.alibaba.dubboadmin.governance.service.ConfigService; +import com.alibaba.dubboadmin.registry.common.domain.Config; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; + +public class ConfigsController extends BaseController { + + @Autowired + private ConfigService configDAO; + + @Autowired + private HttpServletRequest request; + + public void index(Map context) { + context.put("configs", configDAO.findAllConfigsMap()); + } + + public boolean update(Map context) { + @SuppressWarnings("unchecked") + Map all = request.getParameterMap(); + ; + if (all != null && all.size() > 0) { + if (!User.ROOT.equals(currentUser.getRole())) { + context.put("message", getMessage("HaveNoRootPrivilege")); + return false; + } + List configs = new ArrayList(); + for (Map.Entry entry : all.entrySet()) { + String key = entry.getKey(); + String[] values = entry.getValue(); + if (key != null && key.length() > 0 && !key.startsWith("_")) { + String value = ""; + if (values != null && values.length > 0 + && values[0] != null && values[0].length() > 0) { + value = values[0]; + } + Config config = new Config(); + config.setKey(key); + config.setUsername(currentUser.getUsername()); + config.setOperatorAddress((String) context.get("operatorAddress")); + config.setValue(value); + configs.add(config); + } + } + if (configs.size() > 0) { + configDAO.update(configs); + + Set usernames = new HashSet(); + usernames.add(currentUser.getName()); + + Map params = new HashMap(); + params.put("configs", configs); + } + return true; + } else { + context.put("message", getMessage("MissRequestParameters", "configKey,configValue")); + return false; + } + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/PrivilegesController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/PrivilegesController.java new file mode 100644 index 0000000..816d025 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/PrivilegesController.java @@ -0,0 +1,23 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysmanage; + +import com.alibaba.dubboadmin.web.mvc.BaseController; + +public class PrivilegesController extends BaseController { + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/UserownController.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/UserownController.java new file mode 100644 index 0000000..937a1ff --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/mvc/sysmanage/UserownController.java @@ -0,0 +1,43 @@ +/* + * 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 com.alibaba.dubboadmin.web.mvc.sysmanage; + +import java.util.List; +import java.util.Map; + +import com.alibaba.dubboadmin.governance.service.OwnerService; +import com.alibaba.dubboadmin.web.mvc.BaseController; + +import org.springframework.beans.factory.annotation.Autowired; + +/** + * ProvidersController. URI: /services/$service/owners + * + */ +public class UserownController extends BaseController { + + @Autowired + private OwnerService ownerDAO; + + public void index(Map context) { + String user = (String) context.get("user"); + List services; + services = ownerDAO.findServiceNamesByUsername(user); + context.put("user", user); + context.put("services", services); + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/DateFormatUtil.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/DateFormatUtil.java new file mode 100644 index 0000000..caa6819 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/DateFormatUtil.java @@ -0,0 +1,74 @@ + +/* + * 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 com.alibaba.dubboadmin.web.pulltool; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +/** + * DateFormat Utility + * + */ +public class DateFormatUtil { + + private static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + private static final ThreadLocal> tl = new ThreadLocal>(); + + /** + * According to the specified format, Get a DateFormat + * + * @param format + * @return + */ + public static DateFormat getDateFormat(String format) { + Map map = tl.get(); + + if (map == null) { + map = new HashMap(); + tl.set(map); + } + + if (StringUtils.isEmpty(format)) { + format = DEFAULT_FORMAT; + } + + DateFormat ret = map.get(format); + + if (ret == null) { + ret = new SimpleDateFormat(format); + map.put(format, ret); + } + + return ret; + } + + /** + * Get Default DateFormat + * + * @return + */ + public static DateFormat getDateFormat() { + return getDateFormat(null); + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/I18nMessageTool.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/I18nMessageTool.java new file mode 100644 index 0000000..6933979 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/I18nMessageTool.java @@ -0,0 +1,46 @@ +///* +// * 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 com.alibaba.dubboadmin.web.pulltool; +// +//import com.alibaba.citrus.service.pull.ToolFactory; +//import com.alibaba.dubbo.governance.biz.common.i18n.MessageResourceService; +// +//import org.springframework.beans.factory.annotation.Autowired; +// +///** +// * PullTool for accessing message bundle. +// *x +// */ +//public class I18nMessageTool implements ToolFactory { +// +// @Autowired +// private MessageResourceService messageResourceService; +// private boolean singleton = true; +// +// public Object createTool() throws Exception { +// return messageResourceService; +// } +// +// public boolean isSingleton() { +// return this.singleton; +// } +// +// public void setSingleton(boolean singleton) { +// this.singleton = singleton; +// } +// +//} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/RootContextPath.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/RootContextPath.java new file mode 100644 index 0000000..827c58b --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/RootContextPath.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubboadmin.web.pulltool; + +public class RootContextPath { + + private String contextPath; + + public RootContextPath(String contextPath) { + this.contextPath = contextPath; + } + + public String getURI(String uri) { + String prefix; + if (contextPath != null && contextPath.length() > 0 && !"/".equals(contextPath)) { + prefix = contextPath; + } else { + prefix = ""; + } + if (uri.startsWith("/")) { + return prefix + uri; + } else { + return prefix + "/" + uri; + } + } + +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/Tool.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/Tool.java new file mode 100644 index 0000000..fd58f37 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/Tool.java @@ -0,0 +1,489 @@ +/* + * 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 com.alibaba.dubboadmin.web.pulltool; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Array; +import java.net.InetAddress; +import java.net.URLEncoder; +import java.net.UnknownHostException; +import java.text.ParseException; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.utils.NetUtils; +import com.alibaba.dubbo.common.utils.StringUtils; +import com.alibaba.dubboadmin.governance.service.OverrideService; +import com.alibaba.dubboadmin.governance.service.RouteService; +import com.alibaba.dubboadmin.registry.common.domain.Consumer; +import com.alibaba.dubboadmin.registry.common.domain.Override; +import com.alibaba.dubboadmin.registry.common.domain.Provider; +import com.alibaba.dubboadmin.registry.common.domain.Route; +import com.alibaba.dubboadmin.registry.common.domain.User; +import com.alibaba.dubboadmin.registry.common.route.ParseUtils; +import com.alibaba.dubboadmin.registry.common.route.RouteRule; +import com.alibaba.dubboadmin.registry.common.route.RouteRule.MatchPair; +import com.alibaba.dubboadmin.registry.common.util.StringEscapeUtils; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Tool + * + */ +@Component +public class Tool { + + private static final Comparator SIMPLE_NAME_COMPARATOR = new Comparator() { + 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); + } + }; + @Autowired + private OverrideService overrideService; + @Autowired + private RouteService routeService; + + public static String toStackTraceString(Throwable t) { + StringWriter writer = new StringWriter(); + PrintWriter pw = new PrintWriter(writer); + t.printStackTrace(pw); + return writer.toString(); + } + + public static boolean isContains(String[] values, String value) { + return StringUtils.isContains(values, value); + } + + public static boolean startWith(String value, String prefix) { + return value.startsWith(prefix); + } + + public static String getHostPrefix(String address) { + if (address != null && address.length() > 0) { + String hostname = getHostName(address); + if (!address.startsWith(hostname)) { + return "(" + hostname + ")"; + } + } + return ""; + } + + public static String getHostName(String address) { + return NetUtils.getHostName(address); + } + + public static String getHostAddress(String address) { + if (address != null && address.length() > 0) { + int i = address.indexOf(':'); + String port = address.substring(i + 1); + String hostname = NetUtils.getHostName(address); + if (!address.equals(hostname)) { + return hostname + ":" + port; + } + } + return ""; + } + + public static String getPath(String url) { + try { + return URL.valueOf(url).getPath(); + } catch (Throwable t) { + return url; + } + } + + public static String getAddress(String url) { + try { + return URL.valueOf(url).getAddress(); + } catch (Throwable t) { + return url; + } + } + + 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; + } + + 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 encode(String url) { + try { + return URLEncoder.encode(url, "UTF-8"); + } catch (UnsupportedEncodingException e) { + return url; + } + } + + public static String escape(String html) { + return StringEscapeUtils.escapeHtml(html); + } + + public static String unescape(String html) { + return StringEscapeUtils.unescapeHtml(html); + } + + 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 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 sortSimpleName(List 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; + } + + public static String getParameter(String parameters, String key) { + String value = ""; + if (parameters != null && parameters.length() > 0) { + String[] pairs = parameters.split("&"); + for (String pair : pairs) { + String[] kv = pair.split("="); + if (key.equals(kv[0])) { + value = kv[1]; + break; + } + } + } + return value; + } + + public static Map toParameterMap(String parameters) { + return StringUtils.parseQueryString(parameters); + } + + /** + * Get the version value from the paramters parameter of provider + * + * @param parameters + * @return + */ + public static String getVersionFromPara(String parameters) { + String version = ""; + if (parameters != null && parameters.length() > 0) { + String[] params = parameters.split("&"); + for (String o : params) { + String[] kv = o.split("="); + if ("version".equals(kv[0])) { + version = kv[1]; + break; + } + } + } + return version; + } + + public static boolean isProviderEnabled(Provider provider, List oList) { + for (Override o : oList) { + if (o.isMatch(provider)) { + Map params = StringUtils.parseQueryString(o.getParams()); + String disbaled = params.get(Constants.DISABLED_KEY); + if (disbaled != null && disbaled.length() > 0) { + return !"true".equals(disbaled); + } + } + } + return provider.isEnabled(); + } + + public static int getProviderWeight(Provider provider, List oList) { + for (Override o : oList) { + if (o.isMatch(provider)) { + Map params = StringUtils.parseQueryString(o.getParams()); + String weight = params.get(Constants.WEIGHT_KEY); + if (weight != null && weight.length() > 0) { + return Integer.parseInt(weight); + } + } + } + return provider.getWeight(); + } + + public void setOverrideService(OverrideService overrideService) { + this.overrideService = overrideService; + } + + public void setRouteService(RouteService routeService) { + this.routeService = routeService; + } + + public String formatTimestamp(String timestamp) { + if (timestamp == null || timestamp.length() == 0) { + return ""; + } + return formatDate(new Date(Long.valueOf(timestamp))); + } + + //format date + public String formatDate(Date date) { + if (date == null) { + return ""; + } + return DateFormatUtil.getDateFormat().format(date); + } + + public String formatDate(Date date, String template) { + if (date == null || template == null) { + return ""; + } + return DateFormatUtil.getDateFormat(template).format(date); + } + + public boolean beforeNow(Date date) { + Date now = new Date(); + if (now.after(date)) { + return true; + } + return false; + } + + //minus of date + public long dateMinus(Date date1, Date date2) { + return (date1.getTime() - date1.getTime()) / 1000; + } + + public boolean isProviderEnabled(Provider provider) { + List oList = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress()); + return isProviderEnabled(provider, oList); + } + + public int getProviderWeight(Provider provider) { + List oList = overrideService.findByServiceAndAddress(provider.getService(), provider.getAddress()); + return getProviderWeight(provider, oList); + } + + public boolean isInBlackList(Consumer consumer) { + String service = consumer.getService(); + List routes = routeService.findForceRouteByService(service); + if (routes == null || routes.size() == 0) { + return false; + } + String ip = getIP(consumer.getAddress()); + for (Route route : routes) { + try { + if (!route.isEnabled()) { + continue; + } + String filterRule = route.getFilterRule(); + if (filterRule == null || filterRule.length() == 0 || "false".equals(filterRule)) { + Map rule = RouteRule.parseRule(route.getMatchRule()); + MatchPair pair = rule.get("consumer.host"); + if (pair == null) { + pair = rule.get("host"); + } + if (pair != null) { + if (pair.getMatches() != null && pair.getMatches().size() > 0) { + for (String host : pair.getMatches()) { + if (ParseUtils.isMatchGlobPattern(host, ip)) { + return true; + } + } + } + if (pair.getUnmatches() != null && pair.getUnmatches().size() > 0) { + boolean forbid = true; + for (String host : pair.getUnmatches()) { + if (ParseUtils.isMatchGlobPattern(host, ip)) { + forbid = false; + } + } + if (forbid) { + return true; + } + } + } + } + } catch (ParseException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + return false; + } + + public String getConsumerMock(Consumer consumer) { + return getOverridesMock(consumer.getOverrides()); + } + + public String getOverridesMock(List overrides) { + if (overrides != null && overrides.size() > 0) { + for (Override override : overrides) { + Map params = StringUtils.parseQueryString(override.getParams()); + String mock = params.get("mock"); + if (mock != null && mock.length() > 0) { + return mock; + } + } + } + return ""; + } + + public boolean checkUrl(User user, String uri) { + return true; + /*if(!User.ROOT.equals(user.getRole())){ + List disabledSysinfo = new ArrayList(); + List disabledSysmanage = new ArrayList(); + Map features = daoCache.getFeatures(); + if (features.size() > 0){ + for(Entry feature : features.entrySet()){ + if(feature.getKey().startsWith("Sysinfo") && !feature.getValue()){ + disabledSysinfo.add(feature.getKey().replace(".", "/").toLowerCase()); + }else if(feature.getKey().startsWith("Sysmanage") && !feature.getValue()){ + disabledSysmanage.add(feature.getKey().replace(".", "/").toLowerCase()); + } + } + if(uri.startsWith("/sysinfo")){ + for(String disabled : disabledSysinfo){ + if (uri.contains(disabled)){ + return false; + } + } + } + if(uri.startsWith("/sysmanage")){ + for(String disabled : disabledSysmanage){ + if (uri.contains(disabled)){ + return false; + } + } + } + }else{ + return true; + } + } + return true;*/ + } +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/ToolUtil.java b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/ToolUtil.java new file mode 100644 index 0000000..5af098b --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/java/com/alibaba/dubboadmin/web/pulltool/ToolUtil.java @@ -0,0 +1,52 @@ +///* +// * 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 com.alibaba.dubboadmin.web.pulltool; +// +//import com.alibaba.citrus.service.pull.ToolFactory; +//import com.alibaba.dubbo.governance.service.OverrideService; +//import com.alibaba.dubbo.governance.service.RouteService; +// +//import org.springframework.beans.factory.annotation.Autowired; +// +///** +// * PullTool for accessing message bundle. +// * +// */ +//public class ToolUtil implements ToolFactory { +// @Autowired +// OverrideService overrideService; +// +// @Autowired +// RouteService routeService; +// private boolean singleton = false; +// +// public Object createTool() throws Exception { +// Tool tool = new Tool(); +// tool.setOverrideService(overrideService); +// tool.setRouteService(routeService); +// return tool; +// } +// +// public boolean isSingleton() { +// return this.singleton; +// } +// +// public void setSingleton(boolean singleton) { +// this.singleton = singleton; +// } +// +//} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/application.properties b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/application.properties new file mode 100644 index 0000000..477174f --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/application.properties @@ -0,0 +1,27 @@ +# +# 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. +# + +server.port=7001 +spring.velocity.cache=false +spring.velocity.charset=UTF-8 +spring.velocity.layout-url=/templates/default.vm +spring.messages.fallback-to-system-locale=false +spring.messages.basename=i18n/message +spring.root.password=root +spring.guest.password=guest + +dubbo.registry.address=zookeeper://127.0.0.1:2181 diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/dubbo-admin.xml b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/dubbo-admin.xml new file mode 100644 index 0000000..f32036c --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/dubbo-admin.xml @@ -0,0 +1,29 @@ + + + + + + + + + + \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message.properties b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message.properties new file mode 100644 index 0000000..a9fd83f --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message.properties @@ -0,0 +1,16 @@ +# +# 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. +# \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_en.properties b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_en.properties new file mode 100644 index 0000000..431bca0 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_en.properties @@ -0,0 +1,768 @@ +# +# 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. +# + +#menus +home=home +stat=stat +revision=revision +connectionNum=connectionNum +serviceNum=serviceNum +providerNum=providerNum +consumerNum=consumerNum +applicationNum=applicationNum +about=about +help=help +favorites=favorites +histories=histories +governance=governance +applications=applications +efferents=efferents +afferents=afferents +services=services +references=references +addresses=addresses +providers=providers +dependencies=dependencies +layers=layers +clusters=clusters +consumers=consumers +accesses=accesses +routes=routes +weights=weights +loadbalances=loadbalances +tests=tests +mocks=mocks +overrides=overrides +documents=documents +owners=owners +agreements=agreements +approvals=approvals +operations=operations +users=users +envs=envs +helps=helps +registries=registries +configs=configs +features=features +connections=connections +statuses=statuses +failed=failed +cached=cached +dumps=dumps +InvalidIp=InvalidIp +versions=versions +logs=logs +infos=infos +passwds=passwds +dependency.list=dependency.list +dependency.tree=dependency.tree +dependency.graph=dependency.graph +dependency.efferent=dependency.efferent +dependency.afferent=dependency.afferent +provided=provided +consumed=consumed +select=select +clean=clean +information=information +control=control +summary=summary +consumer.application=consumer.application +response.time=response.time +sysinfo.infos=sysinfo.infos +helps.document=helps.document +helps.requirement=helps.requirement +helps.source=helps.source +connections=connections +ReconnectUnkwown=ReconnectUnkwown +confirmReconnectConnection=confirmReconnectConnection +confirmRedirectRegistry=confirmRedirectRegistry +confirmReconnectUnknownConnection=confirmReconnectUnknownConnection +status.resourcename=status.resourcename +status.status=status.status +status.message=status.message +status.description=status.description +status.memoryStatus=status.memoryStatus +status.memoryStatusDesc=status.memoryStatusDesc +status.threadpoolStatus=status.threadpoolStatus +status.threadpoolStatusDesc=status.threadpoolStatusDesc +status.failureStatus=status.failureStatus +status.failureStatusDesc=status.failureStatusDesc +status.cacheStatus=status.cacheStatus +status.cacheStatusDesc=status.cacheStatusDesc +status.timerStatus=status.timerStatus +status.timerStatusDesc=status.timerStatusDesc +status.socketStatus=status.socketStatus +status.socketStatusDesc=status.socketStatusDesc +status.loadStatus=status.loadStatus +status.loadStatusDesc=status.loadStatusDesc +status.datasourceStatus=status.datasourceStatus +status.datasourceStatusDesc=status.datasourceStatusDesc +status.registryStatus=status.registryStatus +status.registryStatusDesc=status.registryStatusDesc +status.monitorStatus=status.monitorStatus +status.monitorStatusDesc=status.monitorStatusDesc +status.summaryStatus=status.summaryStatus +status.summaryStatusDesc=status.summaryStatusDesc +status.warmupStatus=status.warmupStatus +status.warmupStatusDesc=status.warmupStatusDesc +status.OK=status.OK +status.WARN=status.WARN +status.ERROR=status.ERROR +status.UNKNOWN=status.UNKNOWN +Status0=Unknow +Status1=OK +Status2=OK +Status3=ERROR +Status4=FATAL +Status5=UNKNOW +service.filter=service.filter +default.service.filter=default.service.filter +mock=mock +force.mocked=force.mocked +fail.mocked=fail.mocked +no.mocked=no.mocked +force.mock=force.mock +fail.mock=fail.mock +cancel.mock=cancel.mock +confirm.force.mock=\u786e\u8ba4\u5c4f\u853d\u8be5\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.fail.mock=\u786e\u8ba4\u5bf9\u8be5\u670d\u52a1\u5bb9\u9519\uff1f
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.cancel.mock=\u786e\u8ba4\u6062\u590d\u8be5\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +batch.force.mock=batch.force.mock +batch.fail.mock=batch.fail.mock +batch.cancel.mock=batch.cancel.mock +confirm.batch.force.mock=\u786e\u8ba4\u6279\u91cf\u5c4f\u853d\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.batch.fail.mock=\u786e\u8ba4\u6279\u91cf\u5bf9\u670d\u52a1\u5bb9\u9519\uff1f
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.batch.cancel.mock=\u786e\u8ba4\u6279\u91cf\u6062\u590d\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +all.force.mock=all.force.mock +all.fail.mock=all.fail.mock +all.cancel.mock=all.cancel.mock +confirm.all.force.mock=\u786e\u8ba4\u7F3A\u7701\u5c4f\u853d\u8be5\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.all.fail.mock=\u786e\u8ba4\u7F3A\u7701\u5bf9\u8be5\u670d\u52a1\u5bb9\u9519\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.all.cancel.mock=\u786e\u8ba4\u7F3A\u7701\u6062\u590d\u8be5\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +agreement.invocation.quantity=agreement.invocation.quantity +agreement.tps=agreement.tps +response.time=response.time +agreement.availability=agreement.availability +layer.name=layer.name +layer.value=layer.value +default.lazy=default.lazy +layer.arch=layer.arch +loadBalanceStrategy=loadBalanceStrategy +ServiceName=ServiceName +cluster.name=cluster.name +cluster.address=cluster.address +property.name=property.name +property.value=property.value +property.count=property.count +getMethods=getMethods +getAddresses=getAddresses +Edit=Edit +Username=Username +Priority=Priority +ConnectionAddress=ConnectionAddress +Role=Role +Reconnect=Reconnect +Redirect=Redirect +staff.query= +configKey=configKey +configValue=configValue +Preview=Preview +routeselect=routeselect +AllOperations=AllOperations +BeforeOneMonthOperations=BeforeOneMonthOperations +BeforeThreeMonthOperations=BeforeThreeMonthOperations +BeforeHalfYearOperations=BeforeHalfYearOperations +BeforeOneYearOperations=BeforeOneYearOperations +PleaseInput=PleaseInput +BulletinConfig=BulletinConfig +BulletinMessage=BulletinMessage +MailConfig=MailConfig +MailEnabled=MailEnabled +MailHost=MailHost +MailPort=MailPort +MailFrom=MailFrom +MailAuth=MailAuth +MailUsername=MailUsername +MailPassword=MailPassword +LoginConfig=LoginConfig +AllowAnonymousLogin=AllowAnonymousLogin +AllowLegacyLogin=AllowLegacyLogin +RouteEnabled=RouteEnabled +WarmupEnabled=WarmupEnabled +LogConfig=LogConfig +LogLevel=LogLevel +RedirectConfig=RedirectConfig +AutoRedirectInterval=AutoRedirectInterval +AutoRedirectThreshold=AutoRedirectThreshold +AutoRedirectToleratePercent=AutoRedirectToleratePercent +ManualRedirect=ManualRedirect +LimitConfig=LimitConfig +MaxConnectionSize=MaxConnectionSize +MaxCacheSize=MaxCacheSize +MaxMailSize=MaxMailSize +TimerConfig=TimerConfig +AlivedCheckInterval=AlivedCheckInterval +ChangedCheckInterval=ChangedCheckInterval +FailedRetryInterval=FailedRetryInterval +DirtyCheckInterval=DirtyCheckInterval +HeartbeatConfig=HeartbeatConfig +HeartbeatCheckInterval=HeartbeatCheckInterval +HeartbeatCheckTimeout=HeartbeatCheckTimeout +TimeoutConfig=TimeoutConfig +NotifyTimeout=NotifyTimeout +WarmupWaitTime=WarmupWaitTime +UrlConfig=UrlConfig +BucServiceAddress=BucServiceAddress +HelpDocumentUrl=HelpDocumentUrl +HomepageDomain=HomepageDomain +HomepageUrl=HomepageUrl +parametersConfig=parametersConfig +DefaultServiceParameters=DefaultServiceParameters +BatchAddressTip=BatchAddressTip +ConsumerAddress=ConsumerAddress +AccessControlTip=AccessControlTip +access=access +Allowed=Allowed +Forbidden=Forbidden +allow=allow +forbid=forbid +confirm.allow=confirm.allow +confirm.forbid=\u786E\u8BA4\u7981\u6B62\u8BBF\u95EE?
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +batch.allow=batch.allow +batch.forbid=batch.forbid +confirm.batch.allow=confirm.batch.allow +confirm.batch.forbid=\u786E\u8BA4\u7981\u6B62\u6240\u9009\u9879\u8BBF\u95EE?
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +only.allow=only.allow +only.forbid=only.forbid +confirm.only.allow=\u786E\u8BA4\u53EA\u5141\u8BB8\u9009\u4E2D\u9879\u8BBF\u95EE?
\u5176\u5B83\u672A\u9009\u4E2D\u9879\u53CA\u4EE5\u540E\u65B0\u589E\u9879\u5C06\u5168\u90E8\u53D8\u4E3A\u7981\u6B62\u8BBF\u95EE\u3002
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +confirm.only.forbid=\u786E\u8BA4\u53EA\u7981\u6B62\u9009\u4E2D\u9879\u8BBF\u95EE?
\u5176\u5B83\u672A\u9009\u4E2D\u9879\u53CA\u4EE5\u540E\u65B0\u589E\u9879\u5C06\u5168\u90E8\u53D8\u4E3A\u5141\u8BB8\u8BBF\u95EE\u3002
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +Choose=Choose +userown=userown +sysmanage.userown=sysmanage.userown +SingleServiceTip=SingleServiceTip +MultiServiceTip=MultiServiceTip +RouteNameTip=\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-200\u4e2a\u5b57\u7b26\u7ec4\u6210 +RoutePriorityTip=RoutePriorityTip +RouteServiceTip=RouteServiceTip +#RouteServiceTip=\u670d\u52a1\u63a5\u53e3\u540d\u53ef\u4ee5\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u53ea\u652f\u6301\u4e00\u4e2a*\u7b26\u4e14\u8981\u5728\u63a5\u53e3\u672b\u5c3e\uff08\u5206\u7ec4\u3001\u7248\u672c\u4e0d\u652f\u6301\u901a\u914d\u7b26\uff09 +RouteMethodTip=\u53ea\u6709Dubbo2.0.0\u4ee5\u4e0a\u7248\u672c\u7684\u670d\u52a1\u6d88\u8d39\u7aef\u652f\u6301\u6309\u65b9\u6cd5\u8def\u7531\uff0c\u591a\u4e2a\u65b9\u6cd5\u540d\u7528\u9017\u53f7\u5206\u9694 +RouteClusterTip=\u53ef\u901a\u8fc7\u83dc\u5355"\u670d\u52a1\u63a7\u5236"->"\u670d\u52a1\u5668\u96c6\u7fa4"\u7ba1\u7406 +RouteMatchTip=RouteMatchTip +RouteFilterTip=RouteFilterTip +RouteHostTip=RouteHostTip +RouteApplicationTip=RouteApplicationTip +RouteResult=RouteResult +preview=preview +ConsumerApplication=ConsumerApplication +ConsumerCluster=ConsumerCluster +ConsumerHost=ConsumerHost +ConsumerVersion=ConsumerVersion +ConsumerGroup=ConsumerGroup +ProviderApplication=ProviderApplication +ProviderCluster=ProviderCluster +ProviderProtocol=ProviderProtocol +ProviderHost=ProviderHost +ProviderPort=ProviderPort +ProviderVersion=ProviderVersion +ProviderGroup=ProviderGroup +MatchRule=MatchRule +FilterRule=FilterRule +routeName=routeName +routeRule=routeRule +Match=Match +Mismatch=Mismatch +GetMethods=GetMethods +FeatureName=FeatureName +Features=Features +Disable=Disable +Enable=Enable +Enabled=Enabled +Disabled=Disabled +Unknown=Unknown +Users=Users +UsersDescription=UsersDescription +StatusList=StatusList +StatusListDescription=StatusListDescription +Operations=Operations +OperationsDescription=OperationsDescription +Accesses=Accesses +AccessesDescription=AccessesDescription +Configs=Configs +Clusters=Clusters +ClustersDescription=ClustersDescription +Weights=Weights +WeightsDescription=WeightsDescription +Agreements=Agreements +AgreementsDescription=AgreementsDescription +ConfigsDescription=ConfigsDescription +LoadBalances=LoadBalances +LoadBalancesDescription=LoadBalancesDescription +CachedList=CachedList +CachedListDescription=CachedListDescription +FailedList=FailedList +Registries=Registries +FailedListDescription=FailedListDescription +registryAddress=registryAddress +RegistriesDescription=RegistriesDescription +Help=Help +HelpDescription=HelpDescription +Providers=Providers +ProvidersDescription=ProvidersDescription +Log=Log +LogDescription=LogDescription +Services=Services +ServicesDescription=ervicesDescription +Owned=Owned +OwnedDescription=OwnedDescription +Tests=Tests +TestsDescription=TestsDescription +Documents=Documents +DocumentsDescription=DocumentsDescription +Applications=Applications +ApplicationsDescription=ApplicationsDescription +Consumers=Consumers +ConsumersDescription=ConsumersDescription +System=System +SystemDescription=SystemDescription +Routes=Routes +Route=Route +RoutesDescription=RoutesDescription +Connections=Connections +ConnectionsDescription=ConnectionsDescription +RegistryAddress=RegistryAddress +RegisterUsername=RegisterUsername +RegisterDate=RegisterDate +subscribeDate=subscribeDate +Statistics=Statistics +CheckConnection=CheckConnection +CheckDatabase=CheckDatabase +queryUrl=queryUrl +Status=Status +notify=notify +notified=notified +unnotified=unnotified +Unuse=Unuse +NoProvider=NoProvider +NoConsumer=NoConsumer +route.consumer.not.match=route.consumer.not.match +#labels +all=all +service=service +application=application +recursive=recursive +layer=layer +address=address +dubbo=dubbo +version=version +group=group +url=url +parameters=parameters +provider=provider +consumer=consumer +registry=registry +username=username +created=created +modified=modified +register.date=register.date +type=type +static=static +dynamic=dynamic +status=status +enabled=enabled +disabled=disabled +check=check +operation=operation +role=role +provider=provider +consumer=consumer +consumer.address=consumer.address +no.provider=no.provider +no.consumer=no.consumer +ok=ok +warn=warn +error=error +success=success +failure=failure +operation.success=operation.success +operation.failure=operation.failure +isRegistered=isRegistered +isCached=isCached +isCached.true=isCached.true +isCached.false=isCached.false +isSubscribed=isSubscribed +isSubscribed.true=isSubscribed.true +isSubscribed.false=isSubscribed.false +isSubscribed.unmatch=isSubscribed.unmatch +#operations +search=search +query=query +show=show +add=add +addMock=addMock +multiadd=multiadd +edit=edit +save=save +delete=delete +enable=enable +disable=disable +recover=recover +reload=reload +reconnect=reconnect +renotify=renotify +tostatic=tostatic +todynamic=todynamic +favorite=favorite +register=register +subscribe=subscribe +logout=logout +back=back +cancel=cancel +confirm=confirm +batch.add=batch.add +batch.multiservices.add=batch.multiservices.add +batch.delete=batch.delete +batch.enable=batch.enable +batch.disable=batch.disable +batch.recover=batch.recover +batch.reconnect=batch.reconnect +batch.renotify=batch.renotify +batch.tostatic=batch.tostatic +batch.todynamic=batch.todynamic +batch.favorite=batch.favorite +batch.reload=batch.reload +confirm.batch.disable=confirm.batch.disable +confirm.batch.enable=confirm.batch.enable +#prompts +please.input.service=please.input.service +please.input.application=please.input.application +please.input.address=please.input.address +please.input.layer=please.input.layer +please.input=please.input +please.select=please.select +empty.list=empty.list +not.found=not.found +show.all=show.all +confirm.logout=confirm.logout +confirm.delete=\u786e\u5b9a\u5220\u9664?
\u5220\u9664\u540E\u5C06\u4E0D\u53EF\u8FD8\u539F\u3002 +confirm.enable=confirm.enable? +confirm.disable=confirm.disable? +confirm.recover=confirm.recover? +confirm.reconnect=confirm.reconnect? +confirm.renotify=confirm.renotify? +confirm.tostatic=confirm.tostatic? +confirm.todynamic=confirm.todynamic? +confirm.batch.delete=\u786e\u5b9a\u5220\u9664\u6240\u9009\u9879?
\u5220\u9664\u540E\u5C06\u4E0D\u53EF\u8FD8\u539F\u3002 +confirm.batch.enable=confirm.batch.enable +confirm.batch.disable=confirm.batch.disable +confirm.batch.recover=confirm.batch.recover +confirm.batch.reload=confirm.batch.reload +confirm.batch.reconnect=confirm.batch.reconnect +confirm.batch.renotify=confirm.batch.renotify +confirm.batch.tostatic=confirm.batch.tostatic +confirm.batch.todynamic=confirm.batch.todynamic +current.user=current.user +CheckProviderLocalAddress=CheckProviderLocalAddress +CheckProviderApplicationDifferent=CheckProviderApplicationDifferent +CheckProviderAddressMismatch=CheckProviderAddressMismatch +CheckConnectionDisconnected=CheckConnectionDisconnected +CheckConnectionExpired=CheckConnectionExpired +CheckDatabaseMiss=CheckDatabaseMiss +CheckDatabaseMismatch=CheckDatabaseMismatch +CheckDatabaseDirty2Registered=CheckDatabaseDirty2Registered +CheckDatabaseDirty2Subscribed=CheckDatabaseDirty2Subscribed +CheckCacheRegistered=CheckCacheRegistered +CheckCacheConsumer=CheckCacheConsumer +CheckCacheProvider=CheckCacheProvider +CheckCacheSubscribed=CheckCacheSubscribed +CheckCacheService=CheckCacheService +select.all=select.all +ip.address=ip.address +registry.newservice=registry.newservice +add.new.provider=add.new.provider +add.new.route=add.new.route +message.search.noresult=message.search.noresult +provide.service=provide.service +service.method=service.method +startegy=startegy +route.name=route.name +rule.match=rule.match +rule.filtrate=rule.filtrate +priority=priority +routed=routed +unrouted=unrouted +page.total=page.total +page.records=page.records +page.ordinal=page.ordinal +page.page=page.page +page.next=page.next +page.prev=page.prev +page.first=page.first +page.last=page.last +page.line=page.line +methodName=methodName +proview=proview +cluster.name=cluster.name +cluster.address=cluster.address +sameserviceadd=sameserviceadd +whitelist=whitelist +blacklist=blacklist +toWhiteAndBlackList=toWhiteAndBlackList +obtainProviderAddress=obtainProviderAddress +towhitelist=towhitelist +toblacklist=toblacklist +enable=enable +disable=disable +copy=copy +batch.enable=batch.enable +batch.disable=batch.disable +batch.towhitelist=batch.towhitelist +batch.toblacklist=batch.toblacklist +confirm.favorites=confirm.favorites +confirm.batch.towhitelist=\u786e\u8ba4\u52a0\u5165\u767d\u540d\u5355?
\u5c06\u7981\u6b62\u4e0d\u5728\u767d\u540d\u5355\u5185\u7684\u6240\u6709\u6d88\u8d39\u8005\u8bbf\u95ee\uff0c\u9ed1\u540d\u5355\u5931\u6548\u3002 +confirm.batch.toblacklist=\u786e\u8ba4\u52a0\u5165\u9ed1\u540d\u5355?
\u5982\u679c\u6ca1\u6709\u767d\u540d\u5355\uff0c\u5c06\u7981\u6b62\u5728\u9ed1\u540d\u5355\u5185\u7684\u6240\u6709\u5176\u5b83\u6d88\u8d39\u8005\u8bbf\u95ee\u3002 +confirm.enable=confirm.enable +confirm.disable=confirm.disable +confirm.edit=confirm.edit +confirm.disableFeature=confirm.disableFeature +confirm.enableFeature=confirm.enableFeature +confirmDeleteOwner=confirmDeleteOwner +generic=generic +doubling=doubling +update=update +welcome=welcome +approve=approve +chinese.simple=chinese.simple +chinese.tradition=chinese.tradition +register.service=register.service +erratum.guide=erratum.guide +preview.guide=preview.guide +sysinfo.status=sysinfo.status +sysinfo.registries=sysinfo.registries +sysinfo.connections=sysinfo.connections +sysinfo.cached=sysinfo.cached +sysinfo.failed=sysinfo.failed +sysinfo.operations=sysinfo.operations +sysinfo.logs=sysinfo.logs +sysinfo.versions=sysinfo.versions +sysinfo.dumps=sysinfo.dumps +sysinfo.envs=sysinfo.envs +sysinfo.helps=sysinfo.helps +system.management=system.management +sysmanage.users=sysmanage.users +sysmanage.configs=sysmanage.configs +sysmanage.features=sysmanage.features +system.function.control=system.function +personal.set=personal.set +modify.personalinfo=modify.personalinfo +modify.personal.password=modify.personal.password +operation.operateaddress=operation.operateaddress +operation.operatetype=operation.operatetype +operation.datatype=operation.datatype +operation.data=operation.data +operation.createtime=operation.createtime +operation.clean=operation.clean +passwd.oldwrong=passwd.oldwrong +failed=failed +failed_type=failed_type +failed_data=failed_data +failed_sync=failed_sync +failed_subscribe=failed_subscribe +failed_notify=failed_notify +failed_collect=failed_collect +failed_register=failed_register +failed_redirect=failed_redirect +failed_disconnect=failed_disconnect +clientAddress=clientAddress +overrideAddress=overrideAddress +serviceInfo=serviceInfo +consumerAddress=consumerAddress +providerAddress=providerAddress +registryAddress=registryAddress +serviceName=serviceName +serviceUrl=serviceUrl +overrideConsumerAddress=overrideConsumerAddress +overrideProviderAddress=overrideProviderAddress +tipConsumerAddress=tipConsumerAddress +tipProviderAddress=tipProviderAddress +tipProviderAddress=tipProviderAddress +logs=logs +logs.file=logs.file +logs.size=logs.size +logs.modify=logs.modify +logs.level=logs.level +change.log.level=change.log.level +logs.confirmChangeLogLevel=logs.confirmChangeLogLevel +cached=cached +cached.type=cached.type +cached.data=cached.data +cached.reload=cached.reload +batch.cached.reload=batch.cached.reload +cached.recover=cached.recover +batch.cached.recover=batch.cached.recover +servicePrivilege=servicePrivilege +creator=creator +name=name +department=department +email=email +phone=phone +alitalk=alitalk +password=password +roleR=roleR +roleA=roleA +roleG=roleG +roleDescR=roleDescR +roleDescA=roleDescA +roleDescG=roleDescG +oldPassword=oldPassword +newPassword=newPassword +reset=reset +restPassword=restPassword +confirmNewPassword=confirmNewPassword +owns=owns +confirmPassword=confirmPassword +generatePassword=generatePassword +displayName=displayName +locale=locale +privilegeTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7(,)\u5206\u9694\uff0c\u901a\u914d\u7b26\u7528\u661f\u53f7(*)\u8868\u793a\uff0c\u53ea\u80fd\u5728\u6bcf\u4e2a\u503c\u7684\u672a\u5c3e\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u88ab\u6388\u4e0e\u7684\u6743\u9650\u4e0d\u80fd\u8d85\u51fa\u5f53\u524d\u7ba1\u7406\u4eba\u5458\u7684\u6743\u9650 +displayNameTip=\u7528\u6237\u59d3\u540d\uff0c\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-50\u4e2a\u5b57\u7b26\u7ec4\u6210 +emailTip=\u7528\u4e8e\u63a5\u6536\u7cfb\u7edf\u90ae\u4ef6\uff0c\u53ef\u4ee5\u8f93\u5165\u591a\u4e2a\u90ae\u4ef6\u5730\u5740\uff0c\u4f7f\u7528\u82f1\u6587\u5206\u53f7\u5206\u9694(;)\uff0c \u5f62\u5982 foo1@163.comj;foo2@gmail.com +userLocaleTip=\u53d1\u9001\u7cfb\u7edf\u90ae\u4ef6\u65f6\uff0c\u5c06\u6839\u636e\u7528\u6237\u4f7f\u7528\u7684\u8bed\u8a00\u53d1\u9001\u4e0d\u540c\u8bed\u8a00\u7684\u90ae\u4ef6\u5185\u5bb9 +DisplayNameTip=DisplayNameTip +EmailTip=EmailTip +UserLocaleTip=UserLocaleTip +missRequestParameters=missRequestParameters +haveNoRootPrivilege=haveNoRootPrivilege +confirmReloadCache=confirmReloadCache +confirmDeleteRegistry=confirmDeleteRegistry +confirmAutoRedirectRegistry=confirmAutoRedirectRegistry +confirmDeleteExpiredRegistry=confirmDeleteExpiredRegistry +confirmSyncRegistry=confirmSyncRegistry +confirm.toblacklist=\u786e\u8ba4\u52a0\u5165\u9ed1\u540d\u5355?
\u5982\u679c\u6ca1\u6709\u767d\u540d\u5355\uff0c\u5c06\u7981\u6b62\u5728\u9ed1\u540d\u5355\u5185\u7684\u6240\u6709\u6d88\u8d39\u8005\u8bbf\u95ee\u3002 +confirm.towhitelist=\u786e\u8ba4\u52a0\u5165\u767d\u540d\u5355?
\u5c06\u7981\u6b62\u4e0d\u5728\u767d\u540d\u5355\u5185\u7684\u6240\u6709\u5176\u5b83\u6d88\u8d39\u8005\u8bbf\u95ee\uff0c\u9ed1\u540d\u5355\u5931\u6548\u3002 +confirm.clean.operation=confirm.clean.operation +autoRedirect=autoRedirect +deleteExpired=deleteExpired +sync=sync +legacies=legacies +logined=logined +dumps=dumps +Registry=Registry +Java=JDK version +Locale=Locale +OS=OS +Uptime=Uptime +Host=Host +CPU=CPU +confirmEnableUser=confirmEnableUser +confirmDisableUser=confirmDisableUser +documentTitle=documentTitle +documentLink/documentPage=documentLink/documentPage +documentInternal=documentInternal +documentExternal=documentExternal +documentApi=API +documentType=documentType +documentContent=documentContent +Yes=Yes +No=No +returnValue=returnValue +throwException= +testMethodTip=\u5982\u679c\u6709\u65b9\u6cd5\u91cd\u8f7d\u6216\u4f7f\u7528Dubbo1.0.x\u7248\u672c\u7684\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u9700\u5199\u5168\u65b9\u6cd5\u7b7e\u540d\uff0c\u5982\uff1afindBy(int,java.lang.String)\uff0c\u5426\u5219\u53ea\u9700\u65b9\u6cd5\u540d\uff0c\u5982\uff1afindBy +testJsonTip=JSON\u683c\u5f0f\uff1a\u5b57\u7b26\u4e32\u7528\u53cc\u5f15\u53f7\u8868\u793a\uff0c\u5982\uff1a"\u5b57\u7b26\u4e32"\uff0c\u6570\u5b57\u548cBoolean\u503c\u4e0d\u7528\u5f15\u53f7\uff0c\u5982\uff1a123 \u548c true \u6216 false\uff0cPOJO\u5bf9\u8c61\u6216Map\u7528\u5927\u62ec\u53f7\u8868\u793a\uff0c\u5982\uff1a{"\u5c5e\u6027\u540d1": "\u5c5e\u6027\u503c1", "\u5c5e\u6027\u540d2": "\u5c5e\u6027\u503c2"}\uff0c\u6570\u7ec4\u6216List\u6216Set\u7528\u65b9\u62ec\u53f7\u8868\u793a\uff0c\u5982\uff1a["\u503c1", "\u503c2"] +testParametersTip=\u5f53\u4e3a\u65e0\u53c2\u6570\u65b9\u6cd5\u65f6\u53c2\u6570\u503c\u53ef\u4ee5\u4e0d\u586b\uff0c\u53c2\u6570\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testResultTip=\u5f53\u4e3avoid\u65b9\u6cd5\u65f6\u7ed3\u679c\u53ef\u4ee5\u4e0d\u586b\uff0c\u629b\u51fa\u5f02\u5e38\u4f7f\u7528\u5f02\u5e38\u7c7b\u5168\u540d\u8868\u793a\uff0c\u8fd4\u56de\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testAutoRunTip=\u5982\u679c\u8bbe\u7f6e\u4e3a\u81ea\u52a8\u8fd0\u884c\uff0c\u82e5\u8be5\u670d\u52a1\u5df2\u6ce8\u518c\u6216\u65b0\u6ce8\u518c\uff0c\u5219\u81ea\u52a8\u8fd0\u884c\u6b64\u6d4b\u8bd5\u7528\u4f8b\uff0c\u8fd0\u884c\u5931\u8d25\uff0c\u5c06\u53d1\u9001\u90ae\u4ef6 +confirmRunTest=confirmRunTest +confirm.runAll=confirm.runAll +loadBalanceStrategy=loadBalanceStrategy +random=random +roundrobin=roundrobin +leastactive=leastactive +testName=testName +operator=operator +dataFormat=dataFormat +resultType=resultType +resultController=resultController +autoRun=autoRun +manualRun=manualRun +run=run +runAll=runAll +expected=expected +actual=actual +reRun=reRun +startDate=startDate +console=console +total=total +delta=delta +expired=expired +alived=alived +redirect=redirect +current=current +#overrides +override.config=override.config +override.mock=override.mock +parameter=parameter +parameter.key=parameter.key +parameter.value=parameter.value +parameter.tip=\u65b9\u6cd5\u7ea7\u914d\u7f6e\u5982\uff1afindPerson.timeout=1000 +mock.all.method=\u6240\u6709\u65b9\u6cd5\u7684Mock\u503c +mock.method=mock.method +mock.value=mock.value +mock.tip=\u793a\u4f8b\uff1areturn null/empty/JSON\u6216throw com.foo.BarException +protocol=protocol +host=host +port=port +interface=interface +version=version +group=group +methods=methods +category=category +application=application +owner=owner +cluster=cluster +loadbalance=loadbalance +timeout=timeout +retries=retries +threads=threads +connections=connections +accepts=accepts +actives=actives +executes=executes +check=check +side=side +pid=pid +timestamp=timestamp +dubbo=dubbo +anyhost=anyhost +weight=weight +weight.doubling=weight.doubling +weight.halving=weight.halving +confirm.weight.doubling=confirm.weight.doubling +confirm.weight.halving=confirm.weight.halving +batch.weight.doubling=batch.weight.doubling +batch.weight.halving=batch.weight.halving +confirm.batch.weight.doubling=confirm.batch.weight +confirm.batch.weight.halving=confirm.batch.weight +NoSuchOperationData=NoSuchOperationData +CanNotDeleteDynamicData=CanNotDeleteDynamicData +HaveNoServicePrivilege=HaveNoServicePrivilege +dynamic.parameters.tip=dynamic.parameters.tip +default.owner=Owner +logger=logger +default.server=default.server +default.actives=default.actives +default.client=default.client +default.connections=default.connections diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh.properties b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh.properties new file mode 100644 index 0000000..83e8753 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh.properties @@ -0,0 +1,802 @@ +# +# 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. +# + +#menus +home=\u9996\u9875 +stat=\u7edf\u8ba1 +revision=\u4fee\u8ba2\u7248\u672c +connectionNum=\u8fde\u63a5\u6570 +serviceNum=\u670d\u52a1\u6570 +providerNum=\u63d0\u4f9b\u8005\u6570 +consumerNum=\u6d88\u8d39\u8005\u6570 +applicationNum=\u5e94\u7528\u6570 +about=\u5173\u4e8e +help=\u5e2e\u52a9 +favorites=\u6536\u85cf\u5939 +histories=\u5386\u53f2\u8bb0\u5f55 +governance=\u670d\u52a1\u6cbb\u7406 +applications=\u5e94\u7528 +efferents=\u4f9d\u8d56 +afferents=\u88ab\u4f9d\u8d56 +services=\u670d\u52a1 +references=\u5f15\u7528\u670d\u52a1 +addresses=\u673a\u5668 +providers=\u63d0\u4f9b\u8005 +dependencies=\u4f9d\u8d56\u5173\u7cfb +layers=\u5206\u5c42 +clusters=\u96c6\u7fa4 +consumers=\u6d88\u8d39\u8005 +accesses=\u8BBF\u95EE\u63A7\u5236 +routes=\u8def\u7531\u89C4\u5219 +weights=\u6743\u91cd\u8C03\u8282 +loadbalances=\u8d1f\u8f7d\u5747\u8861 +tests=\u6d4b\u8bd5 +mocks=\u6a21\u62df +overrides=\u52a8\u6001\u914d\u7f6e +documents=\u6587\u6863 +owners=\u8d1f\u8d23\u4eba +agreements=\u534f\u5b9a +approvals=\u4e0a\u7ebf\u5ba1\u6279 +operations=\u64cd\u4f5c\u65e5\u5fd7 +users=\u7528\u6237 +envs=\u7cfb\u7edf\u73af\u5883 +helps=\u5e2e\u52a9\u6587\u6863 +registries=\u6ce8\u518c\u4e2d\u5fc3 +configs=\u7cfb\u7edf\u53c2\u6570 +features=\u7cfb\u7edf\u529f\u80fd +connections=\u8fde\u63a5 +statuses=\u7CFB\u7EDF\u72B6\u6001 +failed=\u5931\u8d25\u8bb0\u5f55 +cached=\u7f13\u5b58\u8bb0\u5f55 +dumps=\u5feb\u7167 +InvalidIp=\u65e0\u6548\u0069\u0070\u5730\u5740 +versions=Dubbo\u7248\u672c +logs=\u65e5\u5fd7 +infos=\u4fee\u6539\u4e2a\u4eba\u4fe1\u606f +passwds=\u4fee\u6539\u4e2a\u4eba\u5bc6\u7801 +dependency.list=\u5217\u8868 +dependency.tree=\u6811\u72b6 +dependency.graph=\u56fe\u5f62 +dependency.efferent=\u4f9d\u8d56 +dependency.afferent=\u88ab\u4f9d\u8d56 +provided=\u63d0\u4f9b\u670d\u52a1 +consumed=\u6d88\u8d39\u670d\u52a1 +select=\u9009\u62e9 +clean=\u6e05\u9664 +information=\u4fe1\u606f +control=\u63a7\u5236 +summary=\u6c47\u603b +consumer.application=\u6d88\u8d39\u8005\u5e94\u7528 +response.time=\u54cd\u5e94\u65f6\u95f4 +sysinfo.infos=\u7cfb\u7edf\u4fe1\u606f +helps.document=\u6587\u6863 +helps.requirement=\u9700\u6c42 +helps.source=\u6e90\u4ee3\u7801 +connections=\u5957\u63a5\u5b57\u8fde\u63a5 +ReconnectUnkwown=\u91cd\u8fde\u6240\u6709\u672a\u77e5\u8fde\u63a5 +confirmReconnectConnection=\u786e\u8ba4\u91cd\u5efa\u8fde\u63a5 +confirmRedirectRegistry=\u786e\u8ba4\u91cd\u5b9a\u5411\u6ce8\u518c\u4e2d\u5fc3 +confirmReconnectUnknownConnection=\u786e\u8ba4\u91cd\u8fde\u672a\u77e5\u7684\u8fde\u63a5 +status.resourcename=\u8d44\u6e90\u540d\u79f0 +status.status=\u72b6\u6001 +status.message=\u4fe1\u606f +status.description=\u63cf\u8ff0 +status.memoryStatus=\u5185\u5b58 +status.memoryStatusDesc=\u53ea\u76d1\u63a7Heap\u5185\u5b58\uff0c\u5982\u679c\u7a7a\u95f2\u5185\u5b58\u4e0d\u8db31M\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.threadpoolStatus=\u7ebf\u7a0b\u6c60 +status.threadpoolStatusDesc=\u53ea\u76d1\u63a7\u6ce8\u518c\u8ba2\u9605\u4e3b\u4e1a\u52a1\u7ebf\u7a0b\u6c60\uff0c\u5982\u679c\u7a7a\u95f2\u7ebf\u7a0b\u5c11\u4e8e1\u4e2a\uff0c\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.failureStatus=\u5931\u8d25\u8bb0\u5f55 +status.failureStatusDesc=\u5f53\u6709\u4efb\u4f55\u5931\u8d25\u8bb0\u5f55\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.cacheStatus=\u7f13\u5b58 +status.cacheStatusDesc=\u5982\u679c\u7f13\u5b58\u4e0e\u6570\u636e\u5e93\u4e0d\u4e00\u81f4\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.timerStatus=\u5b9a\u65f6\u5668 +status.timerStatusDesc=\u5f53\u5b9a\u65f6\u5668\u672a\u6b63\u786e\u542f\u52a8\uff0c\u6216\u88ab\u4e0d\u6b63\u5e38\u53d6\u6d88\uff0c\u5219\u62a5\u9519\uff0c\u5426\u5219\u6b63\u5e38 +status.socketStatus=\u5957\u63a5\u5b57 +status.socketStatusDesc=\u5f53\u5957\u63a5\u53e3\u5f00\u542f\u4e0d\u4e86\u6216\u5df2\u88ab\u5360\u7528\u65f6\u62a5\u9519\uff0c\u5f53\u8fde\u63a5\u6570\u7b49\u4e8e\u6700\u5927\u503c\u65f6\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.loadStatus=\u8d1f\u8f7d +status.loadStatusDesc=\u5982\u679c\u8d1f\u8f7d\u5927\u4e8eCPU\u4e2a\u6570\u5219\u8b66\u544a\uff0c\u5982\u679c\u7cfb\u7edf\u4e0d\u652f\u6301\u67e5\u8be2\u8d1f\u8f7d\u5219\u4e0d\u542f\u7528\uff0c\u5426\u5219\u6b63\u5e38 +status.datasourceStatus=\u6570\u636e\u5e93 +status.datasourceStatusDesc=\u53d1\u9001\u4e00\u6761\u7b80\u5355\u67e5\u8be2SQL\uff0c\u6267\u884c\u6210\u529f\u5219\u6b63\u5e38\uff0c\u5426\u5219\u62a5\u9519 +status.registryStatus=\u6CE8\u518C\u4E2D\u5FC3 +status.registryStatusDesc=\u5982\u679C\u8FDE\u4E0D\u4E0A\u6CE8\u518C\u4E2D\u5FC3\u5219\u62A5\u9519\uFF0C\u5426\u5219\u6B63\u5E38 +status.monitorStatus=\u76d1\u89c6\u5668 +status.monitorStatusDesc=\u76d1\u89c6\u5668 +status.summaryStatus=\u6c47\u603b +status.summaryStatusDesc=\u6709\u72b6\u6001\u6c47\u603b\uff0c\u5ffd\u7565\u672a\u542f\u7528\u7684\u72b6\u6001\uff0c\u53ea\u8981\u6709\u4e00\u4e2a\u62a5\u9519\uff0c\u5219\u62a5\u9519\uff0c\u53ea\u8981\u6709\u4e00\u4e2a\u8b66\u544a\uff0c\u5219\u8b66\u544a\uff0c\u5168\u90e8\u6b63\u5e38\u5219\u6b63\u5e38 +status.warmupStatus=\u8fd0\u884c\u72b6\u6001 +status.warmupStatusDesc=\u5904\u4e8ewarmup\u72b6\u6001\u65f6\uff0c\u810f\u6570\u636e\u68c0\u6d4b\u3001\u91cd\u5b9a\u5411\u3001\u4e8b\u4ef6\u53d8\u66f4\u5b9a\u65f6\u5668\u5747\u4e0d\u5de5\u4f5c,\u4e0d\u63a8\u9001\u53d8\u66f4 +status.OK=\u6b63\u5e38 +status.WARN=\u8b66\u544a +status.ERROR=\u9519\u8bef +status.UNKNOWN=\u672a\u77e5 +Status0=Unknow +Status1=OK +Status2=OK +Status3=ERROR +Status4=FATAL +Status5=UNKNOW +mock=\u964d\u7ea7 +force.mocked=\u5DF2\u5C4F\u853D +fail.mocked=\u5DF2\u5BB9\u9519 +no.mocked=\u672A\u964D\u7EA7 +force.mock=\u5c4f\u853d +fail.mock=\u5bb9\u9519 +cancel.mock=\u6062\u590d +confirm.force.mock=\u786e\u8ba4\u5c4f\u853d\u8be5\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.fail.mock=\u786e\u8ba4\u5bf9\u8be5\u670d\u52a1\u5bb9\u9519\uff1f
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.cancel.mock=\u786e\u8ba4\u6062\u590d\u8be5\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +batch.force.mock=\u6279\u91cf\u5c4f\u853d +batch.fail.mock=\u6279\u91cf\u5bb9\u9519 +batch.cancel.mock=\u6279\u91cf\u6062\u590d +confirm.batch.force.mock=\u786e\u8ba4\u6279\u91cf\u5c4f\u853d\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.batch.fail.mock=\u786e\u8ba4\u6279\u91cf\u5bf9\u670d\u52a1\u5bb9\u9519\uff1f
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.batch.cancel.mock=\u786e\u8ba4\u6279\u91cf\u6062\u590d\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +all.force.mock=\u7F3A\u7701\u5c4f\u853d +all.fail.mock=\u7F3A\u7701\u5bb9\u9519 +all.cancel.mock=\u7F3A\u7701\u6062\u590d +confirm.all.force.mock=\u786e\u8ba4\u7F3A\u7701\u5c4f\u853d\u8be5\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.all.fail.mock=\u786e\u8ba4\u7F3A\u7701\u5bf9\u8be5\u670d\u52a1\u5bb9\u9519\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.all.cancel.mock=\u786e\u8ba4\u7F3A\u7701\u6062\u590d\u8be5\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +agreement.invocation.quantity=\u4e00\u5929\u8c03\u7528\u91cf +agreement.tps=TPS\u4e0a\u9650 +response.time=\u54cd\u5e94\u65f6\u95f4 +agreement.availability=\u53ef\u7528\u7387 +layer.name=\u5206\u5c42\u540d\u79f0 +layer.value=\u6570\u5b57\u7b49\u7ea7 +layer.arch=\u5206\u5c42\u67b6\u6784 +loadBalanceStrategy=\u8d1f\u8f7d\u5747\u8861\u7b56\u7565 +ServiceName=\u670d\u52a1\u540d +cluster.name=\u96c6\u7fa4\u540d +cluster.address=\u96c6\u7fa4\u673a\u5668\u5730\u5740 +property.name=\u5c5e\u6027\u540d +property.value=\u5c5e\u6027\u503c +property.count=\u5c5e\u6027\u6570\u91cf +getMethods=\u83b7\u53d6\u670d\u52a1\u65b9\u6cd5 +getAddresses=\u83b7\u53d6\u63d0\u4f9b\u8005\u5730\u5740 +Edit=\u7f16\u8f91 +Username=\u7528\u6237\u540d +Priority=\u4f18\u5148\u7ea7 +ConnectionAddress=\u8fde\u63a5\u5730\u5740 +Role=\u89d2\u8272 +Reconnect=\u91cd\u8fde +Redirect=\u91cd\u5b9a\u5411 +staff.query=\u5185\u7f51\u67e5\u8be2 +configKey=\u914d\u7f6e\u9879 +configValue=\u914d\u7f6e\u9879\u503c +Preview=\u9884\u89c8 +routeselect=\u8def\u7531\u9884\u89c8\uff08\u9009\u62e9\u6d88\u8d39\u8005\uff09 +AllOperations=\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeOneMonthOperations=\u4e00\u4e2a\u6708\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeThreeMonthOperations=\u4e09\u4e2a\u6708\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeHalfYearOperations=\u534a\u5e74\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeOneYearOperations=\u4e00\u5e74\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +PleaseInput=\u8bf7\u8f93\u5165 +BulletinConfig=\u516c\u544a\u914d\u7f6e +BulletinMessage=\u516c\u544a\u4fe1\u606f +MailConfig=\u90ae\u7bb1\u914d\u7f6e +MailEnabled=\u662f\u5426\u542f\u7528\u90ae\u7bb1 +MailHost=\u90ae\u4ef6\u670d\u52a1\u5668\u4e3b\u673a +MailPort=\u90ae\u4ef6\u670d\u52a1\u5668\u7aef\u53e3 +MailFrom=\u90ae\u4ef6\u53d1\u4ef6\u4eba\u5730\u5740 +MailAuth=\u90ae\u7bb1\u662f\u5426\u9700\u8981\u767b\u5f55 +MailUsername=\u90ae\u7bb1\u767b\u5f55\u7528\u6237\u540d +MailPassword=\u90ae\u7bb1\u767b\u5f55\u5bc6\u7801 +LoginConfig=\u767b\u5f55\u914d\u7f6e +AllowAnonymousLogin=\u5141\u8bb8\u533f\u540d\u767b\u5f55 +AllowLegacyLogin=\u5141\u8bb8\u9057\u7559\u7cfb\u7edf\u767b\u5f55 +RouteEnabled=\u662f\u5426\u5f00\u542f\u8def\u7531\u529f\u80fd +WarmupEnabled=\u662f\u5426\u8fdb\u5165\u9884\u70ed\u72b6\u6001 +LogConfig=\u65e5\u5fd7\u914d\u7f6e +LogLevel=\u65e5\u5fd7\u7ea7\u522b +RedirectConfig=\u91cd\u5b9a\u5411\u914d\u7f6e +AutoRedirectInterval=\u81ea\u52a8\u91cd\u5b9a\u5411\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +AutoRedirectThreshold=\u80fd\u591f\u81ea\u52a8\u91cd\u5b9a\u5411\u7684\u8fde\u63a5\u4e0b\u754c +AutoRedirectToleratePercent=\u81ea\u52a8\u91cd\u5b9a\u5411\u65f6\u8fde\u63a5\u6570\u504f\u5dee\u5bb9\u5fcd\u767e\u5206\u6bd4 +ManualRedirect=\u91cd\u5b9a\u5411{0}\u4e2a +LimitConfig=\u8d44\u6e90\u9650\u5236\u914d\u7f6e +MaxThreadSize=\u6700\u5927\u7ebf\u7a0b\u6570 +MaxConnectionSize=\u6700\u5927\u8fde\u63a5\u6570 +MaxCacheSize=\u6700\u5927\u7f13\u5b58\u6570 +MaxMailSize=\u6700\u5927\u90ae\u4ef6\u961f\u5217\u6570 +TimerConfig=\u5b9a\u65f6\u5668\u914d\u7f6e +AlivedCheckInterval=\u6ce8\u518c\u4e2d\u5fc3\u5b58\u6d3b\u72b6\u6001\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +ChangedCheckInterval=\u6570\u636e\u53d8\u66f4\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +FailedRetryInterval=\u5931\u8d25\u91cd\u8bd5\u95f4\u9694(\u6beb\u79d2) +DirtyCheckInterval=\u810f\u6570\u636e\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +HeartbeatConfig=\u5fc3\u8df3\u914d\u7f6e +HeartbeatCheckInterval=\u4e0e\u5ba2\u6237\u7aef\u8fde\u63a5\u5fc3\u8df3\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +HeartbeatCheckTimeout=\u5fc3\u8df3\u8d85\u65f6\u65f6\u95f4(\u6beb\u79d2) +TimeoutConfig=\u8d85\u65f6\u914d\u7f6e +NotifyTimeout=\u4e8b\u4ef6\u63a8\u9001\u8d85\u65f6(\u6beb\u79d2) +WarmupWaitTime=\u542f\u52a8\u9884\u70ed\u65f6\u95f4(\u6beb\u79d2) +UrlConfig=URL\u914d\u7f6e +BucServiceAddress=BUC\u670d\u52a1\u5730\u5740 +HelpDocumentUrl=\u5e2e\u52a9\u6587\u6863URL +HomepageDomain=\u663e\u793a\u4e3b\u9875\u57df\u540d +HomepageUrl=\u4e3b\u9875\u5730\u5740 +parametersConfig=\u53c2\u6570\u914d\u7f6e +DefaultServiceParameters=\u7f3a\u7701\u53c2\u6570\u914d\u7f6e +BatchAddressTip=\u591a\u4e2a\u5730\u5740\u7528\u6362\u884c\u7b26\u5206\u9694\uff0c\u5730\u5740\u5fc5\u9700\u662f0.0.0.0\u5230255.255.255.255\u7684IP\u5730\u5740 +ConsumerAddress=\u6d88\u8d39\u8005\u5730\u5740 +AccessControlTip=\u767d\u540d\u5355\u4f18\u5148\uff0c\u53ea\u8981\u6709\u767d\u540d\u5355\uff0c\u5219\u767d\u540d\u5355\u751f\u6548\uff0c\u5426\u5219\u9ed1\u540d\u5355\u751f\u6548 +access=\u8BBF\u95EE +Allowed=\u5DF2\u5141\u8BB8 +Forbidden=\u5DF2\u7981\u6B62 +allow=\u5141\u8BB8 +forbid=\u7981\u6B62 +confirm.allow=\u786E\u8BA4\u5141\u8BB8\u8BBF\u95EE? +confirm.forbid=\u786E\u8BA4\u7981\u6B62\u8BBF\u95EE?
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +batch.allow=\u6279\u91CF\u5141\u8BB8 +batch.forbid=\u6279\u91CF\u7981\u6B62 +confirm.batch.allow=\u786E\u8BA4\u5141\u8BB8\u6240\u9009\u9879\u8BBF\u95EE? +confirm.batch.forbid=\u786E\u8BA4\u7981\u6B62\u6240\u9009\u9879\u8BBF\u95EE?
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +only.allow=\u53EA\u5141\u8BB8 +only.forbid=\u53EA\u7981\u6B62 +confirm.only.allow=\u786E\u8BA4\u53EA\u5141\u8BB8\u9009\u4E2D\u9879\u8BBF\u95EE?
\u5176\u5B83\u672A\u9009\u4E2D\u9879\u53CA\u4EE5\u540E\u65B0\u589E\u9879\u5C06\u5168\u90E8\u53D8\u4E3A\u7981\u6B62\u8BBF\u95EE\u3002
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +confirm.only.forbid=\u786E\u8BA4\u53EA\u7981\u6B62\u9009\u4E2D\u9879\u8BBF\u95EE?
\u5176\u5B83\u672A\u9009\u4E2D\u9879\u53CA\u4EE5\u540E\u65B0\u589E\u9879\u5C06\u5168\u90E8\u53D8\u4E3A\u5141\u8BB8\u8BBF\u95EE\u3002
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +Choose=\u8bf7\u9009\u62e9 +userown=\u8d1f\u8d23\u7684\u670d\u52a1 +sysmanage.userown=\u8d1f\u8d23\u7684\u670d\u52a1 +SingleServiceTip=\u4e00\u4e2a\u8def\u7531\u53ea\u80fd\u5e94\u7528\u4e8e\u4e00\u4e2a\u670d\u52a1\uff0c\u4e0d\u652f\u6301\u591a\u670d\u52a1\u53ca\u901a\u914d\u7b26 +MultiServiceTip=\u670d\u52a1\u63a5\u53e3\u540d\u53ef\u4ee5\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u53ea\u652f\u6301\u4e00\u4e2a*\u7b26\u4e14\u8981\u5728\u63a5\u53e3\u672b\u5c3e\uff08\u5206\u7ec4\u3001\u7248\u672c\u4e0d\u652f\u6301\u901a\u914d\u7b26\uff09 +RouteNameTip=\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-200\u4e2a\u5b57\u7b26\u7ec4\u6210 +RoutePriorityTip=\u6570\u5b57\u8d8a\u5927\u8d8a\u4f18\u5148 +RouteServiceTip=\u4e00\u4e2a\u8def\u7531\u53ea\u80fd\u5e94\u7528\u4e8e\u4e00\u4e2a\u670d\u52a1\uff0c\u4e0d\u652f\u6301\u591a\u670d\u52a1\u53ca\u901a\u914d\u7b26 +#RouteServiceTip=\u670d\u52a1\u63a5\u53e3\u540d\u53ef\u4ee5\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u53ea\u652f\u6301\u4e00\u4e2a*\u7b26\u4e14\u8981\u5728\u63a5\u53e3\u672b\u5c3e\uff08\u5206\u7ec4\u3001\u7248\u672c\u4e0d\u652f\u6301\u901a\u914d\u7b26\uff09 +RouteMethodTip=\u53ea\u6709Dubbo2.0.0\u4ee5\u4e0a\u7248\u672c\u7684\u670d\u52a1\u6d88\u8d39\u7aef\u652f\u6301\u6309\u65b9\u6cd5\u8def\u7531\uff0c\u591a\u4e2a\u65b9\u6cd5\u540d\u7528\u9017\u53f7\u5206\u9694 +RouteClusterTip=\u53ef\u901a\u8fc7\u83dc\u5355"\u670d\u52a1\u63a7\u5236"->"\u670d\u52a1\u5668\u96c6\u7fa4"\u7ba1\u7406 +RouteMatchTip=\u5f53\u6d88\u8d39\u8005\u6ee1\u8db3\u5339\u914d\u6761\u4ef6\u65f6\u4f7f\u7528\u5f53\u524d\u89c4\u5219\u8fdb\u884c\u8fc7\u6ee4 +RouteFilterTip=\u6ee1\u8db3\u8fc7\u6ee4\u89c4\u5219\u7684\u63d0\u4f9b\u8005\u5730\u5740\u5c06\u88ab\u63a8\u9001\u7ed9\u6d88\u8d39\u8005 +RouteHostTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7\u5206\u9694\uff0c\u4ee5\u661f\u53f7\u7ed3\u5c3e\u8868\u793a\u901a\u914d\u5730\u5740\u6bb5 +RouteApplicationTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7\u5206\u9694 +RouteResult=\u8def\u7531\u7ed3\u679c +preview=\u9884\u89c8 +ConsumerApplication=\u6d88\u8d39\u8005\u5e94\u7528\u540d +ConsumerCluster=\u6d88\u8d39\u8005\u96c6\u7fa4 +ConsumerHost=\u6d88\u8d39\u8005IP\u5730\u5740 +ConsumerVersion=\u6d88\u8d39\u8005\u7248\u672c\u53f7 +ConsumerGroup=\u6d88\u8d39\u8005\u540d\u79f0\u7a7a\u95f4 +ProviderApplication=\u63d0\u4f9b\u8005\u5e94\u7528 +ProviderCluster=\u63d0\u4f9b\u8005\u96c6\u7fa4 +ProviderProtocol=\u63d0\u4f9b\u8005\u534f\u8bae +ProviderHost=\u63d0\u4f9b\u8005IP\u5730\u5740 +ProviderPort=\u63d0\u4f9b\u8005\u7aef\u53e3 +ProviderVersion=\u63d0\u4f9b\u8005\u7248\u672c\u53f7 +ProviderGroup=\u63d0\u4f9b\u8005\u540d\u79f0\u7a7a\u95f4 +MatchRule=\u5339\u914d\u6761\u4ef6 +FilterRule=\u8fc7\u6ee4\u89c4\u5219 +routeName=\u8DEF\u7531\u540D\u79F0 +routeRule=\u8def\u7531\u89c4\u5219 +Match=\u5339\u914d +Mismatch=\u4e0d\u5339\u914d +GetMethods=\u83b7\u53d6\u670d\u52a1\u65b9\u6cd5 +FeatureName=\u529f\u80fd\u540d +Features=\u7cfb\u7edf\u529f\u80fd +Disable=\u7981\u7528 +Enable=\u542f\u7528 +Enabled=\u5df2\u542f\u7528 +Disabled=\u5df2\u7981\u7528 +Unknown=\u672a\u77e5 +Users=\u7528\u6237\u7ba1\u7406 +UsersDescription=\u7528\u6237\u4fe1\u606f\u7ba1\u7406 +StatusList=\u6ce8\u518c\u4e2d\u5fc3\u72b6\u6001 +StatusListDescription=\u6ce8\u518c\u4e2d\u5fc3\u7cfb\u7edf\u72b6\u6001 +Operations=\u64cd\u4f5c\u8bb0\u5f55 +OperationsDescription=\u8bb0\u5f55\u6240\u6709\u4eba\u4e3a\u7684\u64cd\u4f5c +Accesses=\u670d\u52a1\u9ed1\u767d\u540d\u5355 +AccessesDescription=\u670d\u52a1\u9ed1\u767d\u540d\u5355 +Configs=\u7cfb\u7edf\u914d\u7f6e +Clusters=\u670d\u52a1\u5668\u96c6\u7fa4 +ClustersDescription=\u7ba1\u7406\u670d\u52a1\u96c6\u7fa4\u4fe1\u606f +Weights=\u63d0\u4f9b\u8005\u6743\u91cd +WeightsDescription=\u7ba1\u7406\u63d0\u4f9b\u8005\u6743\u91cd\u4fe1\u606f +Agreements=\u670d\u52a1\u7b49\u7ea7\u534f\u5b9a +AgreementsDescription=\u670d\u52a1\u7b49\u7ea7\u534f\u5b9a +ConfigsDescription=\u7cfb\u7edf\u914d\u7f6e\u4fe1\u606f +LoadBalances=\u8d1f\u8f7d\u5747\u8861 +LoadBalancesDescription=\u8d1f\u8f7d\u5747\u8861 +CachedList=\u5185\u5b58\u7f13\u5b58 +CachedListDescription=\u6ce8\u518c\u4e2d\u5fc3\u5185\u5b58\u7f13\u5b58\u8bb0\u5f55 +FailedList=\u5931\u8d25\u8bb0\u5f55 +Registries=\u6ce8\u518c\u4e2d\u5fc3\u96c6\u7fa4 +FailedListDescription=\u5931\u8d25\u8bb0\u5f55\u5217\u8868 +registryAddress=\u6ce8\u518c\u4e2d\u5fc3\u5217\u8868 +RegistriesDescription=\u67e5\u770b\u5df2\u77e5\u7684\u6ce8\u518c\u4e2d\u5fc3 +Help=\u5e2e\u52a9 +HelpDescription=\u5e2e\u52a9 +Providers=\u670d\u52a1\u63d0\u4f9b\u8005 +ProvidersDescription=\u67e5\u770b\u6240\u6709\u670d\u52a1\u63d0\u4f9b\u8005 +Log=\u65e5\u5fd7\u6587\u4ef6 +LogDescription=\u67e5\u770b\u6ce8\u518c\u4e2d\u5fc3Log4J\u65e5\u5fd7 +Services=\u670d\u52a1\u4fe1\u606f +ServicesDescription=\u67e5\u770b\u670d\u52a1\u5df2\u6ce8\u518c\u7684\u6240\u6709\u670d\u52a1 +Owned=\u670d\u52a1\u5f52\u5c5e +OwnedDescription=\u670d\u52a1\u5f52\u5c5e +Tests=\u670d\u52a1\u6d4b\u8bd5 +TestsDescription=\u670d\u52a1\u6d4b\u8bd5\u7528\u4f8b +Documents=\u670d\u52a1\u6587\u6863 +DocumentsDescription=\u6587\u6863 +Applications=\u670d\u52a1\u5e94\u7528 +ApplicationsDescription=\u670d\u52a1\u5e94\u7528 +Consumers=\u670d\u52a1\u6d88\u8d39\u8005 +ConsumersDescription=\u67e5\u770b\u6240\u6709\u670d\u52a1\u6d88\u8d39\u8005 +System=\u7cfb\u7edf\u73af\u5883 +SystemDescription=\u7cfb\u7edf\u73af\u5883\u4fe1\u606f +Routes=\u670d\u52a1\u8def\u7531 +Route=\u8def\u7531 +RoutesDescription=\u7ba1\u7406\u670d\u52a1\u8def\u7531\u89c4\u5219 +Connections=\u5957\u63a5\u5b57\u8fde\u63a5 +ConnectionsDescription=\u8fde\u63a5 +RegistryAddress=\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740 +RegisterUsername=\u6ce8\u518c\u7528\u6237\u540d +RegisterDate=\u6ce8\u518c\u65f6\u95f4 +subscribeDate=\u8ba2\u9605\u65f6\u95f4 +Statistics=\u670d\u52a1\u5b9e\u65f6\u7edf\u8ba1 +CheckConnection=\u68c0\u67e5\u8fde\u63a5 +CheckDatabase=\u68c0\u67e5\u6570\u636e\u5e93 +queryUrl=\u8ba2\u9605\u53c2\u6570 +Status=\u72b6\u6001 +notify=\u901A\u77E5 +notified=\u5df2\u901a\u77e5 +unnotified=\u672A\u901A\u77E5 +Unuse=\u672a\u4f7f\u7528 +NoProvider=\u6ca1\u6709\u63d0\u4f9b\u8005 +NoConsumer=\u6ca1\u6709\u6d88\u8d39\u8005 +route.consumer.not.match=\u672cRoute\u4e0d\u5339\u914d\u6b64\u670d\u52a1\u6d88\u8d39\u8005\uff08\u4f1a\u8fd4\u56de\u6240\u6709\u7684\u670d\u52a1\u63d0\u4f9b\u8005\uff09 +#labels +all=\u6240\u6709 +service=\u670d\u52a1\u540d +application=\u5e94\u7528\u540d +recursive=\u5faa\u73af +layer=\u670d\u52a1\u5206\u5c42 +address=\u673a\u5668IP +dubbo=\u4f7f\u7528dubbo\u7248\u672c +version=\u670d\u52a1\u7248\u672c +group=\u670d\u52a1\u5206\u7ec4 +url=\u670d\u52a1\u5730\u5740 +parameters=\u670d\u52a1\u53c2\u6570 +provider=\u63d0\u4f9b\u8005\u5730\u5740 +consumer=\u6d88\u8d39\u8005\u5730\u5740 +registry=\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740 +username=\u7528\u6237\u540d +created=\u521b\u5efa\u65f6\u95f4 +modified=\u4fee\u6539\u65f6\u95f4 +register.date=\u6ce8\u518c\u65f6\u95f4 +type=\u7c7b\u578b +static=\u9759\u6001 +dynamic=\u52a8\u6001 +status=\u72b6\u6001 +enabled=\u5df2\u542f\u7528 +disabled=\u5df2\u7981\u7528 +check=\u68c0\u67e5 +operation=\u64cd\u4f5c +role=\u89d2\u8272 +provider=\u63d0\u4f9b\u8005 +consumer=\u6d88\u8d39\u8005 +consumer.address=\u6d88\u8d39\u8005\u5730\u5740 +no.provider=\u6ca1\u6709\u63d0\u4f9b\u8005 +no.consumer=\u6ca1\u6709\u6d88\u8d39\u8005 +ok=\u6b63\u5e38 +warn=\u8b66\u544a +error=\u51fa\u9519 +success=\u6210\u529f +failure=\u5931\u8d25 +update=\u66f4\u65b0 +operation.success=\u64cd\u4f5c\u6210\u529f\uff01 +operation.failure=\u64cd\u4f5c\u5931\u8d25\uff01 +isRegistered=\u6ce8\u518c\u7f13\u5b58 +isCached=\u670d\u52a1\u7f13\u5b58 +isCached.true=\u670d\u52a1\u5728\u7f13\u5b58\u4e2d +isCached.false=\u670d\u52a1\u672a\u540c\u6b65\u5230\u7f13\u5b58 +isSubscribed=\u8ba2\u9605\u7f13\u5b58 +isSubscribed.true=\u6b64\u6d88\u8d39\u8005\u5728\u5f53\u524d\u6ce8\u518c\u4e2d\u5fc3\u8ba2\u9605 +isSubscribed.false=\u6b64\u6d88\u8d39\u8005\u5728\u5176\u4ed6\u6ce8\u518c\u4e2d\u5fc3\u8ba2\u9605 +isSubscribed.unmatch=\u6b64\u6d88\u8d39\u8005\u5728\u6570\u636e\u5e93\u548c\u7f13\u5b58\u4e2d\u7684\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740\u4e0d\u4e00\u81f4 +#operations +search=\u641c\u7d22 +search=\u641c\u7d22 +query=\u67e5\u8be2 +show=\u67e5\u770b +add=\u65b0\u589e +addMock=\u65b0\u589eMock +multiadd=\u6279\u91cf\u65b0\u589e +edit=\u7f16\u8f91 +save=\u4fdd\u5b58 +delete=\u5220\u9664 +enable=\u542f\u7528 +disable=\u7981\u7528 +recover=\u6062\u590d +reload=\u91cd\u8f7d\u7f13\u5b58 +reconnect=\u91cd\u8fde +renotify=\u91cd\u65b0\u901a\u77e5 +tostatic=\u8f6c\u4e3a\u9759\u6001 +todynamic=\u8f6c\u4e3a\u52a8\u6001 +favorite=\u6536\u85cf +register=\u7533\u8bf7\u6ce8\u518c +subscribe=\u7533\u8bf7\u8c03\u7528 +logout=\u9000\u51fa +back=\u8fd4\u56de +cancel=\u53d6\u6d88 +confirm=\u786e\u5b9a +batch.add=\u6279\u91cf\u65b0\u589e +batch.multiservices.add=\u591a\u670d\u52a1\u65b0\u589e +batch.delete=\u6279\u91cf\u5220\u9664 +batch.enable=\u6279\u91cf\u542f\u7528 +batch.disable=\u6279\u91cf\u7981\u7528 +batch.recover=\u6279\u91cf\u6062\u590d +batch.reconnect=\u6279\u91cf\u91cd\u8fde +batch.renotify=\u6279\u91cf\u91cd\u65b0\u901a\u77e5 +batch.tostatic=\u6279\u91cf\u9759\u6001 +batch.todynamic=\u6279\u91cf\u52a8\u6001 +batch.favorite=\u6279\u91cf\u6536\u85cf +batch.reload=\u6279\u91cf\u91cd\u8f7d +confirm.batch.disable=\u786e\u8ba4\u6279\u91cf\u7981\u7528 +confirm.batch.enable=\u786e\u8ba4\u6279\u91cf\u542f\u7528 +#prompts +please.input.service=\u8bf7\u8f93\u5165\u670d\u52a1\u540d +please.input.application=\u8bf7\u8f93\u5165\u5e94\u7528\u540d +please.input.address=\u8bf7\u8f93\u5165\u673a\u5668IP +please.input.layer=\u8bf7\u8f93\u5165\u670d\u52a1\u5206\u5c42 +please.input=\u8bf7\u8f93\u5165\u8981\u64cd\u4f5c\u7684\u5185\u5bb9 +please.select=\u8bf7\u9009\u62e9\u8981\u64cd\u4f5c\u7684\u9879 +empty.list=\u6ca1\u6709\u6570\u636e\u53ef\u4ee5\u64cd\u4f5c +not.found=\u6ca1\u6709\u641c\u5230\u5339\u914d\u7684\u7ed3\u679c +show.all=\u663e\u793a\u5168\u90e8 +confirm.logout=\u786e\u5b9a\u9000\u51fa\u767b\u5f55? +confirm.delete=\u786e\u5b9a\u5220\u9664?
\u5220\u9664\u540E\u5C06\u4E0D\u53EF\u8FD8\u539F\u3002 +confirm.enable=\u786e\u5b9a\u542f\u7528? +confirm.disable=\u786e\u5b9a\u7981\u7528? +confirm.recover=\u786e\u5b9a\u6062\u590d? +confirm.reconnect=\u786e\u5b9a\u91cd\u8fde? +confirm.renotify=\u786e\u5b9a\u901a\u77e5? +confirm.tostatic=\u786e\u5b9a\u8f6c\u4e3a\u9759\u6001? +confirm.todynamic=\u786e\u5b9a\u8f6c\u4e3a\u52a8\u6001? +confirm.batch.delete=\u786e\u5b9a\u5220\u9664\u6240\u9009\u9879?
\u5220\u9664\u540E\u5C06\u4E0D\u53EF\u8FD8\u539F\u3002 +confirm.batch.enable=\u786e\u5b9a\u542f\u7528\u6240\u9009\u9879? +confirm.batch.disable=\u786e\u5b9a\u7981\u7528\u6240\u9009\u9879? +confirm.batch.recover=\u786e\u5b9a\u6062\u590d\u6240\u9009\u9879? +confirm.batch.reload=\u786e\u5b9a\u91cd\u8f7d\u5f53\u524d\u670d\u52a1? +confirm.batch.reconnect=\u786e\u5b9a\u91cd\u8fde\u6240\u9009\u9879? +confirm.batch.renotify=\u786e\u5b9a\u91cd\u65b0\u901a\u77e5\u6240\u9009\u9879? +confirm.batch.tostatic=\u786e\u5b9a\u8f6c\u4e3a\u9759\u6001\u6240\u9009\u9879? +confirm.batch.todynamic=\u786e\u5b9a\u8f6c\u4e3a\u52a8\u6001\u6240\u9009\u9879? +current.user=\u5f53\u524d\u7528\u6237 +CheckProviderLocalAddress={0}\u4E0D\u662F\u6709\u6548\u7684\u8FDC\u7A0B\u670D\u52A1\u5730\u5740\uFF0C\u8BF7\u68C0\u67E5\u63D0\u4F9B\u65B9/etc/hosts\u6620\u5C04\u662F\u5426\u6B63\u786E\u3002 +CheckProviderApplicationDifferent=\u591a\u4e2a\u4e0d\u540c\u5e94\u7528\u6ce8\u518c\u4e86\u76f8\u540c\u670d\u52a1\uff0c\u8bf7\u68c0\u67e5{0}\u4e2d\u662f\u5426\u6709\u8bef\u66b4\u9732\u3002 +CheckProviderAddressMismatch=\u670d\u52a1URL\u4e0a\u7684IP\u4e0e\u8fde\u63a5\u6ce8\u518c\u4e2d\u5fc3\u7684IP\u4e0d\u76f8\u540c +CheckConnectionDisconnected=\u8be5\u8fde\u63a5\u5df2\u65ad\u5f00\uff0c\u6570\u636e\u5e93\u810f\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckConnectionExpired=\u8be5\u8fde\u63a5\u6240\u5728\u6ce8\u518c\u4e2d\u5fc3\u5df2\u4e0d\u5b58\u5728\uff08\u6570\u636e\u4f1a\u81ea\u52a8\u5b9a\u671f\u6e05\u7406\uff09 +CheckDatabaseMiss=\u6570\u636e\u5e93\u6570\u636e\u610f\u5916\u4e22\u5931\u6b64\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u6062\u590d\u201d +CheckDatabaseMismatch=\u6570\u636e\u5e93\u4e0e\u6ce8\u518c\u7f13\u5b58\u6570\u636e\u6ce8\u518c\u5730\u5740\u4e0d\u4e00\u81f4 +CheckDatabaseDirty2Registered=\u6570\u636e\u5e93\u6bd4\u6ce8\u518c\u7f13\u5b58\u591a\u6b64\u810f\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckDatabaseDirty2Subscribed=\u6570\u636e\u5e93\u6bd4\u8ba2\u9605\u7f13\u5b58\u591a\u6b64\u810f\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckCacheRegistered=\u6ce8\u518c\u7f13\u5b58\u4e0d\u5b58\u5728\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckCacheConsumer=\u65e0\u6b64\u670d\u52a1\u7684\u670d\u52a1\u7f13\u5b58\uff0c\u4f46\u6709\u6d88\u8d39\u8005\uff01\u8bf7\u70b9\u51fb\u201c\u91cd\u8f7d\u201d +CheckCacheProvider=\u670d\u52a1\u7f13\u5b58\u65e0\u6b64\u63d0\u4f9b\u8005\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8f7d\u201d +CheckCacheSubscribed=\u8ba2\u9605\u7f13\u5b58\u4e0d\u5b58\u5728\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckCacheService=\u65e0\u6b64\u670d\u52a1\u7684\u670d\u52a1\u7f13\u5b58\uff0c\u8bf7\u70b9\u51fb\u63d0\u4f9b\u8005\u7684\u201c\u91cd\u8f7d\u201d +select.all=\u5168\u9009 +ip.address=IP\u5730\u5740 +registry.newservice=\u6ce8\u518c\u65b0\u670d\u52a1 +add.new.provider=\u6dfb\u52a0\u63d0\u4f9b\u8005 +add.new.route=\u6dfb\u52a0\u8def\u7531 +message.search.noresult=\u6ca1\u6709\u7b26\u5408\u7684\u67e5\u8be2\uff0c\u8bf7\u4ece\u63d0\u793a\u5217\u8868\u4e2d\u9009\u62e9\u67e5\u8be2\u6761\u4ef6\uff01 +provide.service=\u63d0\u4f9b\u7684\u670d\u52a1 +service.method=\u670d\u52a1\u65b9\u6cd5 +service.filter=\u670d\u52a1filter +default.service.filter=\u9ed8\u8ba4\u670d\u52a1filter +startegy=\u7b56\u7565 +route.name=\u8def\u7531\u540d\u79f0 +rule.match=\u5339\u914d\u89c4\u5219 +rule.filtrate=\u8fc7\u6ee4\u89c4\u5219 +priority=\u4f18\u5148\u7ea7 +routed=\u5df2\u8def\u7531 +unrouted=\u672A\u8DEF\u7531 +page.total=\u5171 +page.records=\u6761\u8bb0\u5f55 +page.ordinal=\u7b2c +page.page=\u9875 +default.lazy=\u9ed8\u8ba4\u61d2\u542f\u52a8 +page.next=\u4e0b\u4e00\u9875 +page.prev=\u4e0a\u4e00\u9875 +page.first=\u9996\u9875 +page.last=\u5c3e\u9875 +page.line=\u6761 +methodName=\u65b9\u6cd5\u540d +proview=\u9884\u89c8 +cluster.name=\u96c6\u7fa4\u540d +cluster.address=\u96c6\u7fa4\u673a\u5668\u5730\u5740 +sameserviceadd=\u540c\u670d\u52a1\u6dfb\u52a0 +whitelist=\u5141\u8BB8 +blacklist=\u7981\u6B62 +toWhiteAndBlackList=\u8f6c\u5165\u767d\u540d\u5355/\u8f6c\u5165\u9ed1\u540d\u5355 +obtainProviderAddress=\u83b7\u53d6\u63d0\u4f9b\u8005\u5730\u5740 +towhitelist=\u52a0\u5165\u767d\u540d\u5355 +toblacklist=\u52a0\u5165\u9ed1\u540d\u5355 +enable=\u542f\u7528 +disable=\u7981\u7528 +copy=\u590d\u5236 +batch.enable=\u6279\u91cf\u542f\u7528 +batch.disable=\u6279\u91cf\u7981\u7528 +batch.towhitelist=\u52a0\u5165\u767d\u540d\u5355 +batch.toblacklist=\u52a0\u5165\u9ed1\u540d\u5355 +confirm.favorites=\u786e\u8ba4\u6536\u85cf\u5417 +confirm.batch.towhitelist=\u786e\u8ba4\u52a0\u5165\u767d\u540d\u5355?
\u5c06\u7981\u6b62\u4e0d\u5728\u767d\u540d\u5355\u5185\u7684\u6240\u6709\u6d88\u8d39\u8005\u8bbf\u95ee\uff0c\u9ed1\u540d\u5355\u5931\u6548\u3002 +confirm.batch.toblacklist=\u786e\u8ba4\u52a0\u5165\u9ed1\u540d\u5355?
\u5982\u679c\u6ca1\u6709\u767d\u540d\u5355\uff0c\u5c06\u7981\u6b62\u5728\u9ed1\u540d\u5355\u5185\u7684\u6240\u6709\u5176\u5b83\u6d88\u8d39\u8005\u8bbf\u95ee\u3002 +confirm.enable=\u786e\u8ba4\u542f\u7528 +confirm.disable=\u786e\u8ba4\u7981\u7528 +confirm.edit=\u786e\u8ba4\u7f16\u8f91 +confirm.disableFeature=\u786e\u8ba4\u7981\u7528\u529f\u80fd +confirm.enableFeature=\u786e\u8ba4\u542f\u7528\u529f\u80fd +confirmDeleteOwner=\u786e\u8ba4\u5220\u9664\u8d1f\u8d23\u4eba +welcome=\u60a8\u597d +approve=\u5f85\u5ba1\u6279 +chinese.simple=\u7b80\u4f53\u4e2d\u6587 +chinese.tradition=\u7e41\u9ad4\u4e2d\u6587 +register.service=\u6ce8\u518c\u65b0\u670d\u52a1 +erratum.guide=\u6392\u9519\u5411\u5bfc +preview.guide=\u9884\u89c8\u5411\u5bfc +sysinfo.status=\u6ce8\u518c\u4e2d\u5fc3\u72b6\u6001 +sysinfo.registries=\u6ce8\u518c\u4e2d\u5fc3\u96c6\u7fa4 +sysinfo.connections=\u5957\u63a5\u5b57\u8fde\u63a5 +sysinfo.cached=\u5185\u5b58\u7f13\u5b58 +sysinfo.failed=\u5931\u8d25\u8bb0\u5f55 +sysinfo.operations=\u64cd\u4f5c\u8bb0\u5f55 +sysinfo.logs=\u7cfb\u7edf\u65e5\u5fd7 +sysinfo.versions=Dubbo\u7248\u672c +sysinfo.dumps=\u7cfb\u7edf\u5feb\u7167 +sysinfo.envs=\u7cfb\u7edf\u73af\u5883 +sysinfo.helps=\u5e2e\u52a9\u6587\u6863 +system.management=\u7cfb\u7edf\u7ba1\u7406 +sysmanage.users=\u7528\u6237\u7ba1\u7406 +sysmanage.configs=\u7cfb\u7edf\u53c2\u6570\u8bbe\u7f6e +sysmanage.features=\u7cfb\u7edf\u529f\u80fd\u5f00\u5173 +system.function.control=\u7cfb\u7edf\u529f\u80fd\u5f00\u5173 +personal.set=\u4e2a\u4eba\u8bbe\u7f6e +modify.personalinfo=\u4fee\u6539\u4e2a\u4eba\u4fe1\u606f +modify.personal.password=\u4fee\u6539\u4e2a\u4eba\u5bc6\u7801 +operation.operateaddress=\u64cd\u4f5c\u8005\u5730\u5740 +operation.operatetype=\u64cd\u4f5c\u7c7b\u578b +operation.datatype=\u6570\u636e\u7c7b\u578b +operation.data=\u64cd\u4f5c\u5185\u5bb9 +operation.createtime=\u64cd\u4f5c\u65f6\u95f4 +operation.clean=\u6e05\u7406 +passwd.oldwrong=\u65e7\u5bc6\u7801\u9519\u8bef +failed=\u5931\u8d25\u8bb0\u5f55 +failed_type=\u7c7b\u578b +failed_data=\u6570\u636e +failed_sync=\u540c\u6b65\u5730\u5740\u5931\u8d25\u8bb0\u5f55 +failed_subscribe=\u8ba2\u9605\u5931\u8d25\u8bb0\u5f55 +failed_notify=\u901a\u77e5\u5931\u8d25\u8bb0\u5f55 +failed_collect=\u7edf\u8ba1\u5931\u8d25\u8bb0\u5f55 +failed_register=\u6ce8\u518c\u5931\u8d25\u8bb0\u5f55 +failed_redirect=\u91cd\u5b9a\u5411\u5931\u8d25\u8bb0\u5f55 +failed_disconnect=\u65ad\u5f00\u6e05\u7406\u5931\u8d25\u8bb0\u5f55 +clientAddress=\u5ba2\u6237\u7aef\u5730\u5740 +overrideAddress=\u8986\u76d6\u5730\u5740 +serviceInfo=\u670d\u52a1\u4fe1\u606f +consumerAddress=\u6d88\u8d39\u8005\u5730\u5740 +providerAddress=\u63d0\u4f9b\u8005\u5730\u5740 +registryAddress=\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740 +serviceName=\u670d\u52a1\u540d +serviceUrl=\u670d\u52a1\u5730\u5740 +overrideConsumerAddress=\u53ea\u63a8\u9001\u7ed9\u6307\u5b9a\u6d88\u8d39\u8005\u5730\u5740 +overrideProviderAddress=\u53ea\u5728\u8c03\u7528\u6307\u5b9a\u63d0\u4f9b\u8005\u5730\u5740\u65f6\u751f\u6548 +tipConsumerAddress=\u4e0d\u586b\u8868\u793a\u5bf9\u6d88\u8d39\u8005\u5e94\u7528\u7684\u6240\u6709\u673a\u5668\u751f\u6548 +tipProviderAddress=\u4e0d\u586b\u8868\u793a\u5bf9\u670d\u52a1\u7684\u6240\u6709\u63d0\u4f9b\u8005\u673a\u5668\u751f\u6548 +tipProviderAddress=\u4e0d\u586b\u8868\u793a\u5bf9\u670d\u52a1\u7684\u6240\u6709\u63d0\u4f9b\u8005\u673a\u5668\u751f\u6548 +logs=\u7cfb\u7edf\u65e5\u5fd7 +logs.file=\u65e5\u5fd7\u6587\u4ef6 +logs.size=\u6587\u4ef6\u5927\u5c0f +logs.modify=\u4fee\u6539\u65f6\u95f4 +logs.level=\u65e5\u5fd7\u7ea7\u522b +change.log.level=\u4fee\u6539\u65e5\u5fd7\u7ea7\u522b +logs.confirmChangeLogLevel=\u786e\u8ba4\u4fee\u6539\u65e5\u5fd7\u7ea7\u522b +cached=\u5185\u5b58\u7f13\u5b58 +cached.type=\u7c7b\u578b +cached.data=\u6570\u636e +cached.reload=\u91cd\u65b0\u52a0\u8f7d +batch.cached.reload=\u6279\u91cf\u91cd\u65b0\u52a0\u8f7d +cached.recover=\u6062\u590d +batch.cached.recover=\u6279\u91cf\u6062\u590d +servicePrivilege=\u670d\u52a1\u6743\u9650 +creator=\u521b\u5efa\u8005 +name=\u540d\u79f0 +department=\u90e8\u95e8 +email=\u90ae\u7bb1 +phone=\u7535\u8bdd +alitalk=\u963f\u91cc\u65fa\u65fa +password=\u5bc6\u7801 +roleR=\u8d85\u7ea7\u7ba1\u7406\u5458 +roleA=\u7ba1\u7406\u5458 +roleG=\u6e38\u5ba2 +roleDescR=\u7ba1\u7406\u6240\u6709 +roleDescA=\u7ba1\u7406\u81ea\u5df1\u521b\u5efa\u7684\u7528\u6237\u548c\u670d\u52a1 +roleDescG=\u53ea\u67e5\u770b +oldPassword=\u65e7\u5bc6\u7801 +newPassword=\u65b0\u5bc6\u7801 +reset=\u91cd\u7f6e +restPassword=\u91cd\u7f6e\u5bc6\u7801 +confirmNewPassword=\u786e\u8ba4\u65b0\u5bc6\u7801 +owns=\u8d1f\u8d23\u7684\u670d\u52a1 +confirmPassword=\u786e\u8ba4\u5bc6\u7801 +generatePassword=\u751f\u6210\u5bc6\u7801 +displayName=\u59d3\u540d +locale=\u4f7f\u7528\u8bed\u8a00 +privilegeTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7(,)\u5206\u9694\uff0c\u901a\u914d\u7b26\u7528\u661f\u53f7(*)\u8868\u793a\uff0c\u53ea\u80fd\u5728\u6bcf\u4e2a\u503c\u7684\u672a\u5c3e\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u88ab\u6388\u4e0e\u7684\u6743\u9650\u4e0d\u80fd\u8d85\u51fa\u5f53\u524d\u7ba1\u7406\u4eba\u5458\u7684\u6743\u9650 +displayNameTip=\u7528\u6237\u59d3\u540d\uff0c\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-50\u4e2a\u5b57\u7b26\u7ec4\u6210 +emailTip=\u7528\u4e8e\u63a5\u6536\u7cfb\u7edf\u90ae\u4ef6\uff0c\u53ef\u4ee5\u8f93\u5165\u591a\u4e2a\u90ae\u4ef6\u5730\u5740\uff0c\u4f7f\u7528\u82f1\u6587\u5206\u53f7\u5206\u9694(;)\uff0c \u5f62\u5982 foo1@163.comj;foo2@gmail.com +userLocaleTip=\u53d1\u9001\u7cfb\u7edf\u90ae\u4ef6\u65f6\uff0c\u5c06\u6839\u636e\u7528\u6237\u4f7f\u7528\u7684\u8bed\u8a00\u53d1\u9001\u4e0d\u540c\u8bed\u8a00\u7684\u90ae\u4ef6\u5185\u5bb9 +DisplayNameTip +EmailTip +UserLocaleTip +missRequestParameters=\u4e22\u5931\u8bf7\u6c42\u53c2\u6570 +haveNoRootPrivilege=\u6ca1\u6709root\u6743\u9650 +confirmReloadCache=\u786e\u8ba4\u91cd\u65b0\u52a0\u8f7d\u7f13\u5b58 +confirmDeleteRegistry=\u786e\u8ba4\u5220\u9664\u6ce8\u518c\u4e2d\u5fc3 +confirmAutoRedirectRegistry=\u786e\u8ba4\u91cd\u5b9a\u5411\u6ce8\u518c\u4e2d\u5fc3 +confirmDeleteExpiredRegistry=\u786e\u8ba4\u5220\u9664\u8fc7\u671f\u6ce8\u518c\u4e2d\u5fc3 +confirmSyncRegistry=\u786e\u8ba4\u540c\u6b65\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740\u5217\u8868\u5230\u5ba2\u6237\u7aef +confirm.toblacklist=\u786e\u8ba4\u52a0\u5165\u9ed1\u540d\u5355?
\u5982\u679c\u6ca1\u6709\u767d\u540d\u5355\uff0c\u5c06\u7981\u6b62\u5728\u9ed1\u540d\u5355\u5185\u7684\u6240\u6709\u6d88\u8d39\u8005\u8bbf\u95ee\u3002 +confirm.towhitelist=\u786e\u8ba4\u52a0\u5165\u767d\u540d\u5355?
\u5c06\u7981\u6b62\u4e0d\u5728\u767d\u540d\u5355\u5185\u7684\u6240\u6709\u5176\u5b83\u6d88\u8d39\u8005\u8bbf\u95ee\uff0c\u9ed1\u540d\u5355\u5931\u6548\u3002 +confirm.clean.operation=\u786e\u8ba4\u6e05\u9664\u64cd\u4f5c\u8bb0\u5f55 +autoRedirect=\u81ea\u52a8\u91cd\u5b9a\u5411 +deleteExpired=\u5220\u9664\u6240\u6709\u5df2\u8fc7\u671f +sync=\u540c\u6b65 +legacies=1.0\u9057\u7559\u5ba2\u6237\u7aef +logined=\u5df2\u767b\u5f55\u5ba2\u6237\u7aef +dumps=\u7cfb\u7edf\u5feb\u7167 +Registry=\u6ce8\u518c\u4e2d\u5fc3\u7248\u672c +Java=JDK\u7248\u672c +Locale=\u8bed\u8a00 +OS=\u64cd\u4f5c\u7cfb\u7edf +Uptime=\u8fd0\u884c\u65f6\u95f4 +Host=\u57df\u540d +CPU=\u0043\u0050\u0055 +confirmEnableUser=\u786e\u8ba4\u542f\u52a8\u7528\u6237 +confirmDisableUser=\u786e\u8ba4\u7981\u7528\u7528\u6237 +documentTitle=\u6587\u6863\u6807\u9898 +documentLink/documentPage=\u94fe\u63a5\u5730\u5740/\u9875\u9762\u5185\u5bb9 +documentInternal=\u9875\u9762 +documentExternal=\u94fe\u63a5 +documentApi=API +documentType=\u6587\u6863\u7c7b\u578b +documentContent=\u6587\u6863\u5185\u5bb9 +Yes=\u662f +No=\u5426 +returnValue=\u8fd4\u56de\u503c +throwException=\u629b\u51fa\u5f02\u5e38 +#BatchAddressTip=\u591a\u4e2a\u5730\u5740\u7528\u6362\u884c\u7b26\u5206\u9694\uff0c\u5730\u5740\u5fc5\u9700\u662f0.0.0.0\u5230255.255.255.255\u7684IP\u5730\u5740 +#AccessControlTip=\u767d\u540d\u5355\u4f18\u5148\uff0c\u53ea\u8981\u6709\u767d\u540d\u5355\uff0c\u5219\u767d\u540d\u5355\u751f\u6548\uff0c\u5426\u5219\u9ed1\u540d\u5355\u751f\u6548 +#RouteNameTip=\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-200\u4e2a\u5b57\u7b26\u7ec4\u6210 +#RoutePriorityTip=\u6570\u5b57\u8d8a\u5927\u8d8a\u4f18\u5148 +#RouteMethodTip=\u53ea\u6709Dubbo2.0.0\u4ee5\u4e0a\u7248\u672c\u7684\u670d\u52a1\u6d88\u8d39\u7aef\u652f\u6301\u6309\u65b9\u6cd5\u8def\u7531\uff0c\u591a\u4e2a\u65b9\u6cd5\u540d\u7528\u9017\u53f7\u5206\u9694 +#Choose=\u8bf7\u9009\u62e9 +#RouteMatchTip=\u5f53\u6d88\u8d39\u8005\u6ee1\u8db3\u5339\u914d\u6761\u4ef6\u65f6\u4f7f\u7528\u5f53\u524d\u89c4\u5219\u8fdb\u884c\u8fc7\u6ee4 +#RouteHostTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7\u5206\u9694\uff0c\u4ee5\u661f\u53f7\u7ed3\u5c3e\u8868\u793a\u901a\u914d\u5730\u5740\u6bb5 +#RouteClusterTip=\u53ef\u901a\u8fc7\u83dc\u5355"\u670d\u52a1\u63a7\u5236"->"\u670d\u52a1\u5668\u96c6\u7fa4"\u7ba1\u7406 +#RouteFilterTip=\u6ee1\u8db3\u8fc7\u6ee4\u89c4\u5219\u7684\u63d0\u4f9b\u8005\u5730\u5740\u5c06\u88ab\u63a8\u9001\u7ed9\u6d88\u8d39\u8005 +testMethodTip=\u5982\u679c\u6709\u65b9\u6cd5\u91cd\u8f7d\u6216\u4f7f\u7528Dubbo1.0.x\u7248\u672c\u7684\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u9700\u5199\u5168\u65b9\u6cd5\u7b7e\u540d\uff0c\u5982\uff1afindBy(int,java.lang.String)\uff0c\u5426\u5219\u53ea\u9700\u65b9\u6cd5\u540d\uff0c\u5982\uff1afindBy +testJsonTip=JSON\u683c\u5f0f\uff1a\u5b57\u7b26\u4e32\u7528\u53cc\u5f15\u53f7\u8868\u793a\uff0c\u5982\uff1a"\u5b57\u7b26\u4e32"\uff0c\u6570\u5b57\u548cBoolean\u503c\u4e0d\u7528\u5f15\u53f7\uff0c\u5982\uff1a123 \u548c true \u6216 false\uff0cPOJO\u5bf9\u8c61\u6216Map\u7528\u5927\u62ec\u53f7\u8868\u793a\uff0c\u5982\uff1a{"\u5c5e\u6027\u540d1": "\u5c5e\u6027\u503c1", "\u5c5e\u6027\u540d2": "\u5c5e\u6027\u503c2"}\uff0c\u6570\u7ec4\u6216List\u6216Set\u7528\u65b9\u62ec\u53f7\u8868\u793a\uff0c\u5982\uff1a["\u503c1", "\u503c2"] +testParametersTip=\u5f53\u4e3a\u65e0\u53c2\u6570\u65b9\u6cd5\u65f6\u53c2\u6570\u503c\u53ef\u4ee5\u4e0d\u586b\uff0c\u53c2\u6570\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testResultTip=\u5f53\u4e3avoid\u65b9\u6cd5\u65f6\u7ed3\u679c\u53ef\u4ee5\u4e0d\u586b\uff0c\u629b\u51fa\u5f02\u5e38\u4f7f\u7528\u5f02\u5e38\u7c7b\u5168\u540d\u8868\u793a\uff0c\u8fd4\u56de\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testAutoRunTip=\u5982\u679c\u8bbe\u7f6e\u4e3a\u81ea\u52a8\u8fd0\u884c\uff0c\u82e5\u8be5\u670d\u52a1\u5df2\u6ce8\u518c\u6216\u65b0\u6ce8\u518c\uff0c\u5219\u81ea\u52a8\u8fd0\u884c\u6b64\u6d4b\u8bd5\u7528\u4f8b\uff0c\u8fd0\u884c\u5931\u8d25\uff0c\u5c06\u53d1\u9001\u90ae\u4ef6 +confirmRunTest=\u786e\u8ba4\u8fd0\u884c\u6d4b\u8bd5 +confirm.runAll=\u786e\u8ba4\u5bf9\u6240\u6709\u63d0\u4f9b\u8005\u8fd0\u884c\u6d4b\u8bd5 +# +#anonymous=\u533f\u540d +#Unuse=\u672a\u4f7f\u7528 +#RouteName=\u8def\u7531\u540d +#Priority=\u4f18\u5148\u7ea7 +#MatchRule=\u5339\u914d\u6761\u4ef6 +#ConsumerHost=\u6d88\u8d39\u8005IP\u5730\u5740 +#ConsumerCluster=\u6d88\u8d39\u8005\u96c6\u7fa4 +#FilterRule=\u8fc7\u6ee4\u89c4\u5219 +#ProviderHost=\u63d0\u4f9b\u8005IP\u5730\u5740 +#ProviderCluster=\u63d0\u4f9b\u8005\u96c6\u7fa4 +#ProviderProtocol=\u63d0\u4f9b\u8005\u534f\u8bae +#ProviderPort=\u63d0\u4f9b\u8005\u7aef\u53e3 +#Match=\u5339\u914d +#Mismatch=\u4e0d\u5339\u914d +#ConsumerAddress=\u6d88\u8d39\u8005\u5730\u5740 +generic=\u6cdb\u5316 +doubling=\u500d\u6743 +loadBalanceStrategy=\u8d1f\u8f7d\u5747\u8861\u7b56\u7565 +random=\u968f\u673a +roundrobin=\u8f6e\u8be2 +leastactive=\u6700\u5c11\u5e76\u53d1 +testName=\u6d4b\u8bd5\u7528\u4f8b\u540d\u79f0 +operator=\u64cd\u4f5c +dataFormat=\u6570\u636e\u683c\u5f0f +resultType=\u7ed3\u679c\u7c7b\u578b +resultController=\u8fd4\u56de\u503c/\u5f02\u5e38\u7c7b\u578b +autoRun=\u81ea\u52a8\u8fd0\u884c +manualRun=\u624b\u52a8\u8fd0\u884c +run=\u8fd0\u884c +runAll=\u8fd0\u884c\u6240\u6709\u63d0\u4f9b\u8005 +expected=\u671f\u671b\u7ed3\u679c +actual=\u5b9e\u9645\u7ed3\u679c +reRun=\u91cd\u65b0\u8fd0\u884c +#Username=\u7528\u6237\u540d +#DisplayName=\u663e\u793a\u540d +#Department=\u90e8\u95e8 +#Email=\u90ae\u7bb1 +#Phone=\u624b\u673a +#Alitalk=\u65fa\u65fa +startDate=\u542f\u52a8\u65f6\u95f4 +console=\u63a7\u5236\u53f0 +total=\u603b\u6570 +delta=\u504f\u5dee +expired=\u8fc7\u671f +alived=\u5b58\u6d3b +redirect=\u91cd\u5b9a\u5411 +current=\u5f53\u524d +#overrides +override.config=\u52a8\u6001\u914d\u7f6e +override.mock=\u670d\u52a1\u964d\u7ea7 +parameter=\u53c2\u6570 +parameter.key=\u53c2\u6570\u540d +parameter.value=\u53c2\u6570\u503c +parameter.tip=\u65b9\u6cd5\u7ea7\u914d\u7f6e\u5982\uff1afindPerson.timeout=1000 +mock.all.method=\u6240\u6709\u65b9\u6cd5\u7684Mock\u503c +mock.method=\u65b9\u6cd5 +mock.value=\u7684Mock\u503c +mock.tip=\u793a\u4f8b\uff1areturn null/empty/JSON\u6216throw com.foo.BarException +protocol=\u534F\u8BAE +host=\u4E3B\u673A\u540D +port=\u7AEF\u53E3 +interface=\u63A5\u53E3\u540D +version=\u7248\u672C +group=\u5206\u7EC4 +methods=\u65B9\u6CD5\u5217\u8868 +category=\u6570\u636E\u7C7B\u578B +application=\u5E94\u7528\u540D +owner=\u8D1F\u8D23\u4EBA +cluster=\u96C6\u7FA4 +loadbalance=\u8D1F\u8F7D\u5747\u8861 +timeout=\u8D85\u65F6 +retries=\u91CD\u8BD5\u6B21\u6570 +threads=\u7EBF\u7A0B\u6570 +connections=\u8FDE\u63A5\u6570 +accepts=\u63A5\u6536\u8FDE\u63A5\u6570 +actives=\u5BA2\u6237\u7AEF\u5E76\u53D1\u8BF7\u6C42\u9650\u5236 +executes=\u7EBF\u7A0B\u6C60\u5E76\u53D1\u6267\u884C\u9650\u5236 +check=\u68C0\u67E5 +side=\u6240\u5C5E\u7AEF +pid=\u8FDB\u7A0B\u53F7 +timestamp=\u65F6\u95F4\u6233 +dubbo=Dubbo\u7248\u672C +anyhost=\u7ED1\u5B9A\u6240\u6709IP +weight=\u6743\u91CD +weight.doubling=\u500D\u6743 +weight.halving=\u534A\u6743 +confirm.weight.doubling=\u786E\u8BA4\u6743\u91CD\u52A0\u500D? +confirm.weight.halving=\u786E\u8BA4\u6743\u91CD\u51CF\u534A? +batch.weight.doubling=\u6279\u91CF\u500D\u6743 +batch.weight.halving=\u6279\u91CF\u534A\u6743 +confirm.batch.weight.doubling=\u786E\u8BA4\u6240\u9009\u9879\u6743\u91CD\u52A0\u500D? +confirm.batch.weight.halving=\u786E\u8BA4\u6240\u9009\u9879\u6743\u91CD\u51CF\u534A? +NoSuchOperationData=\u64CD\u4F5C\u7684\u6570\u636E\u4E0D\u5B58\u5728\u3002 +CanNotDeleteDynamicData=\u4E0D\u80FD\u5220\u9664\u52A8\u6001\u6570\u636E\u3002 +HaveNoServicePrivilege=\u60A8\u6CA1\u6709\u8BE5\u670D\u52A1\u7684\u6743\u9650\u3002 +dynamic.parameters.tip=\u52A8\u6001URL\u4E0D\u80FD\u76F4\u63A5\u4FEE\u6539\uFF0C\u9700\u901A\u8FC7\u52A8\u6001\u914D\u7F6E\u8FDB\u884C\u8986\u76D6\uFF0C\u683C\u5F0F\u4E0EURL\u53C2\u6570\u76F8\u540C\u3002 +default.owner=\u8d1f\u8d23\u4eba +logger=\u65e5\u5fd7 +default.server=\u9ed8\u8ba4\u670d\u52a1\u7aef +default.actives=\u5e76\u53d1\u8c03\u7528\u6570 +default.client=\u9ed8\u8ba4\u5ba2\u6237\u7aef +default.connections=\u6700\u5927\u8fde\u63a5\u6570 diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh_CN.properties b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh_CN.properties new file mode 100644 index 0000000..83e8753 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh_CN.properties @@ -0,0 +1,802 @@ +# +# 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. +# + +#menus +home=\u9996\u9875 +stat=\u7edf\u8ba1 +revision=\u4fee\u8ba2\u7248\u672c +connectionNum=\u8fde\u63a5\u6570 +serviceNum=\u670d\u52a1\u6570 +providerNum=\u63d0\u4f9b\u8005\u6570 +consumerNum=\u6d88\u8d39\u8005\u6570 +applicationNum=\u5e94\u7528\u6570 +about=\u5173\u4e8e +help=\u5e2e\u52a9 +favorites=\u6536\u85cf\u5939 +histories=\u5386\u53f2\u8bb0\u5f55 +governance=\u670d\u52a1\u6cbb\u7406 +applications=\u5e94\u7528 +efferents=\u4f9d\u8d56 +afferents=\u88ab\u4f9d\u8d56 +services=\u670d\u52a1 +references=\u5f15\u7528\u670d\u52a1 +addresses=\u673a\u5668 +providers=\u63d0\u4f9b\u8005 +dependencies=\u4f9d\u8d56\u5173\u7cfb +layers=\u5206\u5c42 +clusters=\u96c6\u7fa4 +consumers=\u6d88\u8d39\u8005 +accesses=\u8BBF\u95EE\u63A7\u5236 +routes=\u8def\u7531\u89C4\u5219 +weights=\u6743\u91cd\u8C03\u8282 +loadbalances=\u8d1f\u8f7d\u5747\u8861 +tests=\u6d4b\u8bd5 +mocks=\u6a21\u62df +overrides=\u52a8\u6001\u914d\u7f6e +documents=\u6587\u6863 +owners=\u8d1f\u8d23\u4eba +agreements=\u534f\u5b9a +approvals=\u4e0a\u7ebf\u5ba1\u6279 +operations=\u64cd\u4f5c\u65e5\u5fd7 +users=\u7528\u6237 +envs=\u7cfb\u7edf\u73af\u5883 +helps=\u5e2e\u52a9\u6587\u6863 +registries=\u6ce8\u518c\u4e2d\u5fc3 +configs=\u7cfb\u7edf\u53c2\u6570 +features=\u7cfb\u7edf\u529f\u80fd +connections=\u8fde\u63a5 +statuses=\u7CFB\u7EDF\u72B6\u6001 +failed=\u5931\u8d25\u8bb0\u5f55 +cached=\u7f13\u5b58\u8bb0\u5f55 +dumps=\u5feb\u7167 +InvalidIp=\u65e0\u6548\u0069\u0070\u5730\u5740 +versions=Dubbo\u7248\u672c +logs=\u65e5\u5fd7 +infos=\u4fee\u6539\u4e2a\u4eba\u4fe1\u606f +passwds=\u4fee\u6539\u4e2a\u4eba\u5bc6\u7801 +dependency.list=\u5217\u8868 +dependency.tree=\u6811\u72b6 +dependency.graph=\u56fe\u5f62 +dependency.efferent=\u4f9d\u8d56 +dependency.afferent=\u88ab\u4f9d\u8d56 +provided=\u63d0\u4f9b\u670d\u52a1 +consumed=\u6d88\u8d39\u670d\u52a1 +select=\u9009\u62e9 +clean=\u6e05\u9664 +information=\u4fe1\u606f +control=\u63a7\u5236 +summary=\u6c47\u603b +consumer.application=\u6d88\u8d39\u8005\u5e94\u7528 +response.time=\u54cd\u5e94\u65f6\u95f4 +sysinfo.infos=\u7cfb\u7edf\u4fe1\u606f +helps.document=\u6587\u6863 +helps.requirement=\u9700\u6c42 +helps.source=\u6e90\u4ee3\u7801 +connections=\u5957\u63a5\u5b57\u8fde\u63a5 +ReconnectUnkwown=\u91cd\u8fde\u6240\u6709\u672a\u77e5\u8fde\u63a5 +confirmReconnectConnection=\u786e\u8ba4\u91cd\u5efa\u8fde\u63a5 +confirmRedirectRegistry=\u786e\u8ba4\u91cd\u5b9a\u5411\u6ce8\u518c\u4e2d\u5fc3 +confirmReconnectUnknownConnection=\u786e\u8ba4\u91cd\u8fde\u672a\u77e5\u7684\u8fde\u63a5 +status.resourcename=\u8d44\u6e90\u540d\u79f0 +status.status=\u72b6\u6001 +status.message=\u4fe1\u606f +status.description=\u63cf\u8ff0 +status.memoryStatus=\u5185\u5b58 +status.memoryStatusDesc=\u53ea\u76d1\u63a7Heap\u5185\u5b58\uff0c\u5982\u679c\u7a7a\u95f2\u5185\u5b58\u4e0d\u8db31M\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.threadpoolStatus=\u7ebf\u7a0b\u6c60 +status.threadpoolStatusDesc=\u53ea\u76d1\u63a7\u6ce8\u518c\u8ba2\u9605\u4e3b\u4e1a\u52a1\u7ebf\u7a0b\u6c60\uff0c\u5982\u679c\u7a7a\u95f2\u7ebf\u7a0b\u5c11\u4e8e1\u4e2a\uff0c\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.failureStatus=\u5931\u8d25\u8bb0\u5f55 +status.failureStatusDesc=\u5f53\u6709\u4efb\u4f55\u5931\u8d25\u8bb0\u5f55\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.cacheStatus=\u7f13\u5b58 +status.cacheStatusDesc=\u5982\u679c\u7f13\u5b58\u4e0e\u6570\u636e\u5e93\u4e0d\u4e00\u81f4\u5219\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.timerStatus=\u5b9a\u65f6\u5668 +status.timerStatusDesc=\u5f53\u5b9a\u65f6\u5668\u672a\u6b63\u786e\u542f\u52a8\uff0c\u6216\u88ab\u4e0d\u6b63\u5e38\u53d6\u6d88\uff0c\u5219\u62a5\u9519\uff0c\u5426\u5219\u6b63\u5e38 +status.socketStatus=\u5957\u63a5\u5b57 +status.socketStatusDesc=\u5f53\u5957\u63a5\u53e3\u5f00\u542f\u4e0d\u4e86\u6216\u5df2\u88ab\u5360\u7528\u65f6\u62a5\u9519\uff0c\u5f53\u8fde\u63a5\u6570\u7b49\u4e8e\u6700\u5927\u503c\u65f6\u8b66\u544a\uff0c\u5426\u5219\u6b63\u5e38 +status.loadStatus=\u8d1f\u8f7d +status.loadStatusDesc=\u5982\u679c\u8d1f\u8f7d\u5927\u4e8eCPU\u4e2a\u6570\u5219\u8b66\u544a\uff0c\u5982\u679c\u7cfb\u7edf\u4e0d\u652f\u6301\u67e5\u8be2\u8d1f\u8f7d\u5219\u4e0d\u542f\u7528\uff0c\u5426\u5219\u6b63\u5e38 +status.datasourceStatus=\u6570\u636e\u5e93 +status.datasourceStatusDesc=\u53d1\u9001\u4e00\u6761\u7b80\u5355\u67e5\u8be2SQL\uff0c\u6267\u884c\u6210\u529f\u5219\u6b63\u5e38\uff0c\u5426\u5219\u62a5\u9519 +status.registryStatus=\u6CE8\u518C\u4E2D\u5FC3 +status.registryStatusDesc=\u5982\u679C\u8FDE\u4E0D\u4E0A\u6CE8\u518C\u4E2D\u5FC3\u5219\u62A5\u9519\uFF0C\u5426\u5219\u6B63\u5E38 +status.monitorStatus=\u76d1\u89c6\u5668 +status.monitorStatusDesc=\u76d1\u89c6\u5668 +status.summaryStatus=\u6c47\u603b +status.summaryStatusDesc=\u6709\u72b6\u6001\u6c47\u603b\uff0c\u5ffd\u7565\u672a\u542f\u7528\u7684\u72b6\u6001\uff0c\u53ea\u8981\u6709\u4e00\u4e2a\u62a5\u9519\uff0c\u5219\u62a5\u9519\uff0c\u53ea\u8981\u6709\u4e00\u4e2a\u8b66\u544a\uff0c\u5219\u8b66\u544a\uff0c\u5168\u90e8\u6b63\u5e38\u5219\u6b63\u5e38 +status.warmupStatus=\u8fd0\u884c\u72b6\u6001 +status.warmupStatusDesc=\u5904\u4e8ewarmup\u72b6\u6001\u65f6\uff0c\u810f\u6570\u636e\u68c0\u6d4b\u3001\u91cd\u5b9a\u5411\u3001\u4e8b\u4ef6\u53d8\u66f4\u5b9a\u65f6\u5668\u5747\u4e0d\u5de5\u4f5c,\u4e0d\u63a8\u9001\u53d8\u66f4 +status.OK=\u6b63\u5e38 +status.WARN=\u8b66\u544a +status.ERROR=\u9519\u8bef +status.UNKNOWN=\u672a\u77e5 +Status0=Unknow +Status1=OK +Status2=OK +Status3=ERROR +Status4=FATAL +Status5=UNKNOW +mock=\u964d\u7ea7 +force.mocked=\u5DF2\u5C4F\u853D +fail.mocked=\u5DF2\u5BB9\u9519 +no.mocked=\u672A\u964D\u7EA7 +force.mock=\u5c4f\u853d +fail.mock=\u5bb9\u9519 +cancel.mock=\u6062\u590d +confirm.force.mock=\u786e\u8ba4\u5c4f\u853d\u8be5\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.fail.mock=\u786e\u8ba4\u5bf9\u8be5\u670d\u52a1\u5bb9\u9519\uff1f
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.cancel.mock=\u786e\u8ba4\u6062\u590d\u8be5\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +batch.force.mock=\u6279\u91cf\u5c4f\u853d +batch.fail.mock=\u6279\u91cf\u5bb9\u9519 +batch.cancel.mock=\u6279\u91cf\u6062\u590d +confirm.batch.force.mock=\u786e\u8ba4\u6279\u91cf\u5c4f\u853d\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.batch.fail.mock=\u786e\u8ba4\u6279\u91cf\u5bf9\u670d\u52a1\u5bb9\u9519\uff1f
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.batch.cancel.mock=\u786e\u8ba4\u6279\u91cf\u6062\u590d\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +all.force.mock=\u7F3A\u7701\u5c4f\u853d +all.fail.mock=\u7F3A\u7701\u5bb9\u9519 +all.cancel.mock=\u7F3A\u7701\u6062\u590d +confirm.all.force.mock=\u786e\u8ba4\u7F3A\u7701\u5c4f\u853d\u8be5\u670d\u52a1\u7684\u8c03\u7528\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5C4F\u853D\u540E\uFF0C\u5c06\u4e0d\u53d1\u8d77\u8fdc\u7a0b\u8c03\u7528\uff0c\u76f4\u63a5\u5728\u5BA2\u6237\u7AEF\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.all.fail.mock=\u786e\u8ba4\u7F3A\u7701\u5bf9\u8be5\u670d\u52a1\u5bb9\u9519\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5BB9\u9519\u540E\uFF0C\u5f53\u8FDC\u7A0B\u8c03\u7528\u5931\u8d25\u65f6\uff0c\u8fd4\u56de\u7a7a\u5bf9\u8c61\u3002 +confirm.all.cancel.mock=\u786e\u8ba4\u7F3A\u7701\u6062\u590d\u8be5\u670d\u52a1\u6b63\u5e38\u8bbf\u95ee\uff1f
\u8BBE\u7F6E\u964D\u7EA7\u7F3A\u7701\u503C\uFF0C\u5C06\u5F71\u54CD\u672A\u964D\u7EA7\u4EE5\u53CA\u65B0\u7684\u6D88\u8D39\u8005\u3002
\u5c06\u53d6\u6d88\u670d\u52a1\u7684\u5c4f\u853d\u548c\u5bb9\u9519\u884c\u4e3a\u3002 +agreement.invocation.quantity=\u4e00\u5929\u8c03\u7528\u91cf +agreement.tps=TPS\u4e0a\u9650 +response.time=\u54cd\u5e94\u65f6\u95f4 +agreement.availability=\u53ef\u7528\u7387 +layer.name=\u5206\u5c42\u540d\u79f0 +layer.value=\u6570\u5b57\u7b49\u7ea7 +layer.arch=\u5206\u5c42\u67b6\u6784 +loadBalanceStrategy=\u8d1f\u8f7d\u5747\u8861\u7b56\u7565 +ServiceName=\u670d\u52a1\u540d +cluster.name=\u96c6\u7fa4\u540d +cluster.address=\u96c6\u7fa4\u673a\u5668\u5730\u5740 +property.name=\u5c5e\u6027\u540d +property.value=\u5c5e\u6027\u503c +property.count=\u5c5e\u6027\u6570\u91cf +getMethods=\u83b7\u53d6\u670d\u52a1\u65b9\u6cd5 +getAddresses=\u83b7\u53d6\u63d0\u4f9b\u8005\u5730\u5740 +Edit=\u7f16\u8f91 +Username=\u7528\u6237\u540d +Priority=\u4f18\u5148\u7ea7 +ConnectionAddress=\u8fde\u63a5\u5730\u5740 +Role=\u89d2\u8272 +Reconnect=\u91cd\u8fde +Redirect=\u91cd\u5b9a\u5411 +staff.query=\u5185\u7f51\u67e5\u8be2 +configKey=\u914d\u7f6e\u9879 +configValue=\u914d\u7f6e\u9879\u503c +Preview=\u9884\u89c8 +routeselect=\u8def\u7531\u9884\u89c8\uff08\u9009\u62e9\u6d88\u8d39\u8005\uff09 +AllOperations=\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeOneMonthOperations=\u4e00\u4e2a\u6708\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeThreeMonthOperations=\u4e09\u4e2a\u6708\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeHalfYearOperations=\u534a\u5e74\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +BeforeOneYearOperations=\u4e00\u5e74\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8bb0\u5f55 +PleaseInput=\u8bf7\u8f93\u5165 +BulletinConfig=\u516c\u544a\u914d\u7f6e +BulletinMessage=\u516c\u544a\u4fe1\u606f +MailConfig=\u90ae\u7bb1\u914d\u7f6e +MailEnabled=\u662f\u5426\u542f\u7528\u90ae\u7bb1 +MailHost=\u90ae\u4ef6\u670d\u52a1\u5668\u4e3b\u673a +MailPort=\u90ae\u4ef6\u670d\u52a1\u5668\u7aef\u53e3 +MailFrom=\u90ae\u4ef6\u53d1\u4ef6\u4eba\u5730\u5740 +MailAuth=\u90ae\u7bb1\u662f\u5426\u9700\u8981\u767b\u5f55 +MailUsername=\u90ae\u7bb1\u767b\u5f55\u7528\u6237\u540d +MailPassword=\u90ae\u7bb1\u767b\u5f55\u5bc6\u7801 +LoginConfig=\u767b\u5f55\u914d\u7f6e +AllowAnonymousLogin=\u5141\u8bb8\u533f\u540d\u767b\u5f55 +AllowLegacyLogin=\u5141\u8bb8\u9057\u7559\u7cfb\u7edf\u767b\u5f55 +RouteEnabled=\u662f\u5426\u5f00\u542f\u8def\u7531\u529f\u80fd +WarmupEnabled=\u662f\u5426\u8fdb\u5165\u9884\u70ed\u72b6\u6001 +LogConfig=\u65e5\u5fd7\u914d\u7f6e +LogLevel=\u65e5\u5fd7\u7ea7\u522b +RedirectConfig=\u91cd\u5b9a\u5411\u914d\u7f6e +AutoRedirectInterval=\u81ea\u52a8\u91cd\u5b9a\u5411\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +AutoRedirectThreshold=\u80fd\u591f\u81ea\u52a8\u91cd\u5b9a\u5411\u7684\u8fde\u63a5\u4e0b\u754c +AutoRedirectToleratePercent=\u81ea\u52a8\u91cd\u5b9a\u5411\u65f6\u8fde\u63a5\u6570\u504f\u5dee\u5bb9\u5fcd\u767e\u5206\u6bd4 +ManualRedirect=\u91cd\u5b9a\u5411{0}\u4e2a +LimitConfig=\u8d44\u6e90\u9650\u5236\u914d\u7f6e +MaxThreadSize=\u6700\u5927\u7ebf\u7a0b\u6570 +MaxConnectionSize=\u6700\u5927\u8fde\u63a5\u6570 +MaxCacheSize=\u6700\u5927\u7f13\u5b58\u6570 +MaxMailSize=\u6700\u5927\u90ae\u4ef6\u961f\u5217\u6570 +TimerConfig=\u5b9a\u65f6\u5668\u914d\u7f6e +AlivedCheckInterval=\u6ce8\u518c\u4e2d\u5fc3\u5b58\u6d3b\u72b6\u6001\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +ChangedCheckInterval=\u6570\u636e\u53d8\u66f4\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +FailedRetryInterval=\u5931\u8d25\u91cd\u8bd5\u95f4\u9694(\u6beb\u79d2) +DirtyCheckInterval=\u810f\u6570\u636e\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +HeartbeatConfig=\u5fc3\u8df3\u914d\u7f6e +HeartbeatCheckInterval=\u4e0e\u5ba2\u6237\u7aef\u8fde\u63a5\u5fc3\u8df3\u68c0\u67e5\u95f4\u9694(\u6beb\u79d2) +HeartbeatCheckTimeout=\u5fc3\u8df3\u8d85\u65f6\u65f6\u95f4(\u6beb\u79d2) +TimeoutConfig=\u8d85\u65f6\u914d\u7f6e +NotifyTimeout=\u4e8b\u4ef6\u63a8\u9001\u8d85\u65f6(\u6beb\u79d2) +WarmupWaitTime=\u542f\u52a8\u9884\u70ed\u65f6\u95f4(\u6beb\u79d2) +UrlConfig=URL\u914d\u7f6e +BucServiceAddress=BUC\u670d\u52a1\u5730\u5740 +HelpDocumentUrl=\u5e2e\u52a9\u6587\u6863URL +HomepageDomain=\u663e\u793a\u4e3b\u9875\u57df\u540d +HomepageUrl=\u4e3b\u9875\u5730\u5740 +parametersConfig=\u53c2\u6570\u914d\u7f6e +DefaultServiceParameters=\u7f3a\u7701\u53c2\u6570\u914d\u7f6e +BatchAddressTip=\u591a\u4e2a\u5730\u5740\u7528\u6362\u884c\u7b26\u5206\u9694\uff0c\u5730\u5740\u5fc5\u9700\u662f0.0.0.0\u5230255.255.255.255\u7684IP\u5730\u5740 +ConsumerAddress=\u6d88\u8d39\u8005\u5730\u5740 +AccessControlTip=\u767d\u540d\u5355\u4f18\u5148\uff0c\u53ea\u8981\u6709\u767d\u540d\u5355\uff0c\u5219\u767d\u540d\u5355\u751f\u6548\uff0c\u5426\u5219\u9ed1\u540d\u5355\u751f\u6548 +access=\u8BBF\u95EE +Allowed=\u5DF2\u5141\u8BB8 +Forbidden=\u5DF2\u7981\u6B62 +allow=\u5141\u8BB8 +forbid=\u7981\u6B62 +confirm.allow=\u786E\u8BA4\u5141\u8BB8\u8BBF\u95EE? +confirm.forbid=\u786E\u8BA4\u7981\u6B62\u8BBF\u95EE?
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +batch.allow=\u6279\u91CF\u5141\u8BB8 +batch.forbid=\u6279\u91CF\u7981\u6B62 +confirm.batch.allow=\u786E\u8BA4\u5141\u8BB8\u6240\u9009\u9879\u8BBF\u95EE? +confirm.batch.forbid=\u786E\u8BA4\u7981\u6B62\u6240\u9009\u9879\u8BBF\u95EE?
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +only.allow=\u53EA\u5141\u8BB8 +only.forbid=\u53EA\u7981\u6B62 +confirm.only.allow=\u786E\u8BA4\u53EA\u5141\u8BB8\u9009\u4E2D\u9879\u8BBF\u95EE?
\u5176\u5B83\u672A\u9009\u4E2D\u9879\u53CA\u4EE5\u540E\u65B0\u589E\u9879\u5C06\u5168\u90E8\u53D8\u4E3A\u7981\u6B62\u8BBF\u95EE\u3002
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +confirm.only.forbid=\u786E\u8BA4\u53EA\u7981\u6B62\u9009\u4E2D\u9879\u8BBF\u95EE?
\u5176\u5B83\u672A\u9009\u4E2D\u9879\u53CA\u4EE5\u540E\u65B0\u589E\u9879\u5C06\u5168\u90E8\u53D8\u4E3A\u5141\u8BB8\u8BBF\u95EE\u3002
\u88AB\u7981\u6B62\u7684\u5BA2\u6237\u7AEF\u5C06\u6536\u5230\u7981\u6B62\u8BBF\u95EE\u5F02\u5E38\u3002 +Choose=\u8bf7\u9009\u62e9 +userown=\u8d1f\u8d23\u7684\u670d\u52a1 +sysmanage.userown=\u8d1f\u8d23\u7684\u670d\u52a1 +SingleServiceTip=\u4e00\u4e2a\u8def\u7531\u53ea\u80fd\u5e94\u7528\u4e8e\u4e00\u4e2a\u670d\u52a1\uff0c\u4e0d\u652f\u6301\u591a\u670d\u52a1\u53ca\u901a\u914d\u7b26 +MultiServiceTip=\u670d\u52a1\u63a5\u53e3\u540d\u53ef\u4ee5\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u53ea\u652f\u6301\u4e00\u4e2a*\u7b26\u4e14\u8981\u5728\u63a5\u53e3\u672b\u5c3e\uff08\u5206\u7ec4\u3001\u7248\u672c\u4e0d\u652f\u6301\u901a\u914d\u7b26\uff09 +RouteNameTip=\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-200\u4e2a\u5b57\u7b26\u7ec4\u6210 +RoutePriorityTip=\u6570\u5b57\u8d8a\u5927\u8d8a\u4f18\u5148 +RouteServiceTip=\u4e00\u4e2a\u8def\u7531\u53ea\u80fd\u5e94\u7528\u4e8e\u4e00\u4e2a\u670d\u52a1\uff0c\u4e0d\u652f\u6301\u591a\u670d\u52a1\u53ca\u901a\u914d\u7b26 +#RouteServiceTip=\u670d\u52a1\u63a5\u53e3\u540d\u53ef\u4ee5\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u53ea\u652f\u6301\u4e00\u4e2a*\u7b26\u4e14\u8981\u5728\u63a5\u53e3\u672b\u5c3e\uff08\u5206\u7ec4\u3001\u7248\u672c\u4e0d\u652f\u6301\u901a\u914d\u7b26\uff09 +RouteMethodTip=\u53ea\u6709Dubbo2.0.0\u4ee5\u4e0a\u7248\u672c\u7684\u670d\u52a1\u6d88\u8d39\u7aef\u652f\u6301\u6309\u65b9\u6cd5\u8def\u7531\uff0c\u591a\u4e2a\u65b9\u6cd5\u540d\u7528\u9017\u53f7\u5206\u9694 +RouteClusterTip=\u53ef\u901a\u8fc7\u83dc\u5355"\u670d\u52a1\u63a7\u5236"->"\u670d\u52a1\u5668\u96c6\u7fa4"\u7ba1\u7406 +RouteMatchTip=\u5f53\u6d88\u8d39\u8005\u6ee1\u8db3\u5339\u914d\u6761\u4ef6\u65f6\u4f7f\u7528\u5f53\u524d\u89c4\u5219\u8fdb\u884c\u8fc7\u6ee4 +RouteFilterTip=\u6ee1\u8db3\u8fc7\u6ee4\u89c4\u5219\u7684\u63d0\u4f9b\u8005\u5730\u5740\u5c06\u88ab\u63a8\u9001\u7ed9\u6d88\u8d39\u8005 +RouteHostTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7\u5206\u9694\uff0c\u4ee5\u661f\u53f7\u7ed3\u5c3e\u8868\u793a\u901a\u914d\u5730\u5740\u6bb5 +RouteApplicationTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7\u5206\u9694 +RouteResult=\u8def\u7531\u7ed3\u679c +preview=\u9884\u89c8 +ConsumerApplication=\u6d88\u8d39\u8005\u5e94\u7528\u540d +ConsumerCluster=\u6d88\u8d39\u8005\u96c6\u7fa4 +ConsumerHost=\u6d88\u8d39\u8005IP\u5730\u5740 +ConsumerVersion=\u6d88\u8d39\u8005\u7248\u672c\u53f7 +ConsumerGroup=\u6d88\u8d39\u8005\u540d\u79f0\u7a7a\u95f4 +ProviderApplication=\u63d0\u4f9b\u8005\u5e94\u7528 +ProviderCluster=\u63d0\u4f9b\u8005\u96c6\u7fa4 +ProviderProtocol=\u63d0\u4f9b\u8005\u534f\u8bae +ProviderHost=\u63d0\u4f9b\u8005IP\u5730\u5740 +ProviderPort=\u63d0\u4f9b\u8005\u7aef\u53e3 +ProviderVersion=\u63d0\u4f9b\u8005\u7248\u672c\u53f7 +ProviderGroup=\u63d0\u4f9b\u8005\u540d\u79f0\u7a7a\u95f4 +MatchRule=\u5339\u914d\u6761\u4ef6 +FilterRule=\u8fc7\u6ee4\u89c4\u5219 +routeName=\u8DEF\u7531\u540D\u79F0 +routeRule=\u8def\u7531\u89c4\u5219 +Match=\u5339\u914d +Mismatch=\u4e0d\u5339\u914d +GetMethods=\u83b7\u53d6\u670d\u52a1\u65b9\u6cd5 +FeatureName=\u529f\u80fd\u540d +Features=\u7cfb\u7edf\u529f\u80fd +Disable=\u7981\u7528 +Enable=\u542f\u7528 +Enabled=\u5df2\u542f\u7528 +Disabled=\u5df2\u7981\u7528 +Unknown=\u672a\u77e5 +Users=\u7528\u6237\u7ba1\u7406 +UsersDescription=\u7528\u6237\u4fe1\u606f\u7ba1\u7406 +StatusList=\u6ce8\u518c\u4e2d\u5fc3\u72b6\u6001 +StatusListDescription=\u6ce8\u518c\u4e2d\u5fc3\u7cfb\u7edf\u72b6\u6001 +Operations=\u64cd\u4f5c\u8bb0\u5f55 +OperationsDescription=\u8bb0\u5f55\u6240\u6709\u4eba\u4e3a\u7684\u64cd\u4f5c +Accesses=\u670d\u52a1\u9ed1\u767d\u540d\u5355 +AccessesDescription=\u670d\u52a1\u9ed1\u767d\u540d\u5355 +Configs=\u7cfb\u7edf\u914d\u7f6e +Clusters=\u670d\u52a1\u5668\u96c6\u7fa4 +ClustersDescription=\u7ba1\u7406\u670d\u52a1\u96c6\u7fa4\u4fe1\u606f +Weights=\u63d0\u4f9b\u8005\u6743\u91cd +WeightsDescription=\u7ba1\u7406\u63d0\u4f9b\u8005\u6743\u91cd\u4fe1\u606f +Agreements=\u670d\u52a1\u7b49\u7ea7\u534f\u5b9a +AgreementsDescription=\u670d\u52a1\u7b49\u7ea7\u534f\u5b9a +ConfigsDescription=\u7cfb\u7edf\u914d\u7f6e\u4fe1\u606f +LoadBalances=\u8d1f\u8f7d\u5747\u8861 +LoadBalancesDescription=\u8d1f\u8f7d\u5747\u8861 +CachedList=\u5185\u5b58\u7f13\u5b58 +CachedListDescription=\u6ce8\u518c\u4e2d\u5fc3\u5185\u5b58\u7f13\u5b58\u8bb0\u5f55 +FailedList=\u5931\u8d25\u8bb0\u5f55 +Registries=\u6ce8\u518c\u4e2d\u5fc3\u96c6\u7fa4 +FailedListDescription=\u5931\u8d25\u8bb0\u5f55\u5217\u8868 +registryAddress=\u6ce8\u518c\u4e2d\u5fc3\u5217\u8868 +RegistriesDescription=\u67e5\u770b\u5df2\u77e5\u7684\u6ce8\u518c\u4e2d\u5fc3 +Help=\u5e2e\u52a9 +HelpDescription=\u5e2e\u52a9 +Providers=\u670d\u52a1\u63d0\u4f9b\u8005 +ProvidersDescription=\u67e5\u770b\u6240\u6709\u670d\u52a1\u63d0\u4f9b\u8005 +Log=\u65e5\u5fd7\u6587\u4ef6 +LogDescription=\u67e5\u770b\u6ce8\u518c\u4e2d\u5fc3Log4J\u65e5\u5fd7 +Services=\u670d\u52a1\u4fe1\u606f +ServicesDescription=\u67e5\u770b\u670d\u52a1\u5df2\u6ce8\u518c\u7684\u6240\u6709\u670d\u52a1 +Owned=\u670d\u52a1\u5f52\u5c5e +OwnedDescription=\u670d\u52a1\u5f52\u5c5e +Tests=\u670d\u52a1\u6d4b\u8bd5 +TestsDescription=\u670d\u52a1\u6d4b\u8bd5\u7528\u4f8b +Documents=\u670d\u52a1\u6587\u6863 +DocumentsDescription=\u6587\u6863 +Applications=\u670d\u52a1\u5e94\u7528 +ApplicationsDescription=\u670d\u52a1\u5e94\u7528 +Consumers=\u670d\u52a1\u6d88\u8d39\u8005 +ConsumersDescription=\u67e5\u770b\u6240\u6709\u670d\u52a1\u6d88\u8d39\u8005 +System=\u7cfb\u7edf\u73af\u5883 +SystemDescription=\u7cfb\u7edf\u73af\u5883\u4fe1\u606f +Routes=\u670d\u52a1\u8def\u7531 +Route=\u8def\u7531 +RoutesDescription=\u7ba1\u7406\u670d\u52a1\u8def\u7531\u89c4\u5219 +Connections=\u5957\u63a5\u5b57\u8fde\u63a5 +ConnectionsDescription=\u8fde\u63a5 +RegistryAddress=\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740 +RegisterUsername=\u6ce8\u518c\u7528\u6237\u540d +RegisterDate=\u6ce8\u518c\u65f6\u95f4 +subscribeDate=\u8ba2\u9605\u65f6\u95f4 +Statistics=\u670d\u52a1\u5b9e\u65f6\u7edf\u8ba1 +CheckConnection=\u68c0\u67e5\u8fde\u63a5 +CheckDatabase=\u68c0\u67e5\u6570\u636e\u5e93 +queryUrl=\u8ba2\u9605\u53c2\u6570 +Status=\u72b6\u6001 +notify=\u901A\u77E5 +notified=\u5df2\u901a\u77e5 +unnotified=\u672A\u901A\u77E5 +Unuse=\u672a\u4f7f\u7528 +NoProvider=\u6ca1\u6709\u63d0\u4f9b\u8005 +NoConsumer=\u6ca1\u6709\u6d88\u8d39\u8005 +route.consumer.not.match=\u672cRoute\u4e0d\u5339\u914d\u6b64\u670d\u52a1\u6d88\u8d39\u8005\uff08\u4f1a\u8fd4\u56de\u6240\u6709\u7684\u670d\u52a1\u63d0\u4f9b\u8005\uff09 +#labels +all=\u6240\u6709 +service=\u670d\u52a1\u540d +application=\u5e94\u7528\u540d +recursive=\u5faa\u73af +layer=\u670d\u52a1\u5206\u5c42 +address=\u673a\u5668IP +dubbo=\u4f7f\u7528dubbo\u7248\u672c +version=\u670d\u52a1\u7248\u672c +group=\u670d\u52a1\u5206\u7ec4 +url=\u670d\u52a1\u5730\u5740 +parameters=\u670d\u52a1\u53c2\u6570 +provider=\u63d0\u4f9b\u8005\u5730\u5740 +consumer=\u6d88\u8d39\u8005\u5730\u5740 +registry=\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740 +username=\u7528\u6237\u540d +created=\u521b\u5efa\u65f6\u95f4 +modified=\u4fee\u6539\u65f6\u95f4 +register.date=\u6ce8\u518c\u65f6\u95f4 +type=\u7c7b\u578b +static=\u9759\u6001 +dynamic=\u52a8\u6001 +status=\u72b6\u6001 +enabled=\u5df2\u542f\u7528 +disabled=\u5df2\u7981\u7528 +check=\u68c0\u67e5 +operation=\u64cd\u4f5c +role=\u89d2\u8272 +provider=\u63d0\u4f9b\u8005 +consumer=\u6d88\u8d39\u8005 +consumer.address=\u6d88\u8d39\u8005\u5730\u5740 +no.provider=\u6ca1\u6709\u63d0\u4f9b\u8005 +no.consumer=\u6ca1\u6709\u6d88\u8d39\u8005 +ok=\u6b63\u5e38 +warn=\u8b66\u544a +error=\u51fa\u9519 +success=\u6210\u529f +failure=\u5931\u8d25 +update=\u66f4\u65b0 +operation.success=\u64cd\u4f5c\u6210\u529f\uff01 +operation.failure=\u64cd\u4f5c\u5931\u8d25\uff01 +isRegistered=\u6ce8\u518c\u7f13\u5b58 +isCached=\u670d\u52a1\u7f13\u5b58 +isCached.true=\u670d\u52a1\u5728\u7f13\u5b58\u4e2d +isCached.false=\u670d\u52a1\u672a\u540c\u6b65\u5230\u7f13\u5b58 +isSubscribed=\u8ba2\u9605\u7f13\u5b58 +isSubscribed.true=\u6b64\u6d88\u8d39\u8005\u5728\u5f53\u524d\u6ce8\u518c\u4e2d\u5fc3\u8ba2\u9605 +isSubscribed.false=\u6b64\u6d88\u8d39\u8005\u5728\u5176\u4ed6\u6ce8\u518c\u4e2d\u5fc3\u8ba2\u9605 +isSubscribed.unmatch=\u6b64\u6d88\u8d39\u8005\u5728\u6570\u636e\u5e93\u548c\u7f13\u5b58\u4e2d\u7684\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740\u4e0d\u4e00\u81f4 +#operations +search=\u641c\u7d22 +search=\u641c\u7d22 +query=\u67e5\u8be2 +show=\u67e5\u770b +add=\u65b0\u589e +addMock=\u65b0\u589eMock +multiadd=\u6279\u91cf\u65b0\u589e +edit=\u7f16\u8f91 +save=\u4fdd\u5b58 +delete=\u5220\u9664 +enable=\u542f\u7528 +disable=\u7981\u7528 +recover=\u6062\u590d +reload=\u91cd\u8f7d\u7f13\u5b58 +reconnect=\u91cd\u8fde +renotify=\u91cd\u65b0\u901a\u77e5 +tostatic=\u8f6c\u4e3a\u9759\u6001 +todynamic=\u8f6c\u4e3a\u52a8\u6001 +favorite=\u6536\u85cf +register=\u7533\u8bf7\u6ce8\u518c +subscribe=\u7533\u8bf7\u8c03\u7528 +logout=\u9000\u51fa +back=\u8fd4\u56de +cancel=\u53d6\u6d88 +confirm=\u786e\u5b9a +batch.add=\u6279\u91cf\u65b0\u589e +batch.multiservices.add=\u591a\u670d\u52a1\u65b0\u589e +batch.delete=\u6279\u91cf\u5220\u9664 +batch.enable=\u6279\u91cf\u542f\u7528 +batch.disable=\u6279\u91cf\u7981\u7528 +batch.recover=\u6279\u91cf\u6062\u590d +batch.reconnect=\u6279\u91cf\u91cd\u8fde +batch.renotify=\u6279\u91cf\u91cd\u65b0\u901a\u77e5 +batch.tostatic=\u6279\u91cf\u9759\u6001 +batch.todynamic=\u6279\u91cf\u52a8\u6001 +batch.favorite=\u6279\u91cf\u6536\u85cf +batch.reload=\u6279\u91cf\u91cd\u8f7d +confirm.batch.disable=\u786e\u8ba4\u6279\u91cf\u7981\u7528 +confirm.batch.enable=\u786e\u8ba4\u6279\u91cf\u542f\u7528 +#prompts +please.input.service=\u8bf7\u8f93\u5165\u670d\u52a1\u540d +please.input.application=\u8bf7\u8f93\u5165\u5e94\u7528\u540d +please.input.address=\u8bf7\u8f93\u5165\u673a\u5668IP +please.input.layer=\u8bf7\u8f93\u5165\u670d\u52a1\u5206\u5c42 +please.input=\u8bf7\u8f93\u5165\u8981\u64cd\u4f5c\u7684\u5185\u5bb9 +please.select=\u8bf7\u9009\u62e9\u8981\u64cd\u4f5c\u7684\u9879 +empty.list=\u6ca1\u6709\u6570\u636e\u53ef\u4ee5\u64cd\u4f5c +not.found=\u6ca1\u6709\u641c\u5230\u5339\u914d\u7684\u7ed3\u679c +show.all=\u663e\u793a\u5168\u90e8 +confirm.logout=\u786e\u5b9a\u9000\u51fa\u767b\u5f55? +confirm.delete=\u786e\u5b9a\u5220\u9664?
\u5220\u9664\u540E\u5C06\u4E0D\u53EF\u8FD8\u539F\u3002 +confirm.enable=\u786e\u5b9a\u542f\u7528? +confirm.disable=\u786e\u5b9a\u7981\u7528? +confirm.recover=\u786e\u5b9a\u6062\u590d? +confirm.reconnect=\u786e\u5b9a\u91cd\u8fde? +confirm.renotify=\u786e\u5b9a\u901a\u77e5? +confirm.tostatic=\u786e\u5b9a\u8f6c\u4e3a\u9759\u6001? +confirm.todynamic=\u786e\u5b9a\u8f6c\u4e3a\u52a8\u6001? +confirm.batch.delete=\u786e\u5b9a\u5220\u9664\u6240\u9009\u9879?
\u5220\u9664\u540E\u5C06\u4E0D\u53EF\u8FD8\u539F\u3002 +confirm.batch.enable=\u786e\u5b9a\u542f\u7528\u6240\u9009\u9879? +confirm.batch.disable=\u786e\u5b9a\u7981\u7528\u6240\u9009\u9879? +confirm.batch.recover=\u786e\u5b9a\u6062\u590d\u6240\u9009\u9879? +confirm.batch.reload=\u786e\u5b9a\u91cd\u8f7d\u5f53\u524d\u670d\u52a1? +confirm.batch.reconnect=\u786e\u5b9a\u91cd\u8fde\u6240\u9009\u9879? +confirm.batch.renotify=\u786e\u5b9a\u91cd\u65b0\u901a\u77e5\u6240\u9009\u9879? +confirm.batch.tostatic=\u786e\u5b9a\u8f6c\u4e3a\u9759\u6001\u6240\u9009\u9879? +confirm.batch.todynamic=\u786e\u5b9a\u8f6c\u4e3a\u52a8\u6001\u6240\u9009\u9879? +current.user=\u5f53\u524d\u7528\u6237 +CheckProviderLocalAddress={0}\u4E0D\u662F\u6709\u6548\u7684\u8FDC\u7A0B\u670D\u52A1\u5730\u5740\uFF0C\u8BF7\u68C0\u67E5\u63D0\u4F9B\u65B9/etc/hosts\u6620\u5C04\u662F\u5426\u6B63\u786E\u3002 +CheckProviderApplicationDifferent=\u591a\u4e2a\u4e0d\u540c\u5e94\u7528\u6ce8\u518c\u4e86\u76f8\u540c\u670d\u52a1\uff0c\u8bf7\u68c0\u67e5{0}\u4e2d\u662f\u5426\u6709\u8bef\u66b4\u9732\u3002 +CheckProviderAddressMismatch=\u670d\u52a1URL\u4e0a\u7684IP\u4e0e\u8fde\u63a5\u6ce8\u518c\u4e2d\u5fc3\u7684IP\u4e0d\u76f8\u540c +CheckConnectionDisconnected=\u8be5\u8fde\u63a5\u5df2\u65ad\u5f00\uff0c\u6570\u636e\u5e93\u810f\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckConnectionExpired=\u8be5\u8fde\u63a5\u6240\u5728\u6ce8\u518c\u4e2d\u5fc3\u5df2\u4e0d\u5b58\u5728\uff08\u6570\u636e\u4f1a\u81ea\u52a8\u5b9a\u671f\u6e05\u7406\uff09 +CheckDatabaseMiss=\u6570\u636e\u5e93\u6570\u636e\u610f\u5916\u4e22\u5931\u6b64\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u6062\u590d\u201d +CheckDatabaseMismatch=\u6570\u636e\u5e93\u4e0e\u6ce8\u518c\u7f13\u5b58\u6570\u636e\u6ce8\u518c\u5730\u5740\u4e0d\u4e00\u81f4 +CheckDatabaseDirty2Registered=\u6570\u636e\u5e93\u6bd4\u6ce8\u518c\u7f13\u5b58\u591a\u6b64\u810f\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckDatabaseDirty2Subscribed=\u6570\u636e\u5e93\u6bd4\u8ba2\u9605\u7f13\u5b58\u591a\u6b64\u810f\u6570\u636e\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckCacheRegistered=\u6ce8\u518c\u7f13\u5b58\u4e0d\u5b58\u5728\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckCacheConsumer=\u65e0\u6b64\u670d\u52a1\u7684\u670d\u52a1\u7f13\u5b58\uff0c\u4f46\u6709\u6d88\u8d39\u8005\uff01\u8bf7\u70b9\u51fb\u201c\u91cd\u8f7d\u201d +CheckCacheProvider=\u670d\u52a1\u7f13\u5b58\u65e0\u6b64\u63d0\u4f9b\u8005\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8f7d\u201d +CheckCacheSubscribed=\u8ba2\u9605\u7f13\u5b58\u4e0d\u5b58\u5728\uff0c\u8bf7\u70b9\u51fb\u201c\u91cd\u8fde\u201d +CheckCacheService=\u65e0\u6b64\u670d\u52a1\u7684\u670d\u52a1\u7f13\u5b58\uff0c\u8bf7\u70b9\u51fb\u63d0\u4f9b\u8005\u7684\u201c\u91cd\u8f7d\u201d +select.all=\u5168\u9009 +ip.address=IP\u5730\u5740 +registry.newservice=\u6ce8\u518c\u65b0\u670d\u52a1 +add.new.provider=\u6dfb\u52a0\u63d0\u4f9b\u8005 +add.new.route=\u6dfb\u52a0\u8def\u7531 +message.search.noresult=\u6ca1\u6709\u7b26\u5408\u7684\u67e5\u8be2\uff0c\u8bf7\u4ece\u63d0\u793a\u5217\u8868\u4e2d\u9009\u62e9\u67e5\u8be2\u6761\u4ef6\uff01 +provide.service=\u63d0\u4f9b\u7684\u670d\u52a1 +service.method=\u670d\u52a1\u65b9\u6cd5 +service.filter=\u670d\u52a1filter +default.service.filter=\u9ed8\u8ba4\u670d\u52a1filter +startegy=\u7b56\u7565 +route.name=\u8def\u7531\u540d\u79f0 +rule.match=\u5339\u914d\u89c4\u5219 +rule.filtrate=\u8fc7\u6ee4\u89c4\u5219 +priority=\u4f18\u5148\u7ea7 +routed=\u5df2\u8def\u7531 +unrouted=\u672A\u8DEF\u7531 +page.total=\u5171 +page.records=\u6761\u8bb0\u5f55 +page.ordinal=\u7b2c +page.page=\u9875 +default.lazy=\u9ed8\u8ba4\u61d2\u542f\u52a8 +page.next=\u4e0b\u4e00\u9875 +page.prev=\u4e0a\u4e00\u9875 +page.first=\u9996\u9875 +page.last=\u5c3e\u9875 +page.line=\u6761 +methodName=\u65b9\u6cd5\u540d +proview=\u9884\u89c8 +cluster.name=\u96c6\u7fa4\u540d +cluster.address=\u96c6\u7fa4\u673a\u5668\u5730\u5740 +sameserviceadd=\u540c\u670d\u52a1\u6dfb\u52a0 +whitelist=\u5141\u8BB8 +blacklist=\u7981\u6B62 +toWhiteAndBlackList=\u8f6c\u5165\u767d\u540d\u5355/\u8f6c\u5165\u9ed1\u540d\u5355 +obtainProviderAddress=\u83b7\u53d6\u63d0\u4f9b\u8005\u5730\u5740 +towhitelist=\u52a0\u5165\u767d\u540d\u5355 +toblacklist=\u52a0\u5165\u9ed1\u540d\u5355 +enable=\u542f\u7528 +disable=\u7981\u7528 +copy=\u590d\u5236 +batch.enable=\u6279\u91cf\u542f\u7528 +batch.disable=\u6279\u91cf\u7981\u7528 +batch.towhitelist=\u52a0\u5165\u767d\u540d\u5355 +batch.toblacklist=\u52a0\u5165\u9ed1\u540d\u5355 +confirm.favorites=\u786e\u8ba4\u6536\u85cf\u5417 +confirm.batch.towhitelist=\u786e\u8ba4\u52a0\u5165\u767d\u540d\u5355?
\u5c06\u7981\u6b62\u4e0d\u5728\u767d\u540d\u5355\u5185\u7684\u6240\u6709\u6d88\u8d39\u8005\u8bbf\u95ee\uff0c\u9ed1\u540d\u5355\u5931\u6548\u3002 +confirm.batch.toblacklist=\u786e\u8ba4\u52a0\u5165\u9ed1\u540d\u5355?
\u5982\u679c\u6ca1\u6709\u767d\u540d\u5355\uff0c\u5c06\u7981\u6b62\u5728\u9ed1\u540d\u5355\u5185\u7684\u6240\u6709\u5176\u5b83\u6d88\u8d39\u8005\u8bbf\u95ee\u3002 +confirm.enable=\u786e\u8ba4\u542f\u7528 +confirm.disable=\u786e\u8ba4\u7981\u7528 +confirm.edit=\u786e\u8ba4\u7f16\u8f91 +confirm.disableFeature=\u786e\u8ba4\u7981\u7528\u529f\u80fd +confirm.enableFeature=\u786e\u8ba4\u542f\u7528\u529f\u80fd +confirmDeleteOwner=\u786e\u8ba4\u5220\u9664\u8d1f\u8d23\u4eba +welcome=\u60a8\u597d +approve=\u5f85\u5ba1\u6279 +chinese.simple=\u7b80\u4f53\u4e2d\u6587 +chinese.tradition=\u7e41\u9ad4\u4e2d\u6587 +register.service=\u6ce8\u518c\u65b0\u670d\u52a1 +erratum.guide=\u6392\u9519\u5411\u5bfc +preview.guide=\u9884\u89c8\u5411\u5bfc +sysinfo.status=\u6ce8\u518c\u4e2d\u5fc3\u72b6\u6001 +sysinfo.registries=\u6ce8\u518c\u4e2d\u5fc3\u96c6\u7fa4 +sysinfo.connections=\u5957\u63a5\u5b57\u8fde\u63a5 +sysinfo.cached=\u5185\u5b58\u7f13\u5b58 +sysinfo.failed=\u5931\u8d25\u8bb0\u5f55 +sysinfo.operations=\u64cd\u4f5c\u8bb0\u5f55 +sysinfo.logs=\u7cfb\u7edf\u65e5\u5fd7 +sysinfo.versions=Dubbo\u7248\u672c +sysinfo.dumps=\u7cfb\u7edf\u5feb\u7167 +sysinfo.envs=\u7cfb\u7edf\u73af\u5883 +sysinfo.helps=\u5e2e\u52a9\u6587\u6863 +system.management=\u7cfb\u7edf\u7ba1\u7406 +sysmanage.users=\u7528\u6237\u7ba1\u7406 +sysmanage.configs=\u7cfb\u7edf\u53c2\u6570\u8bbe\u7f6e +sysmanage.features=\u7cfb\u7edf\u529f\u80fd\u5f00\u5173 +system.function.control=\u7cfb\u7edf\u529f\u80fd\u5f00\u5173 +personal.set=\u4e2a\u4eba\u8bbe\u7f6e +modify.personalinfo=\u4fee\u6539\u4e2a\u4eba\u4fe1\u606f +modify.personal.password=\u4fee\u6539\u4e2a\u4eba\u5bc6\u7801 +operation.operateaddress=\u64cd\u4f5c\u8005\u5730\u5740 +operation.operatetype=\u64cd\u4f5c\u7c7b\u578b +operation.datatype=\u6570\u636e\u7c7b\u578b +operation.data=\u64cd\u4f5c\u5185\u5bb9 +operation.createtime=\u64cd\u4f5c\u65f6\u95f4 +operation.clean=\u6e05\u7406 +passwd.oldwrong=\u65e7\u5bc6\u7801\u9519\u8bef +failed=\u5931\u8d25\u8bb0\u5f55 +failed_type=\u7c7b\u578b +failed_data=\u6570\u636e +failed_sync=\u540c\u6b65\u5730\u5740\u5931\u8d25\u8bb0\u5f55 +failed_subscribe=\u8ba2\u9605\u5931\u8d25\u8bb0\u5f55 +failed_notify=\u901a\u77e5\u5931\u8d25\u8bb0\u5f55 +failed_collect=\u7edf\u8ba1\u5931\u8d25\u8bb0\u5f55 +failed_register=\u6ce8\u518c\u5931\u8d25\u8bb0\u5f55 +failed_redirect=\u91cd\u5b9a\u5411\u5931\u8d25\u8bb0\u5f55 +failed_disconnect=\u65ad\u5f00\u6e05\u7406\u5931\u8d25\u8bb0\u5f55 +clientAddress=\u5ba2\u6237\u7aef\u5730\u5740 +overrideAddress=\u8986\u76d6\u5730\u5740 +serviceInfo=\u670d\u52a1\u4fe1\u606f +consumerAddress=\u6d88\u8d39\u8005\u5730\u5740 +providerAddress=\u63d0\u4f9b\u8005\u5730\u5740 +registryAddress=\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740 +serviceName=\u670d\u52a1\u540d +serviceUrl=\u670d\u52a1\u5730\u5740 +overrideConsumerAddress=\u53ea\u63a8\u9001\u7ed9\u6307\u5b9a\u6d88\u8d39\u8005\u5730\u5740 +overrideProviderAddress=\u53ea\u5728\u8c03\u7528\u6307\u5b9a\u63d0\u4f9b\u8005\u5730\u5740\u65f6\u751f\u6548 +tipConsumerAddress=\u4e0d\u586b\u8868\u793a\u5bf9\u6d88\u8d39\u8005\u5e94\u7528\u7684\u6240\u6709\u673a\u5668\u751f\u6548 +tipProviderAddress=\u4e0d\u586b\u8868\u793a\u5bf9\u670d\u52a1\u7684\u6240\u6709\u63d0\u4f9b\u8005\u673a\u5668\u751f\u6548 +tipProviderAddress=\u4e0d\u586b\u8868\u793a\u5bf9\u670d\u52a1\u7684\u6240\u6709\u63d0\u4f9b\u8005\u673a\u5668\u751f\u6548 +logs=\u7cfb\u7edf\u65e5\u5fd7 +logs.file=\u65e5\u5fd7\u6587\u4ef6 +logs.size=\u6587\u4ef6\u5927\u5c0f +logs.modify=\u4fee\u6539\u65f6\u95f4 +logs.level=\u65e5\u5fd7\u7ea7\u522b +change.log.level=\u4fee\u6539\u65e5\u5fd7\u7ea7\u522b +logs.confirmChangeLogLevel=\u786e\u8ba4\u4fee\u6539\u65e5\u5fd7\u7ea7\u522b +cached=\u5185\u5b58\u7f13\u5b58 +cached.type=\u7c7b\u578b +cached.data=\u6570\u636e +cached.reload=\u91cd\u65b0\u52a0\u8f7d +batch.cached.reload=\u6279\u91cf\u91cd\u65b0\u52a0\u8f7d +cached.recover=\u6062\u590d +batch.cached.recover=\u6279\u91cf\u6062\u590d +servicePrivilege=\u670d\u52a1\u6743\u9650 +creator=\u521b\u5efa\u8005 +name=\u540d\u79f0 +department=\u90e8\u95e8 +email=\u90ae\u7bb1 +phone=\u7535\u8bdd +alitalk=\u963f\u91cc\u65fa\u65fa +password=\u5bc6\u7801 +roleR=\u8d85\u7ea7\u7ba1\u7406\u5458 +roleA=\u7ba1\u7406\u5458 +roleG=\u6e38\u5ba2 +roleDescR=\u7ba1\u7406\u6240\u6709 +roleDescA=\u7ba1\u7406\u81ea\u5df1\u521b\u5efa\u7684\u7528\u6237\u548c\u670d\u52a1 +roleDescG=\u53ea\u67e5\u770b +oldPassword=\u65e7\u5bc6\u7801 +newPassword=\u65b0\u5bc6\u7801 +reset=\u91cd\u7f6e +restPassword=\u91cd\u7f6e\u5bc6\u7801 +confirmNewPassword=\u786e\u8ba4\u65b0\u5bc6\u7801 +owns=\u8d1f\u8d23\u7684\u670d\u52a1 +confirmPassword=\u786e\u8ba4\u5bc6\u7801 +generatePassword=\u751f\u6210\u5bc6\u7801 +displayName=\u59d3\u540d +locale=\u4f7f\u7528\u8bed\u8a00 +privilegeTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7(,)\u5206\u9694\uff0c\u901a\u914d\u7b26\u7528\u661f\u53f7(*)\u8868\u793a\uff0c\u53ea\u80fd\u5728\u6bcf\u4e2a\u503c\u7684\u672a\u5c3e\u4f7f\u7528\u901a\u914d\u7b26\uff0c\u88ab\u6388\u4e0e\u7684\u6743\u9650\u4e0d\u80fd\u8d85\u51fa\u5f53\u524d\u7ba1\u7406\u4eba\u5458\u7684\u6743\u9650 +displayNameTip=\u7528\u6237\u59d3\u540d\uff0c\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-50\u4e2a\u5b57\u7b26\u7ec4\u6210 +emailTip=\u7528\u4e8e\u63a5\u6536\u7cfb\u7edf\u90ae\u4ef6\uff0c\u53ef\u4ee5\u8f93\u5165\u591a\u4e2a\u90ae\u4ef6\u5730\u5740\uff0c\u4f7f\u7528\u82f1\u6587\u5206\u53f7\u5206\u9694(;)\uff0c \u5f62\u5982 foo1@163.comj;foo2@gmail.com +userLocaleTip=\u53d1\u9001\u7cfb\u7edf\u90ae\u4ef6\u65f6\uff0c\u5c06\u6839\u636e\u7528\u6237\u4f7f\u7528\u7684\u8bed\u8a00\u53d1\u9001\u4e0d\u540c\u8bed\u8a00\u7684\u90ae\u4ef6\u5185\u5bb9 +DisplayNameTip +EmailTip +UserLocaleTip +missRequestParameters=\u4e22\u5931\u8bf7\u6c42\u53c2\u6570 +haveNoRootPrivilege=\u6ca1\u6709root\u6743\u9650 +confirmReloadCache=\u786e\u8ba4\u91cd\u65b0\u52a0\u8f7d\u7f13\u5b58 +confirmDeleteRegistry=\u786e\u8ba4\u5220\u9664\u6ce8\u518c\u4e2d\u5fc3 +confirmAutoRedirectRegistry=\u786e\u8ba4\u91cd\u5b9a\u5411\u6ce8\u518c\u4e2d\u5fc3 +confirmDeleteExpiredRegistry=\u786e\u8ba4\u5220\u9664\u8fc7\u671f\u6ce8\u518c\u4e2d\u5fc3 +confirmSyncRegistry=\u786e\u8ba4\u540c\u6b65\u6ce8\u518c\u4e2d\u5fc3\u5730\u5740\u5217\u8868\u5230\u5ba2\u6237\u7aef +confirm.toblacklist=\u786e\u8ba4\u52a0\u5165\u9ed1\u540d\u5355?
\u5982\u679c\u6ca1\u6709\u767d\u540d\u5355\uff0c\u5c06\u7981\u6b62\u5728\u9ed1\u540d\u5355\u5185\u7684\u6240\u6709\u6d88\u8d39\u8005\u8bbf\u95ee\u3002 +confirm.towhitelist=\u786e\u8ba4\u52a0\u5165\u767d\u540d\u5355?
\u5c06\u7981\u6b62\u4e0d\u5728\u767d\u540d\u5355\u5185\u7684\u6240\u6709\u5176\u5b83\u6d88\u8d39\u8005\u8bbf\u95ee\uff0c\u9ed1\u540d\u5355\u5931\u6548\u3002 +confirm.clean.operation=\u786e\u8ba4\u6e05\u9664\u64cd\u4f5c\u8bb0\u5f55 +autoRedirect=\u81ea\u52a8\u91cd\u5b9a\u5411 +deleteExpired=\u5220\u9664\u6240\u6709\u5df2\u8fc7\u671f +sync=\u540c\u6b65 +legacies=1.0\u9057\u7559\u5ba2\u6237\u7aef +logined=\u5df2\u767b\u5f55\u5ba2\u6237\u7aef +dumps=\u7cfb\u7edf\u5feb\u7167 +Registry=\u6ce8\u518c\u4e2d\u5fc3\u7248\u672c +Java=JDK\u7248\u672c +Locale=\u8bed\u8a00 +OS=\u64cd\u4f5c\u7cfb\u7edf +Uptime=\u8fd0\u884c\u65f6\u95f4 +Host=\u57df\u540d +CPU=\u0043\u0050\u0055 +confirmEnableUser=\u786e\u8ba4\u542f\u52a8\u7528\u6237 +confirmDisableUser=\u786e\u8ba4\u7981\u7528\u7528\u6237 +documentTitle=\u6587\u6863\u6807\u9898 +documentLink/documentPage=\u94fe\u63a5\u5730\u5740/\u9875\u9762\u5185\u5bb9 +documentInternal=\u9875\u9762 +documentExternal=\u94fe\u63a5 +documentApi=API +documentType=\u6587\u6863\u7c7b\u578b +documentContent=\u6587\u6863\u5185\u5bb9 +Yes=\u662f +No=\u5426 +returnValue=\u8fd4\u56de\u503c +throwException=\u629b\u51fa\u5f02\u5e38 +#BatchAddressTip=\u591a\u4e2a\u5730\u5740\u7528\u6362\u884c\u7b26\u5206\u9694\uff0c\u5730\u5740\u5fc5\u9700\u662f0.0.0.0\u5230255.255.255.255\u7684IP\u5730\u5740 +#AccessControlTip=\u767d\u540d\u5355\u4f18\u5148\uff0c\u53ea\u8981\u6709\u767d\u540d\u5355\uff0c\u5219\u767d\u540d\u5355\u751f\u6548\uff0c\u5426\u5219\u9ed1\u540d\u5355\u751f\u6548 +#RouteNameTip=\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-200\u4e2a\u5b57\u7b26\u7ec4\u6210 +#RoutePriorityTip=\u6570\u5b57\u8d8a\u5927\u8d8a\u4f18\u5148 +#RouteMethodTip=\u53ea\u6709Dubbo2.0.0\u4ee5\u4e0a\u7248\u672c\u7684\u670d\u52a1\u6d88\u8d39\u7aef\u652f\u6301\u6309\u65b9\u6cd5\u8def\u7531\uff0c\u591a\u4e2a\u65b9\u6cd5\u540d\u7528\u9017\u53f7\u5206\u9694 +#Choose=\u8bf7\u9009\u62e9 +#RouteMatchTip=\u5f53\u6d88\u8d39\u8005\u6ee1\u8db3\u5339\u914d\u6761\u4ef6\u65f6\u4f7f\u7528\u5f53\u524d\u89c4\u5219\u8fdb\u884c\u8fc7\u6ee4 +#RouteHostTip=\u591a\u4e2a\u503c\u7528\u9017\u53f7\u5206\u9694\uff0c\u4ee5\u661f\u53f7\u7ed3\u5c3e\u8868\u793a\u901a\u914d\u5730\u5740\u6bb5 +#RouteClusterTip=\u53ef\u901a\u8fc7\u83dc\u5355"\u670d\u52a1\u63a7\u5236"->"\u670d\u52a1\u5668\u96c6\u7fa4"\u7ba1\u7406 +#RouteFilterTip=\u6ee1\u8db3\u8fc7\u6ee4\u89c4\u5219\u7684\u63d0\u4f9b\u8005\u5730\u5740\u5c06\u88ab\u63a8\u9001\u7ed9\u6d88\u8d39\u8005 +testMethodTip=\u5982\u679c\u6709\u65b9\u6cd5\u91cd\u8f7d\u6216\u4f7f\u7528Dubbo1.0.x\u7248\u672c\u7684\u670d\u52a1\u63d0\u4f9b\u8005\uff0c\u9700\u5199\u5168\u65b9\u6cd5\u7b7e\u540d\uff0c\u5982\uff1afindBy(int,java.lang.String)\uff0c\u5426\u5219\u53ea\u9700\u65b9\u6cd5\u540d\uff0c\u5982\uff1afindBy +testJsonTip=JSON\u683c\u5f0f\uff1a\u5b57\u7b26\u4e32\u7528\u53cc\u5f15\u53f7\u8868\u793a\uff0c\u5982\uff1a"\u5b57\u7b26\u4e32"\uff0c\u6570\u5b57\u548cBoolean\u503c\u4e0d\u7528\u5f15\u53f7\uff0c\u5982\uff1a123 \u548c true \u6216 false\uff0cPOJO\u5bf9\u8c61\u6216Map\u7528\u5927\u62ec\u53f7\u8868\u793a\uff0c\u5982\uff1a{"\u5c5e\u6027\u540d1": "\u5c5e\u6027\u503c1", "\u5c5e\u6027\u540d2": "\u5c5e\u6027\u503c2"}\uff0c\u6570\u7ec4\u6216List\u6216Set\u7528\u65b9\u62ec\u53f7\u8868\u793a\uff0c\u5982\uff1a["\u503c1", "\u503c2"] +testParametersTip=\u5f53\u4e3a\u65e0\u53c2\u6570\u65b9\u6cd5\u65f6\u53c2\u6570\u503c\u53ef\u4ee5\u4e0d\u586b\uff0c\u53c2\u6570\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testResultTip=\u5f53\u4e3avoid\u65b9\u6cd5\u65f6\u7ed3\u679c\u53ef\u4ee5\u4e0d\u586b\uff0c\u629b\u51fa\u5f02\u5e38\u4f7f\u7528\u5f02\u5e38\u7c7b\u5168\u540d\u8868\u793a\uff0c\u8fd4\u56de\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testAutoRunTip=\u5982\u679c\u8bbe\u7f6e\u4e3a\u81ea\u52a8\u8fd0\u884c\uff0c\u82e5\u8be5\u670d\u52a1\u5df2\u6ce8\u518c\u6216\u65b0\u6ce8\u518c\uff0c\u5219\u81ea\u52a8\u8fd0\u884c\u6b64\u6d4b\u8bd5\u7528\u4f8b\uff0c\u8fd0\u884c\u5931\u8d25\uff0c\u5c06\u53d1\u9001\u90ae\u4ef6 +confirmRunTest=\u786e\u8ba4\u8fd0\u884c\u6d4b\u8bd5 +confirm.runAll=\u786e\u8ba4\u5bf9\u6240\u6709\u63d0\u4f9b\u8005\u8fd0\u884c\u6d4b\u8bd5 +# +#anonymous=\u533f\u540d +#Unuse=\u672a\u4f7f\u7528 +#RouteName=\u8def\u7531\u540d +#Priority=\u4f18\u5148\u7ea7 +#MatchRule=\u5339\u914d\u6761\u4ef6 +#ConsumerHost=\u6d88\u8d39\u8005IP\u5730\u5740 +#ConsumerCluster=\u6d88\u8d39\u8005\u96c6\u7fa4 +#FilterRule=\u8fc7\u6ee4\u89c4\u5219 +#ProviderHost=\u63d0\u4f9b\u8005IP\u5730\u5740 +#ProviderCluster=\u63d0\u4f9b\u8005\u96c6\u7fa4 +#ProviderProtocol=\u63d0\u4f9b\u8005\u534f\u8bae +#ProviderPort=\u63d0\u4f9b\u8005\u7aef\u53e3 +#Match=\u5339\u914d +#Mismatch=\u4e0d\u5339\u914d +#ConsumerAddress=\u6d88\u8d39\u8005\u5730\u5740 +generic=\u6cdb\u5316 +doubling=\u500d\u6743 +loadBalanceStrategy=\u8d1f\u8f7d\u5747\u8861\u7b56\u7565 +random=\u968f\u673a +roundrobin=\u8f6e\u8be2 +leastactive=\u6700\u5c11\u5e76\u53d1 +testName=\u6d4b\u8bd5\u7528\u4f8b\u540d\u79f0 +operator=\u64cd\u4f5c +dataFormat=\u6570\u636e\u683c\u5f0f +resultType=\u7ed3\u679c\u7c7b\u578b +resultController=\u8fd4\u56de\u503c/\u5f02\u5e38\u7c7b\u578b +autoRun=\u81ea\u52a8\u8fd0\u884c +manualRun=\u624b\u52a8\u8fd0\u884c +run=\u8fd0\u884c +runAll=\u8fd0\u884c\u6240\u6709\u63d0\u4f9b\u8005 +expected=\u671f\u671b\u7ed3\u679c +actual=\u5b9e\u9645\u7ed3\u679c +reRun=\u91cd\u65b0\u8fd0\u884c +#Username=\u7528\u6237\u540d +#DisplayName=\u663e\u793a\u540d +#Department=\u90e8\u95e8 +#Email=\u90ae\u7bb1 +#Phone=\u624b\u673a +#Alitalk=\u65fa\u65fa +startDate=\u542f\u52a8\u65f6\u95f4 +console=\u63a7\u5236\u53f0 +total=\u603b\u6570 +delta=\u504f\u5dee +expired=\u8fc7\u671f +alived=\u5b58\u6d3b +redirect=\u91cd\u5b9a\u5411 +current=\u5f53\u524d +#overrides +override.config=\u52a8\u6001\u914d\u7f6e +override.mock=\u670d\u52a1\u964d\u7ea7 +parameter=\u53c2\u6570 +parameter.key=\u53c2\u6570\u540d +parameter.value=\u53c2\u6570\u503c +parameter.tip=\u65b9\u6cd5\u7ea7\u914d\u7f6e\u5982\uff1afindPerson.timeout=1000 +mock.all.method=\u6240\u6709\u65b9\u6cd5\u7684Mock\u503c +mock.method=\u65b9\u6cd5 +mock.value=\u7684Mock\u503c +mock.tip=\u793a\u4f8b\uff1areturn null/empty/JSON\u6216throw com.foo.BarException +protocol=\u534F\u8BAE +host=\u4E3B\u673A\u540D +port=\u7AEF\u53E3 +interface=\u63A5\u53E3\u540D +version=\u7248\u672C +group=\u5206\u7EC4 +methods=\u65B9\u6CD5\u5217\u8868 +category=\u6570\u636E\u7C7B\u578B +application=\u5E94\u7528\u540D +owner=\u8D1F\u8D23\u4EBA +cluster=\u96C6\u7FA4 +loadbalance=\u8D1F\u8F7D\u5747\u8861 +timeout=\u8D85\u65F6 +retries=\u91CD\u8BD5\u6B21\u6570 +threads=\u7EBF\u7A0B\u6570 +connections=\u8FDE\u63A5\u6570 +accepts=\u63A5\u6536\u8FDE\u63A5\u6570 +actives=\u5BA2\u6237\u7AEF\u5E76\u53D1\u8BF7\u6C42\u9650\u5236 +executes=\u7EBF\u7A0B\u6C60\u5E76\u53D1\u6267\u884C\u9650\u5236 +check=\u68C0\u67E5 +side=\u6240\u5C5E\u7AEF +pid=\u8FDB\u7A0B\u53F7 +timestamp=\u65F6\u95F4\u6233 +dubbo=Dubbo\u7248\u672C +anyhost=\u7ED1\u5B9A\u6240\u6709IP +weight=\u6743\u91CD +weight.doubling=\u500D\u6743 +weight.halving=\u534A\u6743 +confirm.weight.doubling=\u786E\u8BA4\u6743\u91CD\u52A0\u500D? +confirm.weight.halving=\u786E\u8BA4\u6743\u91CD\u51CF\u534A? +batch.weight.doubling=\u6279\u91CF\u500D\u6743 +batch.weight.halving=\u6279\u91CF\u534A\u6743 +confirm.batch.weight.doubling=\u786E\u8BA4\u6240\u9009\u9879\u6743\u91CD\u52A0\u500D? +confirm.batch.weight.halving=\u786E\u8BA4\u6240\u9009\u9879\u6743\u91CD\u51CF\u534A? +NoSuchOperationData=\u64CD\u4F5C\u7684\u6570\u636E\u4E0D\u5B58\u5728\u3002 +CanNotDeleteDynamicData=\u4E0D\u80FD\u5220\u9664\u52A8\u6001\u6570\u636E\u3002 +HaveNoServicePrivilege=\u60A8\u6CA1\u6709\u8BE5\u670D\u52A1\u7684\u6743\u9650\u3002 +dynamic.parameters.tip=\u52A8\u6001URL\u4E0D\u80FD\u76F4\u63A5\u4FEE\u6539\uFF0C\u9700\u901A\u8FC7\u52A8\u6001\u914D\u7F6E\u8FDB\u884C\u8986\u76D6\uFF0C\u683C\u5F0F\u4E0EURL\u53C2\u6570\u76F8\u540C\u3002 +default.owner=\u8d1f\u8d23\u4eba +logger=\u65e5\u5fd7 +default.server=\u9ed8\u8ba4\u670d\u52a1\u7aef +default.actives=\u5e76\u53d1\u8c03\u7528\u6570 +default.client=\u9ed8\u8ba4\u5ba2\u6237\u7aef +default.connections=\u6700\u5927\u8fde\u63a5\u6570 diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh_TW.properties b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh_TW.properties new file mode 100644 index 0000000..56ae82e --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/i18n/message_zh_TW.properties @@ -0,0 +1,726 @@ +# +# 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. +# + +#menus +home=\u9996\u9801 +about=\u95dc\u65bc +help=\u5e6b\u52a9 +revision=\u4fee\u8a02 +favorites=\u6211\u7684\u6700\u611b +histories=\u6b77\u53f2\u8a18\u9304 +governance=\u670d\u52d9\u6cbb\u7406 +applications=\u61c9\u7528 +efferents=\u4f9d\u8cf4 +afferents=\u88ab\u4f9d\u8cf4 +services=\u670d\u52d9 +references=\u5f15\u7528\u670d\u52d9 +addresses=\u6a5f\u5668 +providers=\u63d0\u4f9b\u8005 +dependencies=\u4f9d\u8cf4\u95dc\u4fc2 +layers=\u5206\u5c64 +clusters=\u96c6\u7fa4 +consumers=\u6d88\u8cbb\u8005 +accesses=\u9ed1\u767d\u540d\u55ae +routes=\u8def\u7531 +weights=\u6b0a\u91cd +InvalidIP=\u7121\u6548\u0069\u0070\u5730\u5740 +loadbalances=\u8ca0\u8f09\u5747\u8861 +tests=\u6e2c\u8a66 +mocks=\u6a21\u64ec +overrides=\u52d5\u614b\u914d\u7f6e +documents=\u6587\u6a94 +owners=\u8ca0\u8cac\u4eba +agreements=\u5354\u5b9a +approvals=\u4e0a\u7dda\u5be9\u6279 +operations=\u64cd\u4f5c\u65e5\u8a8c +users=\u7528\u6236 +envs=\u7cfb\u7d71\u74b0\u5883 +helps=\u5e6b\u52a9\u6587\u6a94 +registries=\u8a3b\u518a\u4e2d\u5fc3 +configs=\u7cfb\u7d71\u53c3\u6578 +features=\u7cfb\u7d71\u529f\u80fd +connections=\u9023\u63a5 +statuses=\u72c0\u614b\u6e05\u55ae +failed=\u5931\u6557\u8a18\u9304 +cached=\u7de9\u5b58\u8a18\u9304 +dumps=\u5feb\u7167 +default.lazy=\u9ed8\u8a8d\u61f6\u555f\u52d5 +versions=Dubbo\u7248\u672c +service.filter=\u670d\u52d9filter +default.service.filter=\u9ed8\u8a8d\u670d\u52d9filter +logs=\u65e5\u8a8c +infos=\u4fee\u6539\u500b\u4eba\u8cc7\u8a0a +passwds=\u4fee\u6539\u500b\u4eba\u5bc6\u78bc +dependency.list=\u5217\u8868 +dependency.tree=\u6a39\u72c0 +dependency.graph=\u5716\u5f62 +dependency.efferent=\u4f9d\u8cf4 +dependency.afferent=\u88ab\u4f9d\u8cf4 +provided=\u63d0\u4f9b\u670d\u52d9 +consumed=\u6d88\u8cbb\u670d\u52d9 +select=\u9078\u64c7 +clean=\u6e05\u9664 +information=\u4fe1\u606f +control=\u63a7\u5236 +summary=\u532f\u7e3d +consumer.application=\u6d88\u8cbb\u8005\u61c9\u7528 +response.time=\u56de\u61c9\u6642\u9593 +sysinfo.infos=\u7cfb\u7d71\u8cc7\u8a0a +helps.document=\u6587\u6a94 +helps.requirement=\u9700\u6c42 +helps.source=\u539f\u59cb\u7a0b\u5f0f\u78bc +connections=\u901a\u8a0a\u7aef\u9023\u63a5 +ReconnectUnkwown=\u91cd\u9023\u6240\u6709\u672a\u77e5\u9023\u63a5 +confirmReconnectConnection=\u78ba\u8a8d\u91cd\u5efa\u9023\u63a5 +confirmRedirectRegistry=\u78ba\u8a8d\u91cd\u5b9a\u5411\u8a3b\u518a\u4e2d\u5fc3 +confirmReconnectUnknownConnection=\u78ba\u8a8d\u91cd\u9023\u672a\u77e5\u7684\u9023\u63a5 +status.resourcename=\u8cc7\u6e90\u540d\u7a31 +status.status=\u72c0\u614b +status.message=\u4fe1\u606f +status.description=\u63cf\u8ff0 +status.memoryStatus=\u8a18\u61b6\u9ad4 +status.memoryStatusDesc=\u53ea\u76e3\u63a7Heap\u8a18\u61b6\u9ad4\uff0c\u5982\u679c\u7a7a\u9592\u8a18\u61b6\u9ad4\u4e0d\u8db31M\u5247\u8b66\u544a\uff0c\u5426\u5247\u6b63\u5e38 +status.threadpoolStatus=\u57f7\u884c\u7dd2\u6c60 +status.threadpoolStatusDesc=\u53ea\u76e3\u63a7\u8a3b\u518a\u8a02\u95b1\u4e3b\u696d\u52d9\u57f7\u884c\u7dd2\u6c60\uff0c\u5982\u679c\u7a7a\u9592\u57f7\u884c\u7dd2\u5c11\u65bc1\u500b\uff0c\u5247\u8b66\u544a\uff0c\u5426\u5247\u6b63\u5e38 +status.failureStatus=\u5931\u6557\u8a18\u9304 +status.failureStatusDesc=\u7576\u6709\u4efb\u4f55\u5931\u6557\u8a18\u9304\u5247\u8b66\u544a\uff0c\u5426\u5247\u6b63\u5e38 +status.cacheStatus=\u7de9\u5b58 +status.cacheStatusDesc=\u5982\u679c\u7de9\u5b58\u8207\u8cc7\u6599\u5eab\u4e0d\u4e00\u81f4\u5247\u8b66\u544a\uff0c\u5426\u5247\u6b63\u5e38 +status.timerStatus=\u8a08\u6642\u5668 +status.timerStatusDesc=\u7576\u8a08\u6642\u5668\u672a\u6b63\u78ba\u555f\u52d5\uff0c\u6216\u88ab\u4e0d\u6b63\u5e38\u53d6\u6d88\uff0c\u5247\u5831\u932f\uff0c\u5426\u5247\u6b63\u5e38 +status.socketStatus=\u901a\u8a0a\u7aef +status.socketStatusDesc=\u7576\u5957\u4ecb\u9762\u958b\u555f\u4e0d\u4e86\u6216\u5df2\u88ab\u4f54\u7528\u6642\u5831\u932f\uff0c\u7576\u9023\u63a5\u6578\u7b49\u65bc\u6700\u5927\u503c\u6642\u8b66\u544a\uff0c\u5426\u5247\u6b63\u5e38 +status.loadStatus=\u8ca0\u8f09 +status.loadStatusDesc=\u5982\u679c\u8ca0\u8f09\u5927\u65bcCPU\u500b\u6578\u5247\u8b66\u544a\uff0c\u5982\u679c\u7cfb\u7d71\u4e0d\u652f\u63f4\u67e5\u8a62\u8ca0\u8f09\u5247\u4e0d\u555f\u7528\uff0c\u5426\u5247\u6b63\u5e38 +status.databaseStatus=\u8cc7\u6599\u5eab +status.databaseStatusDesc=\u767c\u9001\u4e00\u689d\u7c21\u55ae\u67e5\u8a62SQL\uff0c\u57f7\u884c\u6210\u529f\u5247\u6b63\u5e38\uff0c\u5426\u5247\u5831\u932f +status.threadPool=\u9032\u7a0b\u57f7\u884c\u7dd2 +status.threadPoolStatusDesc=\u76e3\u63a7\u9032\u7a0b\u7684\u57f7\u884c\u7dd2\u6c60 +status.monitorStatus=\u76e3\u8996\u5668 +status.monitorStatusDesc=\u76e3\u8996\u5668 +status.summaryStatus=\u532f\u7e3d +status.summaryStatusDesc=\u6709\u72c0\u614b\u532f\u7e3d\uff0c\u5ffd\u7565\u672a\u555f\u7528\u7684\u72c0\u614b\uff0c\u53ea\u8981\u6709\u4e00\u500b\u5831\u932f\uff0c\u5247\u5831\u932f\uff0c\u53ea\u8981\u6709\u4e00\u500b\u8b66\u544a\uff0c\u5247\u8b66\u544a\uff0c\u5168\u90e8\u6b63\u5e38\u5247\u6b63\u5e38 +status.warmupStatus=\u904b\u884c\u72c0\u614b +status.warmupStatusDesc=\u8655\u65bcwarmup\u72c0\u614b\u6642\uff0c\u9ad2\u8cc7\u6599\u6aa2\u6e2c\u3001\u91cd\u5b9a\u5411\u3001\u4e8b\u4ef6\u8b8a\u66f4\u8a08\u6642\u5668\u5747\u4e0d\u5de5\u4f5c,\u4e0d\u63a8\u9001\u8b8a\u66f4 +status.OK=\u6b63\u5e38 +status.WARN=\u8b66\u544a +status.ERROR=\u932f\u8aa4 +status.UNKNOWN=\u672a\u77e5 +Status0=Unknow +Status1=OK +Status2=OK +Status3=ERROR +Status4=FATAL +Status5=UNKNOW +mock=\u964d\u7d1a +force.mock=\u906e\u7f69 +fail.mock=\u5bb9\u932f +cancel.mock=\u6062\u5fa9 +confirm.force.mock=\u78ba\u8a8d\u906e\u7f69\u8a72\u670d\u52d9\u7684\u8abf\u7528\uff1f
\u5c07\u4e0d\u767c\u8d77\u9060\u7aef\u8abf\u7528\uff0c\u76f4\u63a5\u8fd4\u56de\u7a7a\u7269\u4ef6\u3002(\u53ef\u5728\u52d5\u614b\u914d\u7f6e\u9801\u9762\u4fee\u6539\u8fd4\u56de\u8cc7\u6599) +confirm.fail.mock=\u78ba\u8a8d\u5c0d\u8a72\u670d\u52d9\u5bb9\u932f\uff1f
\u7576\u8abf\u7528\u5931\u6557\u6642\uff0c\u8fd4\u56de\u7a7a\u7269\u4ef6\u3002(\u53ef\u5728\u52d5\u614b\u914d\u7f6e\u9801\u9762\u4fee\u6539\u8fd4\u56de\u8cc7\u6599) +confirm.cancel.mock=\u78ba\u8a8d\u6062\u5fa9\u8a72\u670d\u52d9\u6b63\u5e38\u8a2a\u554f\uff1f
\u5c07\u53d6\u6d88\u670d\u52d9\u7684\u906e\u7f69\u548c\u5bb9\u932f\u884c\u70ba\u3002 +batch.force.mock=\u6279\u91cf\u906e\u7f69 +batch.fail.mock=\u6279\u91cf\u5bb9\u932f +batch.cancel.mock=\u6279\u91cf\u6062\u5fa9 +confirm.batch.force.mock=\u78ba\u8a8d\u6279\u91cf\u906e\u7f69\u670d\u52d9\u7684\u8abf\u7528\uff1f
\u5c07\u4e0d\u767c\u8d77\u9060\u7aef\u8abf\u7528\uff0c\u76f4\u63a5\u8fd4\u56de\u7a7a\u7269\u4ef6\u3002(\u53ef\u5728\u52d5\u614b\u914d\u7f6e\u9801\u9762\u4fee\u6539\u8fd4\u56de\u8cc7\u6599) +confirm.batch.fail.mock=\u78ba\u8a8d\u6279\u91cf\u5c0d\u670d\u52d9\u5bb9\u932f\uff1f
\u7576\u8abf\u7528\u5931\u6557\u6642\uff0c\u8fd4\u56de\u7a7a\u7269\u4ef6\u3002(\u53ef\u5728\u52d5\u614b\u914d\u7f6e\u9801\u9762\u4fee\u6539\u8fd4\u56de\u8cc7\u6599) +confirm.batch.cancel.mock=\u78ba\u8a8d\u6279\u91cf\u6062\u5fa9\u670d\u52d9\u6b63\u5e38\u8a2a\u554f\uff1f
\u5c07\u53d6\u6d88\u670d\u52d9\u7684\u906e\u7f69\u548c\u5bb9\u932f\u884c\u70ba\u3002 +agreement.invocation.quantity=\u4e00\u5929\u8abf\u7528\u91cf +agreement.tps=TPS\u4e0a\u9650 +response.time=\u56de\u61c9\u6642\u9593 +agreement.availability=\u53ef\u7528\u7387 +layer.name=\u5206\u5c64\u540d\u7a31 +layer.value=\u6578\u4f4d\u7b49\u7d1a +layer.arch=\u5206\u5c64\u67b6\u69cb +loadBalanceStrategy=\u8ca0\u8f09\u5747\u8861\u7b56\u7565 +ServiceName=\u670d\u52d9\u540d +cluster.name=\u96c6\u7fa4\u540d +cluster.address=\u96c6\u7fa4\u6a5f\u5668\u5730\u5740 +property.name=\u5c6c\u6027\u540d +property.value=\u5c6c\u6027\u503c +property.count=\u5c6c\u6027\u6578\u91cf +getMethods=\u7372\u53d6\u670d\u52d9\u65b9\u6cd5 +getAddresses=\u7372\u53d6\u63d0\u4f9b\u8005\u5730\u5740 +Edit=\u7de8\u8f2f +Username=\u7528\u6236\u540d +Priority=\u512a\u5148\u9806\u5e8f +ConnectionAddress=\u9023\u63a5\u4f4d\u5740 +Role=\u89d2\u8272 +Reconnect=\u91cd\u9023 +Redirect=\u91cd\u5b9a\u5411 +staff.query=\u5167\u7db2\u67e5\u8a62 +configKey=\u914d\u7f6e\u9805 +configValue=\u914d\u7f6e\u9805\u503c +Preview=\u9810\u89bd +routeselect=\u8def\u7531\u9810\u89bd\uff08\u9078\u64c7\u6d88\u8cbb\u8005\uff09 +AllOperations=\u6240\u6709\u64cd\u4f5c\u8a18\u9304 +BeforeOneMonthOperations=\u4e00\u500b\u6708\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8a18\u9304 +BeforeThreeMonthOperations=\u4e09\u500b\u6708\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8a18\u9304 +BeforeHalfYearOperations=\u534a\u5e74\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8a18\u9304 +BeforeOneYearOperations=\u4e00\u5e74\u4ee5\u524d\u7684\u6240\u6709\u64cd\u4f5c\u8a18\u9304 +PleaseInput=\u8acb\u8f38\u5165 +BulletinConfig=\u516c\u544a\u914d\u7f6e +BulletinMessage=\u516c\u544a\u8cc7\u8a0a +MailConfig=\u90f5\u7bb1\u914d\u7f6e +MailEnabled=\u662f\u5426\u555f\u7528\u90f5\u7bb1 +MailHost=\u90f5\u4ef6\u4f3a\u670d\u5668\u4e3b\u6a5f +MailPort=\u90f5\u4ef6\u4f3a\u670d\u5668\u57e0 +MailFrom=\u90f5\u4ef6\u5bc4\u4ef6\u8005\u5730\u5740 +MailAuth=\u90f5\u7bb1\u662f\u5426\u9700\u8981\u767b\u9304 +MailUsername=\u90f5\u7bb1\u767b\u9304\u7528\u6236\u540d +MailPassword=\u90f5\u7bb1\u767b\u9304\u5bc6\u78bc +LoginConfig=\u767b\u9304\u914d\u7f6e +AllowAnonymousLogin=\u5141\u8a31\u533f\u540d\u767b\u5165 +AllowLegacyLogin=\u5141\u8a31\u907a\u7559\u7cfb\u7d71\u767b\u9304 +RouteEnabled=\u662f\u5426\u958b\u555f\u8def\u7531\u529f\u80fd +WarmupEnabled=\u662f\u5426\u9032\u5165\u9810\u71b1\u72c0\u614b +LogConfig=\u65e5\u8a8c\u914d\u7f6e +LogLevel=\u65e5\u8a8c\u7d1a\u5225 +RedirectConfig=\u91cd\u5b9a\u5411\u914d\u7f6e +AutoRedirectInterval=\u81ea\u52d5\u91cd\u5b9a\u5411\u6aa2\u67e5\u9593\u9694(\u6beb\u79d2) +AutoRedirectThreshold=\u80fd\u5920\u81ea\u52d5\u91cd\u5b9a\u5411\u7684\u9023\u63a5\u4e0b\u754c +AutoRedirectToleratePercent=\u81ea\u52d5\u91cd\u5b9a\u5411\u6642\u9023\u63a5\u6578\u504f\u5dee\u5bb9\u5fcd\u767e\u5206\u6bd4 +ManualRedirect=\u91cd\u5b9a\u5411{0}\u500b +LimitConfig=\u8cc7\u6e90\u9650\u5236\u914d\u7f6e +MaxThreadSize=\u6700\u5927\u57f7\u884c\u7dd2\u6578 +MaxConnectionSize=\u6700\u5927\u9023\u63a5\u6578 +MaxCacheSize=\u6700\u5927\u7de9\u5b58\u6578 +MaxMailSize=\u6700\u5927\u90f5\u4ef6\u4f47\u5217\u6578 +TimerConfig=\u8a08\u6642\u5668\u914d\u7f6e +AlivedCheckInterval=\u8a3b\u518a\u4e2d\u5fc3\u5b58\u6d3b\u72c0\u614b\u6aa2\u67e5\u9593\u9694(\u6beb\u79d2) +ChangedCheckInterval=\u8cc7\u6599\u8b8a\u66f4\u6aa2\u67e5\u9593\u9694(\u6beb\u79d2) +FailedRetryInterval=\u5931\u6557\u91cd\u8a66\u9593\u9694(\u6beb\u79d2) +DirtyCheckInterval=\u9ad2\u8cc7\u6599\u6aa2\u67e5\u9593\u9694(\u6beb\u79d2) +HeartbeatConfig=\u5fc3\u8df3\u914d\u7f6e +HeartbeatCheckInterval=\u8207\u7528\u6236\u7aef\u9023\u63a5\u5fc3\u8df3\u6aa2\u67e5\u9593\u9694(\u6beb\u79d2) +HeartbeatCheckTimeout=\u5fc3\u8df3\u8d85\u6642\u6642\u9593(\u6beb\u79d2) +TimeoutConfig=\u8d85\u6642\u914d\u7f6e +NotifyTimeout=\u4e8b\u4ef6\u63a8\u9001\u8d85\u6642(\u6beb\u79d2) +WarmupWaitTime=\u555f\u52d5\u9810\u71b1\u6642\u9593(\u6beb\u79d2) +UrlConfig=URL\u914d\u7f6e +BucServiceAddress=BUC\u670d\u52d9\u4f4d\u5740 +HelpDocumentUrl=\u5e6b\u52a9\u6587\u6a94URL +HomepageDomain=\u986f\u793a\u4e3b\u9801\u529f\u80fd\u8b8a\u6578\u540d\u7a31 +HomepageUrl=\u4e3b\u9801\u5730\u5740 +parametersConfig=\u53c3\u6578\u914d\u7f6e +DefaultServiceParameters=\u7f3a\u7701\u53c3\u6578\u914d\u7f6e +BatchAddressTip=\u591a\u500b\u4f4d\u5740\u7528\u5206\u884c\u7b26\u865f\u5206\u9694\uff0c\u4f4d\u5740\u5fc5\u9700\u662f0.0.0.0\u5230255.255.255.255\u7684IP\u5730\u5740 +ConsumerAddress=\u6d88\u8cbb\u8005\u5730\u5740 +AccessControlTip=\u767d\u540d\u55ae\u512a\u5148\uff0c\u53ea\u8981\u6709\u767d\u540d\u55ae\uff0c\u5247\u767d\u540d\u55ae\u751f\u6548\uff0c\u5426\u5247\u9ed1\u540d\u55ae\u751f\u6548 +Allowed=\u767d\u540d\u55ae +Forbidden=\u9ed1\u540d\u55ae +Choose=\u8acb\u9078\u64c7 +userown=\u8ca0\u8cac\u7684\u670d\u52d9 +sysmanage.userown=\u8ca0\u8cac\u7684\u670d\u52d9 +SingleServiceTip=\u4e00\u500b\u8def\u7531\u53ea\u80fd\u61c9\u7528\u65bc\u4e00\u500b\u670d\u52d9\uff0c\u4e0d\u652f\u63f4\u591a\u670d\u52d9\u53ca\u842c\u7528\u5b57\u5143 +MultiServiceTip=\u670d\u52d9\u4ecb\u9762\u540d\u53ef\u4ee5\u4f7f\u7528\u842c\u7528\u5b57\u5143\uff0c\u53ea\u652f\u63f4\u4e00\u500b*\u7b26\u4e14\u8981\u5728\u4ecb\u9762\u672b\u5c3e\uff08\u5206\u7d44\u3001\u7248\u672c\u4e0d\u652f\u63f4\u842c\u7528\u5b57\u5143\uff09 +RouteNameTip=\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-200\u500b\u5b57\u5143\u7d44\u6210 +RoutePriorityTip=\u6578\u5b57\u8d8a\u5927\u8d8a\u512a\u5148 +RouteServiceTip=\u4e00\u500b\u8def\u7531\u53ea\u80fd\u61c9\u7528\u65bc\u4e00\u500b\u670d\u52d9\uff0c\u4e0d\u652f\u63f4\u591a\u670d\u52d9\u53ca\u842c\u7528\u5b57\u5143 +#RouteServiceTip=\u670d\u52d9\u4ecb\u9762\u540d\u53ef\u4ee5\u4f7f\u7528\u842c\u7528\u5b57\u5143\uff0c\u53ea\u652f\u63f4\u4e00\u500b*\u7b26\u4e14\u8981\u5728\u4ecb\u9762\u672b\u5c3e\uff08\u5206\u7d44\u3001\u7248\u672c\u4e0d\u652f\u63f4\u842c\u7528\u5b57\u5143\uff09 +RouteMethodTip=\u53ea\u6709Dubbo2.0.0\u4ee5\u4e0a\u7248\u672c\u7684\u670d\u52d9\u6d88\u8cbb\u7aef\u652f\u63f4\u6309\u65b9\u6cd5\u8def\u7531\uff0c\u591a\u500b\u65b9\u6cd5\u540d\u7528\u9017\u865f\u5206\u9694 +RouteClusterTip=\u53ef\u901a\u904e\u529f\u80fd\u8868"\u670d\u52d9\u63a7\u5236"->"\u4f3a\u670d\u5668\u96c6\u7fa4"\u7ba1\u7406 +RouteMatchTip=\u7576\u6d88\u8cbb\u8005\u6eff\u8db3\u5339\u914d\u689d\u4ef6\u6642\u4f7f\u7528\u7576\u524d\u898f\u5247\u9032\u884c\u904e\u6ffe +RouteFilterTip=\u6eff\u8db3\u904e\u6ffe\u898f\u5247\u7684\u63d0\u4f9b\u8005\u4f4d\u5740\u5c07\u88ab\u63a8\u9001\u7d66\u6d88\u8cbb\u8005 +RouteHostTip=\u591a\u500b\u503c\u7528\u9017\u865f\u5206\u9694\uff0c\u4ee5\u661f\u865f\u7d50\u5c3e\u8868\u793a\u901a\u914d\u4f4d\u5740\u6bb5 +RouteApplicationTip=\u591a\u500b\u503c\u7528\u9017\u865f\u5206\u9694 +RouteResult=\u8def\u7531\u7d50\u679c +preview=\u9810\u89bd +ConsumerApplication=\u6d88\u8cbb\u8005\u61c9\u7528\u540d +ConsumerCluster=\u6d88\u8cbb\u8005\u96c6\u7fa4 +ConsumerHost=\u6d88\u8cbb\u8005IP\u5730\u5740 +ConsumerVersion=\u6d88\u8cbb\u8005\u7248\u672c\u865f +ConsumerGroup=\u6d88\u8cbb\u8005\u540d\u7a31\u7a7a\u9593 +ProviderApplication=\u63d0\u4f9b\u8005\u61c9\u7528 +ProviderCluster=\u63d0\u4f9b\u8005\u96c6\u7fa4 +ProviderProtocol=\u63d0\u4f9b\u8005\u5354\u5b9a +ProviderHost=\u63d0\u4f9b\u8005IP\u5730\u5740 +ProviderPort=\u63d0\u4f9b\u8005\u57e0 +ProviderVersion=\u63d0\u4f9b\u8005\u7248\u672c\u865f +ProviderGroup=\u63d0\u4f9b\u8005\u540d\u7a31\u7a7a\u9593 +MatchRule=\u5339\u914d\u689d\u4ef6 +FilterRule=\u904e\u6ffe\u898f\u5247 +routeRule=\u8def\u7531\u898f\u5247 +Match=\u5339\u914d +Mismatch=\u4e0d\u5339\u914d +GetMethods=\u7372\u53d6\u670d\u52d9\u65b9\u6cd5 +FeatureName=\u529f\u80fd\u540d +Features=\u7cfb\u7d71\u529f\u80fd +Disable=\u7981\u7528 +Enable=\u555f\u7528 +Enabled=\u5df2\u555f\u7528 +Disabled=\u5df2\u7981\u7528 +Unknown=\u672a\u77e5 +Users=\u7528\u6236\u7ba1\u7406 +UsersDescription=\u4f7f\u7528\u8005\u8cc7\u8a0a\u7ba1\u7406 +StatusList=\u8a3b\u518a\u4e2d\u5fc3\u72c0\u614b +StatusListDescription=\u8a3b\u518a\u4e2d\u5fc3\u7cfb\u7d71\u72c0\u614b +Operations=\u64cd\u4f5c\u8a18\u9304 +OperationsDescription=\u8a18\u9304\u6240\u6709\u4eba\u70ba\u7684\u64cd\u4f5c +Accesses=\u670d\u52d9\u9ed1\u767d\u540d\u55ae +AccessesDescription=\u670d\u52d9\u9ed1\u767d\u540d\u55ae +Configs=\u7cfb\u7d71\u7d44\u614b +Clusters=\u4f3a\u670d\u5668\u96c6\u7fa4 +ClustersDescription=\u7ba1\u7406\u670d\u52d9\u96c6\u7fa4\u8cc7\u8a0a +Weights=\u63d0\u4f9b\u8005\u6b0a\u91cd +WeightsDescription=\u7ba1\u7406\u63d0\u4f9b\u8005\u6b0a\u91cd\u8cc7\u8a0a +Agreements=\u670d\u52d9\u7b49\u7d1a\u5354\u5b9a +AgreementsDescription=\u670d\u52d9\u7b49\u7d1a\u5354\u5b9a +ConfigsDescription=\u7cfb\u7d71\u7d44\u614b\u4fe1\u606f +LoadBalances=\u8ca0\u8f09\u5747\u8861 +LoadBalancesDescription=\u8ca0\u8f09\u5747\u8861 +CachedList=\u8a18\u61b6\u9ad4\u7de9\u5b58 +CachedListDescription=\u8a3b\u518a\u4e2d\u5fc3\u8a18\u61b6\u9ad4\u7de9\u5b58\u8a18\u9304 +FailedList=\u5931\u6557\u8a18\u9304 +Registries=\u8a3b\u518a\u4e2d\u5fc3\u96c6\u7fa4 +FailedListDescription=\u5931\u6557\u8a18\u9304\u6e05\u55ae +registryAddress=\u8a3b\u518a\u4e2d\u5fc3\u5217\u8868 +RegistriesDescription=\u67e5\u770b\u5df2\u77e5\u7684\u8a3b\u518a\u4e2d\u5fc3 +Help=\u5e6b\u52a9 +HelpDescription=\u5e6b\u52a9 +Providers=\u670d\u52d9\u63d0\u4f9b\u8005 +ProvidersDescription=\u67e5\u770b\u6240\u6709\u670d\u52d9\u63d0\u4f9b\u8005 +Log=\u65e5\u8a8c\u6a94 +LogDescription=\u67e5\u770b\u8a3b\u518a\u4e2d\u5fc3Log4J\u65e5\u8a8c +Services=\u670d\u52d9\u8cc7\u8a0a +ServicesDescription=\u67e5\u770b\u670d\u52d9\u5df2\u8a3b\u518a\u7684\u6240\u6709\u670d\u52d9 +Owned=\u670d\u52d9\u6b78\u5c6c +OwnedDescription=\u670d\u52d9\u6b78\u5c6c +Tests=\u670d\u52d9\u6e2c\u8a66 +TestsDescription=\u670d\u52d9\u6e2c\u8a66\u7528\u4f8b +Documents=\u670d\u52d9\u6587\u6a94 +DocumentsDescription=\u6587\u6a94 +Applications=\u670d\u52d9\u61c9\u7528 +ApplicationsDescription=\u670d\u52d9\u61c9\u7528 +Consumers=\u670d\u52d9\u6d88\u8cbb\u8005 +ConsumersDescription=\u67e5\u770b\u6240\u6709\u670d\u52d9\u6d88\u8cbb\u8005 +System=\u7cfb\u7d71\u74b0\u5883 +SystemDescription=\u7cfb\u7d71\u74b0\u5883\u8cc7\u8a0a +Routes=\u670d\u52d9\u8def\u7531 +Route=\u8def\u7531 +RoutesDescription=\u7ba1\u7406\u670d\u52d9\u8def\u7531\u898f\u5247 +Connections=\u901a\u8a0a\u7aef\u9023\u63a5 +ConnectionsDescription=\u9023\u63a5 +RegistryAddress=\u8a3b\u518a\u4e2d\u5fc3\u5730\u5740 +RegisterUsername=\u8a3b\u518a\u7528\u6236\u540d +RegisterDate=\u8a3b\u518a\u6642\u9593 +subscribeDate=\u8a02\u95b1\u6642\u9593 +Statistics=\u670d\u52d9\u5373\u6642\u7d71\u8a08 +CheckConnection=\u6aa2\u67e5\u9023\u63a5 +CheckDatabase=\u6aa2\u67e5\u8cc7\u6599\u5eab +queryUrl=\u8a02\u95b1\u53c3\u6578 +Status=\u72c0\u614b +notified=\u5df2\u901a\u77e5 +Unuse=\u672a\u4f7f\u7528 +NoProvider=\u6c92\u6709\u63d0\u4f9b\u8005 +NoConsumer=\u6c92\u6709\u6d88\u8cbb\u8005 +route.consumer.not.match=\u672cRoute\u4e0d\u5339\u914d\u6b64\u670d\u52d9\u6d88\u8cbb\u8005\uff08\u6703\u8fd4\u56de\u6240\u6709\u7684\u670d\u52d9\u63d0\u4f9b\u8005\uff09 +#labels +all=\u6240\u6709 +service=\u670d\u52d9\u540d +application=\u61c9\u7528\u540d +recursive=\u8ff4\u5708 +layer=\u670d\u52d9\u5206\u5c64 +address=\u6a5f\u5668IP +dubbo=\u4f7f\u7528dubbo\u7248\u672c +version=\u670d\u52d9\u7248\u672c +group=\u670d\u52d9\u5206\u7d44 +url=\u670d\u52d9\u4f4d\u5740 +parameters=\u670d\u52d9\u53c3\u6578 +provider=\u63d0\u4f9b\u8005\u5730\u5740 +consumer=\u6d88\u8cbb\u8005\u5730\u5740 +registry=\u8a3b\u518a\u4e2d\u5fc3\u5730\u5740 +username=\u7528\u6236\u540d +created=\u5275\u5efa\u6642\u9593 +modified=\u4fee\u6539\u6642\u9593 +register.date=\u8a3b\u518a\u6642\u9593 +type=\u985e\u578b +static=\u975c\u614b +dynamic=\u52d5\u614b +status=\u72c0\u614b +enabled=\u5df2\u555f\u7528 +disabled=\u5df2\u7981\u7528 +check=\u6aa2\u67e5 +operation=\u64cd\u4f5c +role=\u89d2\u8272 +provider=\u63d0\u4f9b\u8005 +consumer=\u6d88\u8cbb\u8005 +no.provider=\u6c92\u6709\u63d0\u4f9b\u8005 +no.consumer=\u6c92\u6709\u6d88\u8cbb\u8005 +ok=\u6b63\u5e38 +warn=\u8b66\u544a +error=\u51fa\u932f +success=\u6210\u529f +failure=\u5931\u6557 +operation.success=\u64cd\u4f5c\u6210\u529f\uff01 +operation.failure=\u64cd\u4f5c\u5931\u6557\uff01 +isRegistered=\u8a3b\u518a\u7de9\u5b58 +isCached=\u670d\u52d9\u7de9\u5b58 +isCached.true=\u670d\u52d9\u5728\u7de9\u5b58\u4e2d +isCached.false=\u670d\u52d9\u672a\u540c\u6b65\u5230\u7de9\u5b58 +isSubscribed=\u8a02\u95b1\u7de9\u5b58 +isSubscribed.true=\u6b64\u6d88\u8cbb\u8005\u5728\u7576\u524d\u8a3b\u518a\u4e2d\u5fc3\u8a02\u95b1 +isSubscribed.false=\u6b64\u6d88\u8cbb\u8005\u5728\u5176\u4ed6\u8a3b\u518a\u4e2d\u5fc3\u8a02\u95b1 +isSubscribed.unmatch=\u6b64\u6d88\u8cbb\u8005\u5728\u8cc7\u6599\u5eab\u548c\u7de9\u5b58\u4e2d\u7684\u8a3b\u518a\u4e2d\u5fc3\u5730\u5740\u4e0d\u4e00\u81f4 +#operations +search=\u641c\u7d22 +search=\u641c\u7d22 +query=\u67e5\u8a62 +show=\u67e5\u770b +add=\u65b0\u589e +addMock=\u65b0\u589eMock +multiadd=\u6279\u91cf\u65b0\u589e +edit=\u7de8\u8f2f +save=\u4fdd\u5b58 +delete=\u522a\u9664 +enable=\u555f\u7528 +disable=\u7981\u7528 +recover=\u6062\u5fa9 +reload=\u91cd\u8f09\u7de9\u5b58 +reconnect=\u91cd\u9023 +renotify=\u91cd\u65b0\u901a\u77e5 +tostatic=\u8f49\u70ba\u975c\u614b +todynamic=\u8f49\u70ba\u52d5\u614b +favorite=\u6536\u85cf +register=\u7533\u8acb\u8a3b\u518a +subscribe=\u7533\u8acb\u8abf\u7528 +logout=\u9000\u51fa +back=\u8fd4\u56de +cancel=\u53d6\u6d88 +confirm=\u78ba\u5b9a +batch.add=\u6279\u91cf\u65b0\u589e +batch.multiservices.add=\u591a\u670d\u52d9\u65b0\u589e +batch.delete=\u6279\u91cf\u522a\u9664 +batch.enable=\u6279\u91cf\u555f\u7528 +batch.disable=\u6279\u91cf\u7981\u7528 +batch.recover=\u6279\u91cf\u6062\u5fa9 +batch.reconnect=\u6279\u91cf\u91cd\u9023 +batch.renotify=\u6279\u91cf\u91cd\u65b0\u901a\u77e5 +batch.tostatic=\u6279\u91cf\u975c\u614b +batch.todynamic=\u6279\u91cf\u52d5\u614b +batch.favorite=\u6279\u91cf\u6536\u85cf +batch.reload=\u6279\u91cf\u91cd\u8f09 +confirm.batch.disable=\u78ba\u8a8d\u6279\u91cf\u7981\u7528 +confirm.batch.enable=\u78ba\u8a8d\u6279\u91cf\u555f\u7528 +#prompts +please.input.service=\u8acb\u8f38\u5165\u670d\u52d9\u540d +please.input.application=\u8acb\u8f38\u5165\u61c9\u7528\u540d +please.input.address=\u8acb\u8f38\u5165\u6a5f\u5668IP +please.input.layer=\u8acb\u8f38\u5165\u670d\u52d9\u5206\u5c64 +please.input=\u8acb\u8f38\u5165\u8981\u64cd\u4f5c\u7684\u5167\u5bb9 +please.select=\u8acb\u9078\u64c7\u8981\u64cd\u4f5c\u7684\u9805 +empty.list=\u6c92\u6709\u8cc7\u6599\u53ef\u4ee5\u64cd\u4f5c +not.found=\u6c92\u6709\u641c\u5230\u5339\u914d\u7684\u7d50\u679c +show.all=\u986f\u793a\u5168\u90e8 +confirm.logout=\u78ba\u5b9a\u9000\u51fa\u767b\u9304? +confirm.delete=\u78ba\u5b9a\u522a\u9664? +confirm.enable=\u78ba\u5b9a\u555f\u7528? +confirm.disable=\u78ba\u5b9a\u7981\u7528? +confirm.recover=\u78ba\u5b9a\u6062\u5fa9 +confirm.reconnect=\u78ba\u5b9a\u91cd\u9023? +confirm.renotify=\u78ba\u5b9a\u901a\u77e5? +confirm.tostatic=\u78ba\u5b9a\u8f49\u70ba\u975c\u614b? +confirm.todynamic=\u78ba\u5b9a\u8f49\u70ba\u52d5\u614b? +confirm.batch.delete=\u78ba\u5b9a\u522a\u9664\u6240\u9078\u9805? +confirm.batch.enable=\u78ba\u5b9a\u555f\u7528\u6240\u9078\u9805? +confirm.batch.disable=\u78ba\u5b9a\u7981\u7528\u6240\u9078\u9805? +confirm.batch.recover=\u78ba\u5b9a\u6062\u5fa9\u6240\u9078\u9805? +confirm.batch.reload=\u78ba\u5b9a\u91cd\u8f09\u7576\u524d\u670d\u52d9? +confirm.batch.reconnect=\u78ba\u5b9a\u91cd\u9023\u6240\u9078\u9805? +confirm.batch.renotify=\u78ba\u5b9a\u91cd\u65b0\u901a\u77e5\u6240\u9078\u9805? +confirm.batch.tostatic=\u78ba\u5b9a\u8f49\u70ba\u975c\u614b\u6240\u9078\u9805? +confirm.batch.todynamic=\u78ba\u5b9a\u8f49\u70ba\u52d5\u614b\u6240\u9078\u9805? +current.user=\u7576\u524d\u7528\u6236 +CheckProviderAddressMismatch=\u670d\u52d9URL\u4e0a\u7684IP\u8207\u9023\u63a5\u8a3b\u518a\u4e2d\u5fc3\u7684IP\u4e0d\u76f8\u540c +CheckProviderApplicationDifferent=\u591a\u500b\u4e0d\u540c\u61c9\u7528\u8a3b\u518a\u4e86\u76f8\u540c\u670d\u52d9\uff0c\u8acb\u6aa2\u67e5{0}\u4e2d\u662f\u5426\u6709\u8aa4\u66b4\u9732\u3002 +CheckConnectionDisconnected=\u8a72\u9023\u63a5\u5df2\u65b7\u958b\uff0c\u8cc7\u6599\u5eab\u9ad2\u8cc7\u6599\uff0c\u8acb\u9ede\u64ca\u201c\u91cd\u9023\u201d +CheckConnectionExpired=\u8a72\u9023\u63a5\u6240\u5728\u8a3b\u518a\u4e2d\u5fc3\u5df2\u4e0d\u5b58\u5728\uff08\u8cc7\u6599\u6703\u81ea\u52d5\u5b9a\u671f\u6e05\u7406\uff09 +CheckDatabaseMiss=\u8cc7\u6599\u5eab\u8cc7\u6599\u610f\u5916\u4e1f\u5931\u6b64\u8cc7\u6599\uff0c\u8acb\u9ede\u64ca\u201c\u6062\u5fa9\u201d +CheckDatabaseMismatch=\u8cc7\u6599\u5eab\u8207\u8a3b\u518a\u7de9\u5b58\u8cc7\u6599\u8a3b\u518a\u4f4d\u5740\u4e0d\u4e00\u81f4 +CheckDatabaseDirty2Registered=\u8cc7\u6599\u5eab\u6bd4\u8a3b\u518a\u7de9\u5b58\u591a\u6b64\u9ad2\u8cc7\u6599\uff0c\u8acb\u9ede\u64ca\u201c\u91cd\u9023\u201d +CheckDatabaseDirty2Subscribed=\u8cc7\u6599\u5eab\u6bd4\u8a02\u95b1\u7de9\u5b58\u591a\u6b64\u9ad2\u8cc7\u6599\uff0c\u8acb\u9ede\u64ca\u201c\u91cd\u9023\u201d +CheckCacheRegistered=\u8a3b\u518a\u7de9\u5b58\u4e0d\u5b58\u5728\uff0c\u8acb\u9ede\u64ca\u201c\u91cd\u9023\u201d +CheckCacheConsumer=\u7121\u6b64\u670d\u52d9\u7684\u670d\u52d9\u7de9\u5b58\uff0c\u4f46\u6709\u6d88\u8cbb\u8005\uff01\u8acb\u9ede\u64ca\u201c\u91cd\u8f09\u201d +CheckCacheProvider=\u670d\u52d9\u7de9\u5b58\u7121\u6b64\u63d0\u4f9b\u8005\uff0c\u8acb\u9ede\u64ca\u201c\u91cd\u8f09\u201d +CheckCacheSubscribed=\u8a02\u95b1\u7de9\u5b58\u4e0d\u5b58\u5728\uff0c\u8acb\u9ede\u64ca\u201c\u91cd\u9023\u201d +CheckCacheService=\u7121\u6b64\u670d\u52d9\u7684\u670d\u52d9\u7de9\u5b58\uff0c\u8acb\u9ede\u64ca\u63d0\u4f9b\u8005\u7684\u201c\u91cd\u8f09\u201d +select.all=\u5168\u9078 +ip.address=IP\u5730\u5740 +registry.newservice=\u8a3b\u518a\u65b0\u670d\u52d9 +add.new.provider=\u6dfb\u52a0\u63d0\u4f9b\u8005 +add.new.route=\u6dfb\u52a0\u8def\u7531 +message.search.noresult=\u6c92\u6709\u7b26\u5408\u7684\u67e5\u8a62\uff0c\u8acb\u5f9e\u63d0\u793a\u5217\u8868\u4e2d\u9078\u64c7\u67e5\u8a62\u6e96\u5247\uff01 +provide.service=\u63d0\u4f9b\u7684\u670d\u52d9 +service.method=\u670d\u52d9\u65b9\u6cd5 +startegy=\u7b56\u7565 +route.name=\u8def\u7531\u540d\u7a31 +rule.match=\u5339\u914d\u898f\u5247 +rule.filtrate=\u904e\u6ffe\u898f\u5247 +priority=\u512a\u5148\u9806\u5e8f +routed=\u5df2\u8def\u7531 +page.total=\u5171 +page.records=\u689d\u8a18\u9304 +page.ordinal=\u7b2c +page.page=\u9801 +page.next=\u4e0b\u4e00\u9801 +page.prev=\u4e0a\u4e00\u9801 +page.first=\u9996\u9801 +page.last=\u5c3e\u9801 +page.line=\u689d +methodName=\u65b9\u6cd5\u540d +proview=\u9810\u89bd +cluster.name=\u96c6\u7fa4\u540d +cluster.address=\u96c6\u7fa4\u6a5f\u5668\u5730\u5740 +sameserviceadd=\u540c\u670d\u52d9\u6dfb\u52a0 +whitelist=\u767d\u540d\u55ae +blacklist=\u9ed1\u540d\u55ae +toWhiteAndBlackList=\u8f49\u5165\u767d\u540d\u55ae/\u8f49\u5165\u9ed1\u540d\u55ae +obtainProviderAddress=\u7372\u53d6\u63d0\u4f9b\u8005\u5730\u5740 +towhitelist=\u52a0\u5165\u767d\u540d\u55ae +toblacklist=\u52a0\u5165\u9ed1\u540d\u55ae +enable=\u555f\u7528 +disable=\u7981\u7528 +copy=\u8907\u88fd +batch.enable=\u6279\u91cf\u555f\u7528 +batch.disable=\u6279\u91cf\u7981\u7528 +batch.towhitelist=\u52a0\u5165\u767d\u540d\u55ae +batch.toblacklist=\u52a0\u5165\u9ed1\u540d\u55ae +confirm.favorites=\u78ba\u8a8d\u6536\u85cf\u55ce +confirm.batch.towhitelist=\u78ba\u8a8d\u52a0\u5165\u767d\u540d\u55ae?
\u5c07\u7981\u6b62\u4e0d\u5728\u767d\u540d\u55ae\u5167\u7684\u6240\u6709\u6d88\u8cbb\u8005\u8a2a\u554f\uff0c\u9ed1\u540d\u55ae\u5931\u6548\u3002 +confirm.batch.toblacklist=\u78ba\u8a8d\u52a0\u5165\u9ed1\u540d\u55ae?
\u5982\u679c\u6c92\u6709\u767d\u540d\u55ae\uff0c\u5c07\u7981\u6b62\u5728\u9ed1\u540d\u55ae\u5167\u7684\u6240\u6709\u5176\u5b83\u6d88\u8cbb\u8005\u8a2a\u554f\u3002 +confirm.enable=\u78ba\u8a8d\u555f\u7528 +confirm.disable=\u78ba\u8a8d\u7981\u7528 +confirm.edit=\u78ba\u8a8d\u7de8\u8f2f +confirm.disableFeature=\u78ba\u8a8d\u7981\u7528\u529f\u80fd +confirm.enableFeature=\u78ba\u8a8d\u555f\u7528\u529f\u80fd +confirmDeleteOwner=\u78ba\u8a8d\u522a\u9664\u8ca0\u8cac\u4eba +welcome=\u60a8\u597d +approve=\u5f85\u5be9\u6279 +chinese.simple=\u7c21\u9ad4\u4e2d\u6587 +chinese.tradition=\u7e41\u9ad4\u4e2d\u6587 +register.service=\u8a3b\u518a\u65b0\u670d\u52d9 +erratum.guide=\u6392\u932f\u56ae\u5c0e +preview.guide=\u9810\u89bd\u56ae\u5c0e +sysinfo.status=\u8a3b\u518a\u4e2d\u5fc3\u72c0\u614b +sysinfo.registries=\u8a3b\u518a\u4e2d\u5fc3\u96c6\u7fa4 +sysinfo.connections=\u901a\u8a0a\u7aef\u9023\u63a5 +sysinfo.cached=\u8a18\u61b6\u9ad4\u7de9\u5b58 +sysinfo.failed=\u5931\u6557\u8a18\u9304 +sysinfo.operations=\u64cd\u4f5c\u8a18\u9304 +sysinfo.logs=\u7cfb\u7d71\u65e5\u8a8c +sysinfo.versions=Dubbo\u7248\u672c +sysinfo.dumps=\u7cfb\u7d71\u5feb\u7167 +sysinfo.envs=\u7cfb\u7d71\u74b0\u5883 +sysinfo.helps=\u5e6b\u52a9\u6587\u6a94 +system.management=\u7cfb\u7d71\u7ba1\u7406 +sysmanage.users=\u7528\u6236\u7ba1\u7406 +sysmanage.configs=\u7cfb\u7d71\u53c3\u6578\u8a2d\u7f6e +sysmanage.features=\u7cfb\u7d71\u529f\u80fd\u958b\u95dc +system.function.control=\u7cfb\u7d71\u529f\u80fd\u958b\u95dc +personal.set=\u500b\u4eba\u8a2d\u7f6e +modify.personalinfo=\u4fee\u6539\u500b\u4eba\u8cc7\u8a0a +modify.personal.password=\u4fee\u6539\u500b\u4eba\u5bc6\u78bc +operation.operateaddress=\u64cd\u4f5c\u8005\u4f4d\u5740 +operation.operatetype=\u64cd\u4f5c\u985e\u578b +operation.datatype=\u8cc7\u6599\u985e\u578b +operation.data=\u64cd\u4f5c\u5167\u5bb9 +operation.createtime=\u64cd\u4f5c\u6642\u9593 +operation.clean=\u6e05\u7406 +passwd.oldwrong=\u820a\u5bc6\u78bc\u932f\u8aa4 +failed=\u5931\u6557\u8a18\u9304 +failed_type=\u985e\u578b +failed_data=\u6578\u64da +failed_sync=\u540c\u6b65\u4f4d\u5740\u5931\u6557\u8a18\u9304 +failed_subscribe=\u8a02\u95b1\u5931\u6557\u8a18\u9304 +failed_notify=\u901a\u77e5\u5931\u6557\u8a18\u9304 +failed_collect=\u7d71\u8a08\u5931\u6557\u8a18\u9304 +failed_register=\u8a3b\u518a\u5931\u6557\u8a18\u9304 +failed_redirect=\u91cd\u5b9a\u5411\u5931\u6557\u8a18\u9304 +failed_disconnect=\u65b7\u958b\u6e05\u7406\u5931\u6557\u8a18\u9304 +clientAddress=\u7528\u6236\u7aef\u5730\u5740 +overrideAddress=\u8986\u84cb\u4f4d\u5740 +serviceInfo=\u670d\u52d9\u8cc7\u8a0a +consumerAddress=\u6d88\u8cbb\u8005\u5730\u5740 +providerAddress=\u63d0\u4f9b\u8005\u5730\u5740 +registryAddress=\u8a3b\u518a\u4e2d\u5fc3\u5730\u5740 +serviceName=\u670d\u52d9\u540d +serviceUrl=\u670d\u52d9\u4f4d\u5740 +overrideConsumerAddress=\u53ea\u63a8\u9001\u7d66\u6307\u5b9a\u6d88\u8cbb\u8005\u5730\u5740 +overrideProviderAddress=\u53ea\u8986\u84cb\u6307\u5b9a\u63d0\u4f9b\u8005\u5730\u5740 +tipConsumerAddress=\u53ef\u4e0d\u586b\uff0c\u8868\u793a\u5c0d\u6d88\u8cbb\u8005\u61c9\u7528\u7684\u6240\u6709\u6a5f\u5668\u751f\u6548 +tipProviderAddress=\u53ef\u4e0d\u586b\uff0c\u8868\u793a\u5c0d\u670d\u52d9\u7684\u6240\u6709\u63d0\u4f9b\u8005\u6a5f\u5668\u751f\u6548 +logs=\u7cfb\u7d71\u65e5\u8a8c +logs.file=\u65e5\u8a8c\u6a94 +logs.size=\u6587\u4ef6\u5927\u5c0f +logs.modify=\u4fee\u6539\u6642\u9593 +logs.level=\u65e5\u8a8c\u7d1a\u5225 +change.log.level=\u4fee\u6539\u65e5\u8a8c\u7d1a\u5225 +logs.confirmChangeLogLevel=\u78ba\u8a8d\u4fee\u6539\u65e5\u8a8c\u7d1a\u5225 +cached=\u8a18\u61b6\u9ad4\u7de9\u5b58 +cached.type=\u985e\u578b +cached.data=\u6578\u64da +cached.reload=\u91cd\u65b0\u8f09\u5165 +batch.cached.reload=\u6279\u91cf\u91cd\u65b0\u8f09\u5165 +cached.recover=\u6062\u5fa9 +batch.cached.recover=\u6279\u91cf\u6062\u5fa9 +servicePrivilege=\u670d\u52d9\u8a31\u53ef\u6b0a +creator=\u5275\u5efa\u8005 +name=\u540d\u7a31 +department=\u90e8\u9580 +email=\u90f5\u7bb1 +phone=\u96fb\u8a71 +alitalk=\u963f\u88e1\u65fa\u65fa +password=\u5bc6\u78bc +roleR=\u8d85\u7d1a\u7ba1\u7406\u54e1 +roleA=\u7ba1\u7406\u54e1 +roleG=\u904a\u5ba2 +roleDescR=\u7ba1\u7406\u6240\u6709 +roleDescA=\u7ba1\u7406\u81ea\u5df1\u5275\u5efa\u7684\u4f7f\u7528\u8005\u548c\u670d\u52d9 +roleDescG=\u53ea\u67e5\u770b +oldPassword=\u820a\u5bc6\u78bc +newPassword=\u65b0\u5bc6\u78bc +reset=\u91cd\u7f6e +restPassword=\u91cd\u7f6e\u5bc6\u78bc +confirmNewPassword=\u78ba\u8a8d\u65b0\u5bc6\u78bc +owns=\u8ca0\u8cac\u7684\u670d\u52d9 +confirmPassword=\u78ba\u8a8d\u5bc6\u78bc +generatePassword=\u751f\u6210\u5bc6\u78bc +displayName=\u59d3\u540d +locale=\u4f7f\u7528\u8a9e\u8a00 +privilegeTip=\u591a\u500b\u503c\u7528\u9017\u865f(,)\u5206\u9694\uff0c\u842c\u7528\u5b57\u5143\u7528\u661f\u865f(*)\u8868\u793a\uff0c\u53ea\u80fd\u5728\u6bcf\u500b\u503c\u7684\u672a\u5c3e\u4f7f\u7528\u842c\u7528\u5b57\u5143\uff0c\u88ab\u6388\u8207\u7684\u8a31\u53ef\u6b0a\u4e0d\u80fd\u8d85\u51fa\u7576\u524d\u7ba1\u7406\u4eba\u54e1\u7684\u8a31\u53ef\u6b0a +displayNameTip=\u7528\u6236\u59d3\u540d\uff0c\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-50\u500b\u5b57\u5143\u7d44\u6210 +emailTip=\u7528\u65bc\u63a5\u6536\u7cfb\u7d71\u90f5\u4ef6\uff0c\u53ef\u4ee5\u8f38\u5165\u591a\u500b\u90f5\u5bc4\u5730\u5740\uff0c\u4f7f\u7528\u82f1\u6587\u5206\u865f\u5206\u9694(;)\uff0c \u5f62\u5982 foo1@163.comj;foo2@gmail.com +userLocaleTip=\u767c\u9001\u7cfb\u7d71\u90f5\u4ef6\u6642\uff0c\u5c07\u6839\u64da\u4f7f\u7528\u8005\u4f7f\u7528\u7684\u8a9e\u8a00\u767c\u9001\u4e0d\u540c\u8a9e\u8a00\u7684\u90f5\u4ef6\u5167\u5bb9 +DisplayNameTip +EmailTip +UserLocaleTip +missRequestParameters=\u4e1f\u5931\u8acb\u6c42\u53c3\u6578 +haveNoRootPrivilege=\u6c92\u6709root\u8a31\u53ef\u6b0a +confirmReloadCache=\u78ba\u8a8d\u91cd\u65b0\u8f09\u5165\u7de9\u5b58 +confirmDeleteRegistry=\u78ba\u8a8d\u522a\u9664\u8a3b\u518a\u4e2d\u5fc3 +confirmAutoRedirectRegistry=\u78ba\u8a8d\u91cd\u5b9a\u5411\u8a3b\u518a\u4e2d\u5fc3 +confirmDeleteExpiredRegistry=\u78ba\u8a8d\u522a\u9664\u904e\u671f\u8a3b\u518a\u4e2d\u5fc3 +confirmSyncRegistry=\u78ba\u8a8d\u540c\u6b65\u8a3b\u518a\u4e2d\u5fc3\u5730\u5740\u6e05\u55ae\u5230\u7528\u6236\u7aef +confirm.toblacklist=\u78ba\u8a8d\u52a0\u5165\u9ed1\u540d\u55ae?
\u5982\u679c\u6c92\u6709\u767d\u540d\u55ae\uff0c\u5c07\u7981\u6b62\u5728\u9ed1\u540d\u55ae\u5167\u7684\u6240\u6709\u6d88\u8cbb\u8005\u8a2a\u554f\u3002 +confirm.towhitelist=\u78ba\u8a8d\u52a0\u5165\u767d\u540d\u55ae?
\u5c07\u7981\u6b62\u4e0d\u5728\u767d\u540d\u55ae\u5167\u7684\u6240\u6709\u5176\u5b83\u6d88\u8cbb\u8005\u8a2a\u554f\uff0c\u9ed1\u540d\u55ae\u5931\u6548\u3002 +confirm.clean.operation=\u78ba\u8a8d\u6e05\u9664\u64cd\u4f5c\u8a18\u9304 +autoRedirect=\u81ea\u52d5\u91cd\u5b9a\u5411 +deleteExpired=\u522a\u9664\u6240\u6709\u5df2\u904e\u671f +sync=\u540c\u6b65 +legacies=1.0\u907a\u7559\u7528\u6236\u7aef +logined=\u5df2\u767b\u9304\u7528\u6236\u7aef +dumps=\u7cfb\u7d71\u5feb\u7167 +update=\u66f4\u65b0 +generic=\u6cdb\u5316 +Registry=\u8a3b\u518a\u4e2d\u5fc3\u7248\u672c +Java=JDK\u7248\u672c +Locale=\u8a9e\u8a00 +CPU=\u0043\u0050\u0055 +OS=\u4f5c\u696d\u7cfb\u7d71 +Uptime=\u57f7\u884c\u6642\u9593 +Host=\u529f\u80fd\u8b8a\u6578\u540d\u7a31 +confirmEnableUser=\u78ba\u8a8d\u555f\u52d5\u7528\u6236 +confirmDisableUser=\u78ba\u8a8d\u7981\u7528\u7528\u6236 +documentTitle=\u6587\u6a94\u6a19\u984c +documentLink/documentPage=\u9023\u7d50\u4f4d\u5740/\u9801\u9762\u5167\u5bb9 +documentInternal=\u9801\u9762 +documentExternal=\u9023\u7d50 +documentApi=API +documentType=\u6587\u6a94\u985e\u578b +documentContent=\u6587\u6a94\u5167\u5bb9 +Yes=\u662f +No=\u5426 +returnValue=\u8fd4\u56de\u503c +throwException=\u62cb\u51fa\u7570\u5e38 +#BatchAddressTip=\u591a\u500b\u4f4d\u5740\u7528\u5206\u884c\u7b26\u865f\u5206\u9694\uff0c\u4f4d\u5740\u5fc5\u9700\u662f0.0.0.0\u5230255.255.255.255\u7684IP\u5730\u5740 +#AccessControlTip=\u767d\u540d\u55ae\u512a\u5148\uff0c\u53ea\u8981\u6709\u767d\u540d\u55ae\uff0c\u5247\u767d\u540d\u55ae\u751f\u6548\uff0c\u5426\u5247\u9ed1\u540d\u55ae\u751f\u6548 +#RouteNameTip=\u53ef\u4f7f\u7528\u4e2d\u6587\uff0c\u75311-200\u500b\u5b57\u5143\u7d44\u6210 +#RoutePriorityTip=\u6578\u5b57\u8d8a\u5927\u8d8a\u512a\u5148 +#RouteMethodTip=\u53ea\u6709Dubbo2.0.0\u4ee5\u4e0a\u7248\u672c\u7684\u670d\u52d9\u6d88\u8cbb\u7aef\u652f\u63f4\u6309\u65b9\u6cd5\u8def\u7531\uff0c\u591a\u500b\u65b9\u6cd5\u540d\u7528\u9017\u865f\u5206\u9694 +#Choose=\u8acb\u9078\u64c7 +#RouteMatchTip=\u7576\u6d88\u8cbb\u8005\u6eff\u8db3\u5339\u914d\u689d\u4ef6\u6642\u4f7f\u7528\u7576\u524d\u898f\u5247\u9032\u884c\u904e\u6ffe +#RouteHostTip=\u591a\u500b\u503c\u7528\u9017\u865f\u5206\u9694\uff0c\u4ee5\u661f\u865f\u7d50\u5c3e\u8868\u793a\u901a\u914d\u4f4d\u5740\u6bb5 +#RouteClusterTip=\u53ef\u901a\u904e\u529f\u80fd\u8868"\u670d\u52d9\u63a7\u5236"->"\u4f3a\u670d\u5668\u96c6\u7fa4"\u7ba1\u7406 +#RouteFilterTip=\u6eff\u8db3\u904e\u6ffe\u898f\u5247\u7684\u63d0\u4f9b\u8005\u4f4d\u5740\u5c07\u88ab\u63a8\u9001\u7d66\u6d88\u8cbb\u8005 +testMethodTip=\u5982\u679c\u6709\u65b9\u6cd5\u91cd\u8f09\u6216\u4f7f\u7528Dubbo1.0.x\u7248\u672c\u7684\u670d\u52d9\u63d0\u4f9b\u8005\uff0c\u9700\u5beb\u5168\u65b9\u6cd5\u7c3d\u540d\uff0c\u5982\uff1afindBy(int,java.lang.String)\uff0c\u5426\u5247\u53ea\u9700\u65b9\u6cd5\u540d\uff0c\u5982\uff1afindBy +testJsonTip=JSON\u683c\u5f0f\uff1a\u5b57\u4e32\u7528\u96d9\u5f15\u865f\u8868\u793a\uff0c\u5982\uff1a"\u5b57\u4e32"\uff0c\u6578\u4f4d\u548cBoolean\u503c\u4e0d\u7528\u5f15\u865f\uff0c\u5982\uff1a123 \u548c true \u6216 false\uff0cPOJO\u7269\u4ef6\u6216Map\u7528\u5927\u62ec\u5f27\u8868\u793a\uff0c\u5982\uff1a{"\u5c6c\u6027\u540d1": "\u5c6c\u6027\u503c1", "\u5c6c\u6027\u540d2": "\u5c6c\u6027\u503c2"}\uff0c\u9663\u5217\u6216List\u6216Set\u7528\u65b9\u62ec\u865f\u8868\u793a\uff0c\u5982\uff1a["\u503c1", "\u503c2"] +testParametersTip=\u7576\u70ba\u7121\u53c3\u6578\u65b9\u6cd5\u6642\u53c3\u6578\u503c\u53ef\u4ee5\u4e0d\u586b\uff0c\u53c3\u6578\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testResultTip=\u7576\u70bavoid\u65b9\u6cd5\u6642\u7d50\u679c\u53ef\u4ee5\u4e0d\u586b\uff0c\u62cb\u51fa\u7570\u5e38\u4f7f\u7528\u7570\u5e38\u985e\u5168\u540d\u8868\u793a\uff0c\u8fd4\u56de\u503c\u4f7f\u7528JSON\u683c\u5f0f\u8868\u793a +testAutoRunTip=\u5982\u679c\u8a2d\u7f6e\u70ba\u81ea\u52d5\u904b\u884c\uff0c\u82e5\u8a72\u670d\u52d9\u5df2\u8a3b\u518a\u6216\u65b0\u8a3b\u518a\uff0c\u5247\u81ea\u52d5\u904b\u884c\u6b64\u6e2c\u8a66\u7528\u4f8b\uff0c\u904b\u884c\u5931\u6557\uff0c\u5c07\u767c\u9001\u90f5\u4ef6 +confirmRunTest=\u78ba\u8a8d\u904b\u884c\u6e2c\u8a66 +confirm.runAll=\u78ba\u8a8d\u5c0d\u6240\u6709\u63d0\u4f9b\u8005\u904b\u884c\u6e2c\u8a66 +# +#anonymous=\u533f\u540d +#Unuse=\u672a\u4f7f\u7528 +#RouteName=\u8def\u7531\u540d +#Priority=\u512a\u5148\u9806\u5e8f +#MatchRule=\u5339\u914d\u689d\u4ef6 +#ConsumerHost=\u6d88\u8cbb\u8005IP\u5730\u5740 +#ConsumerCluster=\u6d88\u8cbb\u8005\u96c6\u7fa4 +#FilterRule=\u904e\u6ffe\u898f\u5247 +#ProviderHost=\u63d0\u4f9b\u8005IP\u5730\u5740 +#ProviderCluster=\u63d0\u4f9b\u8005\u96c6\u7fa4 +#ProviderProtocol=\u63d0\u4f9b\u8005\u5354\u5b9a +#ProviderPort=\u63d0\u4f9b\u8005\u57e0 +#Match=\u5339\u914d +#Mismatch=\u4e0d\u5339\u914d +#ConsumerAddress=\u6d88\u8cbb\u8005\u5730\u5740 +loadBalanceStrategy=\u8ca0\u8f09\u5747\u8861\u7b56\u7565 +random=\u96a8\u6a5f +roundrobin=\u8f2a\u8a62 +leastactive=\u6700\u5c11\u4f75\u767c +testName=\u6e2c\u8a66\u7528\u4f8b\u540d\u7a31 +operator=\u64cd\u4f5c +dataFormat=\u8cc7\u6599\u683c\u5f0f +resultType=\u7d50\u679c\u985e\u578b +resultController=\u8fd4\u56de\u503c/\u7570\u5e38\u985e\u578b +autoRun=\u81ea\u52d5\u904b\u884c +manualRun=\u624b\u52d5\u904b\u884c +run=\u904b\u884c +runAll=\u904b\u884c\u6240\u6709\u63d0\u4f9b\u8005 +expected=\u671f\u671b\u7d50\u679c +actual=\u5be6\u969b\u7d50\u679c +reRun=\u91cd\u65b0\u904b\u884c +#Username=\u7528\u6236\u540d +#DisplayName=\u986f\u793a\u540d +#Department=\u90e8\u9580 +#Email=\u90f5\u7bb1 +#Phone=\u624b\u6a5f +#Alitalk=\u65fa\u65fa +startDate=\u555f\u52d5\u6642\u9593 +console=\u63a7\u5236\u53f0 +total=\u7e3d\u6578 +delta=\u504f\u5dee +expired=\u904e\u671f +alived=\u5b58\u6d3b +redirect=\u91cd\u5b9a\u5411 +current=\u7576\u524d +#overrides +override.config=\u52d5\u614b\u914d\u7f6e +override.mock=\u670d\u52d9\u964d\u7d1a +parameter=\u53c3\u6578 +parameter.key=\u53c3\u6578\u540d +parameter.value=\u53c3\u6578\u503c +mock.all.method=\u6240\u6709\u65b9\u6cd5\u7684Mock\u503c +mock.method=\u65b9\u6cd5 +mock.value=\u7684Mock\u503c +default.owner=\u8ca0\u8cac\u4eba +logger=\u65e5\u8a8c +default.server=\u9ed8\u8a8d\u670d\u52d9\u7aef +default.actives=\u4e26\u767c\u8abf\u7528\u6578 +default.client=\u9ed8\u8a8d\u5ba2\u6236\u7aef +default.connections=\u6700\u5927\u9023\u63a5\u6578 diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/log4j.properties b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/log4j.properties new file mode 100644 index 0000000..5be84a2 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/log4j.properties @@ -0,0 +1,37 @@ +# +# 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. +# +log4j.rootCategory=INFO, stdout, file +log4j.logger.org.apache=ERROR + + +# 控制台输出 +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.target=System.out +log4j.appender.stdout.Threshold=INFO +log4j.appender.stdout.encoding=GBK +log4j.appender.stdout.layout.ConversionPattern=%5p %c{2} - %m%n + +# 文件输出 +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.file=dubbo-governance.log +log4j.appender.file.Threshold=INFO +log4j.appender.file.append=true +log4j.appender.file.maxFileSize=10MB +log4j.appender.file.maxBackupIndex=100 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d [%t] %-5p %C{6} (%F:%L) - %m%n \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/common.css b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/common.css new file mode 100644 index 0000000..e5fb2bf --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/common.css @@ -0,0 +1,689 @@ +/* + * 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. + */ + +@charset "utf-8"; +/* CSS Document */ +html, body, div, p, ul, li, dl, dt, dd, h1, h2, h3, h4, h5, h6, form, input, select, button, textarea, iframe, table, th, td { + margin: 0; + padding: 0; +} + +select, textarea, input { + border: #b3b3b3 1px solid; +} + +input.radio, input.checkbox { + border: none; +} + +img { + border: none; +} + +ul, li { + list-style-type: none; +} + +body { + margin: 0; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #586573; + min-width: 1150px; + word-wrap: break-word; + word-break: break-all; +} + +body.pop { + background-color: transparent; +} + +body.pop_del { + min-width: 750px; +} + +a { + color: #2f7ed3; + cursor: pointer; +} + +a.fontlink { + color: #2f7ed3; + text-decoration: underline; +} + +.none { + display: none; +} + +.left { + float: left; +} + +.right { + float: right; +} + +/*head*/ +.head_right { + float: right; + padding-top: 45px; + margin: 0 10px 0 0; + color: #FFF; +} + +.head_right span { + color: #fff; + line-height: 30px; + float: right; + margin-right: 15px; +} + +.head_right span a { + color: #fff; +} + +.exit { + float: right; + padding-top: 3px; +} + +/*menu*/ +.nav ul li { + float: left; + height: 31px; + line-height: 24px; +} + +.nav ul li a { + padding-top: 5px; + height: 26px; + color: #FFF; + display: block; + width: 157px; + text-decoration: none; + text-align: center; +} + +.nav ul li.current a { + color: #000; + display: block; + width: 157px; + text-decoration: none; + text-align: center; +} + +.nav ul li.current ul li a { + color: #fff; + display: block; + width: 157px; + text-decoration: none; + text-align: center; +} + +.nav li:hover ul { + display: block; +} + +.nav ul li ul { + position: absolute; + display: none; + list-style-type: none; + text-align: left; +} + +.nav ul li ul li { + display: block; + text-decoration: none; + height: 28; + clear: both; +} + +.nav ul li ul li a { + color: #fff; + display: block; + text-decoration: none; +} + +.nav ul li ul li a:hover { + background-image: none; +} + +.nav ul li.sub_nav a { + color: #fff; + display: block; + width: 157px; + text-decoration: none; + text-align: center; + line-height: 26px; +} + +.nav ul li.sub_nav ul li a { + color: #fff; + display: block; + width: 157px; + text-decoration: none; + text-align: center; +} + +.nav ul li.current_nosub a { + color: #000; + display: block; + width: 157px; + text-decoration: none; + text-align: center; + line-height: 26px; +} + +.about { + clear: right; + float: right; + line-height: 28px; + margin-right: 20px; +} + +.about a { + color: #fff; +} + +/*全局搜索*/ +.search_o { + clear: left; + width: 500px; + margin-bottom: 10px; +} + +.search_btn { + margin-top: 5px; + *margin: 0; +} + +.btn_search { + background: url(../images/btn_service.png); + width: 132px; + height: 20px; + text-align: center; + line-height: 20px; + margin-top: 10px; +} + +.btn_search a, .btn_info a { + text-decoration: none; + color: #666; + display: block; +} + +.search { + width: 500px; + margin: 150px auto; +} + +.search_categories { + height: 18px; +} + +.search_categories ul li { + float: left; + width: 60px; + line-height: 10px; + *line-height: 15px; + text-align: center; +} + +.search_categories ul li a { + color: #586573; + text-decoration: none; +} + +.search_categories ul li span.search_line { + margin-left: 10px; + color: #CCC; +} + +.search_categories ul li span.search_line_end { + margin-left: 10px; + color: #fff; +} + +/*main*/ +.main { + background: url(../images/main_bg.png) repeat-x; + min-height: 229px; + padding: 15px 20px 20px 20px; + *padding-bottom: 0; + /* min-height:593px; */ + height: 100%; +} + +.title { + font-family: "微软雅黑"; + font-weight: 200; + color: #696969; + font-size: 16px; + float: left; + margin-bottom: 10px; +} + +.title_num { + font-size: 14px; + float: left; + padding: 13px 0 0 10px; + padding-top: 9px \0; + *padding-top: 9px; +} + +.crumbs { + float: left; + padding-top: 15px; + padding-left: 20px; + color: #999; +} + +.num_o { + clear: left; + padding-top: 10px; + *padding-top: 0; +} + +.num_t { + clear: left; + padding-top: 10px; +} + +/*table_search*/ +.search_list { + overflow: hidden; + margin-bottom: 10px; +} + +.search_list table th { + font-weight: normal; + padding-right: 10px; +} + +.search_list table td { + font-weight: normal; + padding-right: 15px; +} + +/*table_ico_btn*/ +.ico_btn { + clear: both; +} + +.ico_btn a, table.list td a { + text-decoration: none; +} + +.ico_btn span.ico_font, table.list td span.ico_font { + margin-left: 5px; +} + +.ico_btn span.ico_line, table.list td span.ico_line { + margin: 0 10px 0 10px; + color: #CCC; +} + +/*table*/ +table.list { + color: #586573; + clear: left; + width: 100%; + border: #dedede 1px solid; + margin-bottom: 10px; +} + +table.list th { + height: 29px; + color: #fff; + line-height: 29px; + text-align: left; + padding-left: 8px; + font-weight: bold; +} + +table.list td { + text-align: left; + padding-left: 10px; + line-height: 34px; + border-top: #d4d4d4 1px dashed; +} + +/*footer*/ +.footer span { + color: #fff; + line-height: 26px; + margin-left: 20px; +} + +/*button*/ +.btn a, .login_btn a { + text-decoration: none; + color: #586573; + display: block; +} + +span.star { + color: #F00; +} + +/*pop*/ +table.pop_top td.pop_lefttop_small h1 { + font-size: 24px; + color: #000; + padding-left: 90px; + padding-top: 20px; +} + +table.pop_top td.pop_midtop_small { + background: url(../images/pop_midtop_small.png); + height: 105px; +} + +table.pop_top td.pop_righttop_small { + background: url(../images/pop_righttop_small.png); + width: 46px; + height: 105px; +} + +table.pop_mid td.pop_left { + background: url(../images/pop_left.png); + width: 19px; +} + +table.pop_mid td.pop_content { + background: #f7f7f7; +} + +table.pop_mid td.pop_right { + background: url(../images/pop_right.png); + width: 19px; +} + +table.pop_mid td.pop_leftbottom_small { + background: url(../images/pop_leftbottom.png); + width: 19px; + height: 22px; +} + +table.pop_mid td.pop_midbottom_small { + background: url(../images/pop_midbottom.png); + height: 22px; +} + +table.pop_mid td.pop_rightbottom_small { + background: url(../images/pop_rightbottom.png); + width: 19px; + height: 22px; +} + +table.pop_box { + border-top: #cdcdcd 1px dashed; + border-bottom: #cdcdcd 1px dashed; + margin: 0px auto 20px auto; + padding: 0; +} + +table.pop_box th { + text-align: right; + height: 30px; +} + +table.pop_box th.space { + height: 15px; +} + +.pop_close { + background: url(../images/pop_close.png); + width: 20px; + height: 20px; + margin: 10px 0 0 13px; + cursor: pointer; +} + +.tip_close { + margin: 13px 14px 0 0; + float: right; +} + +.pop_tipmessage table, .pop_tipmessage_del table, .pop_tipmessage_succeed table, .pop_tipmessage_choose table { + padding: 100px 60px 0 0; + float: right; + *margin: 100px 60px 0 0; +} + +.pop_tipmessage table th, .pop_tipmessage_del table th, .pop_tipmessage_succeed table th, .pop_tipmessage_choose table th { + font-size: 30px; + font-weight: 500; + color: #333; + text-align: right; +} + +.pop_tipmessage table td, .pop_tipmessage_del table td, .pop_tipmessage_succeed table td, .pop_tipmessage_choose table td { + line-height: 60px; + text-align: right; +} + +.pop_tipmessage table td.pop_tip_btn, .pop_tipmessage_del table td.pop_tip_btn, .pop_tipmessage_succeed table td.pop_tip_btn, .pop_tipmessage_choose table td.pop_tip_btn { + padding-top: 30px; +} + +/*翻页*/ +span.go a { + font-weight: bold; + margin-left: 5px; + text-decoration: none; + font-size: 14px; +} + +.prev, .num { + padding: 0 5px 0 5px; +} + +/*login*/ +.user { + color: #fff; + float: right; + width: 400px; + margin-top: 80px; + margin-right: 50px; +} + +.user table td { + line-height: 42px; + padding-left: 10px; +} + +input.login_input { + border: #989898 1px solid; + padding: 2px 0 0 4px; + width: 220px; + height: 17px; +} + +/*横向tab*/ +.contentbox_tab { + clear: both; + background: #fff; + padding: 15px 15px 8px 15px; + overflow: hidden; + margin-right: -10px; + margin-bottom: 8px; +} + +.menubox ul li { + float: left; + display: block; + cursor: pointer; + width: 90px; + text-align: center; + line-height: 28px; + line-height: 28px \0; +} + +.menubox ul li a { + text-decoration: none; + color: #fff; +} + +.menubox ul li.active { + background: url(../images/tab_active.png); + width: 90px; + height: 29px; +} + +.menubox ul li.active a { + color: #666; +} + +.tab { + clear: left; + *margin-top: -10px; +} + +.box_tab { + background: #f5f5f5; + border: #ccc 1px solid; +} + +/*纵向tab*/ +.favorite { + width: 291px; + clear: left; + float: left; + *margin-top: 10px; +} + +.fav_tab { + float: right; +} + +.fav_tab ul li { + background: url(../images/fav_tab_normal.png); + width: 20px; + height: 70px; +} + +.fav_tab ul li.active { + background: url(../images/fav_tab_active.png); + width: 20px; + height: 70px; +} + +.fav_tab ul li a, .fav_tab ul li.active a { + text-decoration: none; + padding: 6px 0 0 4px; + display: block; + line-height: 15px; +} + +.fav_box { + float: left; + width: 269px; + min-height: 150px; + background: #f5f5f5; + border: #ccc 1px solid; +} + +.fav_box_title { + background: url(../images/fav_title.png); + height: 30px; + line-height: 30px; + padding-left: 15px; +} + +.fav_box_title span { + padding-left: 5px; +} + +.fav_box_title img { + margin-left: 20px; +} + +.fav_title_left { + float: left; +} + +.fav_content { + margin: 10px 0 10px 15px; +} + +.fav_content table td { + line-height: 23px; +} + +.fav_tips { + width: 210px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.fav_tips a { + text-decoration: none; +} + +/*setting*/ +.setting_box { + background: #f0f2f4; + border: #ccc 1px solid; + clear: both; + padding: 20px 20px 25px 20px; + *padding-top: 10px; + margin-bottom: 10px; +} + +.setting_box table.setting th { + font-weight: normal; + text-align: right; + line-height: 32px; + width: 100px; +} + +.setting_box table.setting td { + padding-left: 10px; +} + +span.red { + color: #F00; + margin-left: 10px; +} + +input.setting_input { + width: 200px; + height: 18px; +} + +select.setting_select { + width: 202px; + height: 18px; +} + +.setting_box_page { + padding-bottom: 30px; +} + +/*pop_tips*/ +.pop_tips { + width: 300px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + + + diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/dubbo.css b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/dubbo.css new file mode 100644 index 0000000..3a462d9 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/dubbo.css @@ -0,0 +1,335 @@ +/* + * 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. + */ + +@charset "utf-8"; +/* CSS Document */ +/*head*/ +.head_right_dubbo { + float: right; +} + +.head_right_dubbo span { + color: #fff; + line-height: 30px; + float: right; + margin-right: 15px; +} + +.head_right_dubbo span a { + color: #fff; +} + +.exit { + float: right; + padding-top: 3px; +} + +.head_right_dubbotop { + margin-top: 0px; + margin-right: 0px; + color: white; +} + +.head_right_dubbobottom { + margin-top: 30px; + margin-right: 10px; + text-align: right; + color: white; +} + +.head_right_dubbobottom td { + margin-left: 50px; +} + +/*title*/ +.title_search { + margin-bottom: 20px; + *margin-bottom: 10px; +} + +.dubbo_search { + background: url(../images/main_bg.png) repeat-x; + padding: 15px 20px 0 20px; + height: 120px; + *height: 100px; +} + +.dubbo_search_nobox { + height: 40px; +} + +.dubbo_main { + height: 100%; + clear: left; +} + +.dubbo_content { + margin: 0 20px 20px 20px; + background: #f3f5f5; + border: #cccccc 1px solid; + padding: 15px 25px 10px 15px; +} + +/*search*/ +.search { + width: 500px; + margin: 150px auto; +} + +.search_o { + clear: left; + width: 500px; +} + +.search_categories { + height: 18px; +} + +.search_categories ul li { + float: left; + width: 60px; + line-height: 10px; + *line-height: 15px; + text-align: center; +} + +.search_categories ul li a { + color: #586573; + text-decoration: none; +} + +.search_categories ul li span.search_line { + margin-left: 10px; + color: #CCC; +} + +.search_categories ul li span.search_line_end { + margin-left: 10px; + color: #fff; +} + +.active { + background: url(../images/search_active.png); + width: 52px; + height: 20px; + display: block; +} + +.search_input { + background: url(../images/search_input.png); + width: 438px; + height: 31px; + float: left; +} + +.search_input input { + border: none; + background: url(../images/input.png); + width: 350px; + height: 21px; + margin: 5px 0 0 80px; + *margin: 4px 0 0 80px; + color: #7d8a98; + line-height: 20px; +} + +.search_btn { + margin-top: 5px; + *margin: 0; +} + +.btn_search { + background: url(../images/btn_service.png); + width: 132px; + height: 20px; + text-align: center; + line-height: 20px; + margin-top: 10px; +} + +.btn_search a, .btn_info a { + text-decoration: none; + color: #666; + display: block; +} + +/*table*/ +table.info { + width: 100%; +} + +table.info th { + font-weight: bold; + text-align: left; + padding-top: 10px; +} + +table.info td { + font-weight: normal; + text-align: left; + padding-top: 10px; + padding-left: 10px; +} + +.btn_info { + background: url(../images/btn_info.png); + width: 78px; + height: 20px; + text-align: center; + line-height: 20px; + float: left; + margin: 5px 5px 10px 0; +} + +.search_list input { + width: 200px; + float: left; + margin-right: 10px; + height: 17px; +} + +table.list_dubbo th { + background: url(../images/dubbo_list_th.png); + height: 29px; + color: #586573; + font-weight: normal; + padding-left: 10px; +} + +table.list_dubbo th.checkbox { + width: 50px; +} + +table.list_dubbo th.operate, table.list_system th.operate { + width: 190px; +} + +table.list_system { + width: 700px; +} + +table.list_system th { + text-align: left; +} + +table.list_system th.operate_system { + width: 180px; +} + +table.list_system td span.radio_font { + padding: 0 40px 0 5px; +} + +span.rule_green { + color: #390; +} + +span.rule_orange { + color: #F60; +} + +/*setting*/ +span.state { + color: #390; +} + +/*favorite*/ +.favorite { + width: 291px; + clear: left; + float: left; + *margin-top: 10px; +} + +.fav_tab { + float: right; +} + +.fav_tab ul li { + background: url(../images/fav_tab_normal.png); + width: 20px; + height: 70px; +} + +.fav_tab ul li.active { + background: url(../images/fav_tab_active.png); + width: 20px; + height: 70px; +} + +.fav_tab ul li a, .fav_tab ul li.active a { + text-decoration: none; + padding: 6px 0 0 4px; + display: block; + line-height: 15px; +} + +.fav_box { + float: left; + width: 269px; + min-height: 150px; + background: #f5f5f5; + border: #ccc 1px solid; +} + +.fav_box_title { + background: url(../images/fav_title.png); + height: 30px; + line-height: 30px; + padding-left: 15px; +} + +.fav_box_title span { + padding-left: 5px; +} + +.fav_box_title img { + margin-left: 20px; +} + +.fav_title_left { + float: left; +} + +.fav_content { + margin: 10px 0 10px 15px; +} + +.fav_content table td { + line-height: 23px; +} + +.fav_tips { + width: 210px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.fav_tips a { + text-decoration: none; +} + +.fav_content_checkbox { + margin-right: 10px; +} + +.fav_arrow { + float: right; + padding-top: 7px; + padding-right: 10px; +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/skin.css b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/skin.css new file mode 100644 index 0000000..d0e0794 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/css/skin.css @@ -0,0 +1,275 @@ +/* + * 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. + */ + +@charset "utf-8"; +/* CSS Document */ +/*head*/ +.head { + min-width: 1150px; + height: 78px; + background-image: url(../images/head_bg.png); +} + +/*menu*/ +.nav, .nav_harbor { + color: #FFF; + background-image: url(../images/nav_bg.png); + min-width: 1150px; + height: 31px; + clear: right; +} + +.nav ul li a:hover, .nav_harbor ul li a:hover, .nav_harbor ul li:hover a { + background-image: url(../images/nav_pass.png); +} + +.nav ul li ul, .nav ul li ul li { + background-color: #3d8efa; +} + +.nav ul li ul li a:hover { + background-color: #64a6fd; +} + +.nav ul li.sub_nav { + background: url(../images/nav_btn_bg22.png) no-repeat; +} + +.nav ul li.sub_nav:hover { + color: #fff; + background: url(../images/nav_btn_bg22.png) no-repeat 0 -31px; +} + +.nav ul li.sub_nav a:hover { + color: #fff; + background: url(../images/nav_btn_bg22.png) no-repeat 0 -31px; +} + +.nav ul li.sub_nav ul li a:hover { + background-color: #64a6fd; + background-image: none; +} + +.nav ul li.current_nosub { + background: url(../images/nav_btn_bg44.png) no-repeat; +} + +.nav ul li.current_nosub :hover { + background: url(../images/nav_btn_bg44.png) no-repeat; +} + +.nav ul li.current:hover > a { + background: url(../images/nav_btn_bg22.png) no-repeat 0 -31px; + color: #fff; +} + +.nav ul li.current, .nav_harbor ul li.current { + background-image: url(../images/nav_btn_bg3.png); + background-position: right; +} + +.nav ul li.current a:hover { + background: url(../images/nav_btn_bg22.png) no-repeat 0 -31px; +} + +.nav ul li.current ul li a:hover { + background-color: #64a6fd; + background-image: none; +} + +.nav_harbor li .sub { + background-color: #3d8efa; +} + +.nav_harbor .sub ul li a:hover { + background-color: #64a5fc; +} + +li.sub_font { + color: #fff82d; + font-weight: bold; +} + +/*全局搜索*/ +.search_input { + background: url(../images/search_input.png); + width: 438px; + height: 31px; + float: left; +} + +.search_input input { + border: none; + background: url(../images/input.png); + width: 350px; + height: 21px; + margin: 5px 0 0 80px; + *margin: 4px 0 0 80px; + color: #7d8a98; + line-height: 20px; +} + +.active { + background: url(../images/search_active.png); + width: 52px; + height: 20px; + display: block; +} + +/*table*/ +table.list th { + background: url(../images/table_title_bg.png) repeat-x; +} + +table.list th.head_title { + background: url(../images/table_title_bg.png); + width: 10px; + height: 29px; +} + +/*pop*/ +table.pop_top td.pop_lefttop_small { + background: url(../images/pop_lefttop_small.png); + width: 300px; + height: 105px; +} + +.pop_tipmessage { + background: url(../images/tip_warning.png); +} + +.pop_tipmessage_choose { + background: url(../images/tip_choose.png); +} + +.pop_tipmessage_del { + background: url(../images/tip_del.png); +} + +.pop_tipmessage_succeed { + background: url(../images/tip_succeed.png); +} + +.pop_tipmessage, .pop_tipmessage_choose, .pop_tipmessage_del, .pop_tipmessage_succeed { + width: 720px; + height: 300px; +} + +/*button*/ +.btn { + width: 65px; + height: 20px; + background: url(../images/button_normal.png); + text-align: center; + float: left; + margin-right: 5px; + line-height: 20px; + display: block; +} + +.btn a:hover { + color: #C60; + width: 65px; + height: 20px; + background: url(../images/button_hover.png); + text-align: center; + float: left; + margin-right: 5px; + display: block; +} + +.login_btn { + width: 65px; + height: 20px; + background: url(../images/login_btn_normal.png); + text-align: center; + margin-right: 5px; + line-height: 20px; + display: block; +} + +.login_btn a:hover { + color: #C60; + width: 65px; + height: 20px; + background: url(../images/login_btn_hover.png); + text-align: center; + float: left; + margin-right: 5px; + display: block; +} + +/*footer*/ +.footer { + margin-top: 10px; + *margin: 0; + min-width: 1150px; + background: #808080; + height: 28px; +} + +/*翻页*/ +.page { + color: #2a7ec5; + float: right; + padding-bottom: 5px; +} + +.page a { + color: #2a7ec5; +} + +a.current_num { + color: #f09a3e; +} + +/*login*/ +.login { + background-image: url(../images/login_bg.png); + background-repeat: no-repeat; + background-color: #1a4f89; +} + +.login_container { + width: 100%; + margin-top: 200px; + background-image: url(../images/login_shadow.png); + height: 231px; +} + +.login_box { + margin: 0 auto; + background-image: url(../images/login_box.png); + width: 804px; + height: 231px; +} + +/*tab*/ +.menubox { + background: #8ebdec; + height: 29px; + width: 100%; + padding-left: 10px; +} + +/*可伸缩区块*/ +a.title_o { + font-size: 14px; + font-weight: bold; + text-decoration: none; + color: #2f7ed3; +} diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/404error.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/404error.gif new file mode 100644 index 0000000..bb0a0d4 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/404error.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg01.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg01.gif new file mode 100644 index 0000000..b4bb53d Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg01.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg02.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg02.gif new file mode 100644 index 0000000..8ef69e2 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg02.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg03.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg03.gif new file mode 100644 index 0000000..758e1a6 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg03.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg04.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg04.gif new file mode 100644 index 0000000..1b0d3c4 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/bg04.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/btn_info.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/btn_info.png new file mode 100644 index 0000000..f134253 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/btn_info.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/btn_service.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/btn_service.png new file mode 100644 index 0000000..2db951e Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/btn_service.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/button_hover.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/button_hover.png new file mode 100644 index 0000000..7349fa6 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/button_hover.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/button_normal.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/button_normal.png new file mode 100644 index 0000000..da86a90 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/button_normal.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_01.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_01.gif new file mode 100644 index 0000000..e724e6f Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_01.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_02.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_02.gif new file mode 100644 index 0000000..a885908 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_02.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_03.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_03.gif new file mode 100644 index 0000000..8a05188 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_03.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_04.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_04.gif new file mode 100644 index 0000000..cae50cd Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/co_04.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/dog.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/dog.gif new file mode 100644 index 0000000..65a7ad8 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/dog.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/dubbo_list_th.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/dubbo_list_th.png new file mode 100644 index 0000000..18c206c Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/dubbo_list_th.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/exit.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/exit.png new file mode 100644 index 0000000..463d73e Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/exit.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_arrow.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_arrow.png new file mode 100644 index 0000000..2308b42 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_arrow.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_tab_active.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_tab_active.png new file mode 100644 index 0000000..e81be9c Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_tab_active.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_tab_normal.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_tab_normal.png new file mode 100644 index 0000000..52cbe09 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_tab_normal.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_title.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_title.png new file mode 100644 index 0000000..56c1103 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/fav_title.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/head_bg.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/head_bg.png new file mode 100644 index 0000000..3613f89 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/head_bg.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_add.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_add.png new file mode 100644 index 0000000..beb0b3b Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_add.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_back.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_back.png new file mode 100644 index 0000000..1a42281 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_back.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_balance.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_balance.png new file mode 100644 index 0000000..94fba84 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_balance.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_cancel.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_cancel.png new file mode 100644 index 0000000..62a9f20 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_cancel.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_delete.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_delete.png new file mode 100644 index 0000000..33a2eed Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_delete.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_disable.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_disable.png new file mode 100644 index 0000000..0c5b834 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_disable.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_down.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_down.png new file mode 100644 index 0000000..229a185 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_down.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_edit.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_edit.png new file mode 100644 index 0000000..aca3e86 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_edit.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_enable.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_enable.png new file mode 100644 index 0000000..516d1a5 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_enable.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_error.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_error.png new file mode 100644 index 0000000..edacb87 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_error.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_favorite.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_favorite.png new file mode 100644 index 0000000..8c5972e Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_favorite.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_forb.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_forb.png new file mode 100644 index 0000000..19bba76 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_forb.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_graph.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_graph.png new file mode 100644 index 0000000..265510c Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_graph.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_help.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_help.png new file mode 100644 index 0000000..be52814 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_help.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_list.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_list.png new file mode 100644 index 0000000..4a8672b Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_list.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_password.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_password.png new file mode 100644 index 0000000..1cc0332 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_password.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_reconnect.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_reconnect.png new file mode 100644 index 0000000..3cccf2f Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_reconnect.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_recover.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_recover.png new file mode 100644 index 0000000..a1664ea Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_recover.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_register.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_register.png new file mode 100644 index 0000000..7ef0014 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_register.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_reload.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_reload.png new file mode 100644 index 0000000..bc55bca Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_reload.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_renotify.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_renotify.png new file mode 100644 index 0000000..f759a12 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_renotify.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_run.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_run.png new file mode 100644 index 0000000..fa12a82 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_run.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_save.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_save.png new file mode 100644 index 0000000..5c10b60 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_save.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_search.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_search.png new file mode 100644 index 0000000..4e293ca Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_search.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_show.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_show.png new file mode 100644 index 0000000..c2fe42c Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_show.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_subscribe.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_subscribe.png new file mode 100644 index 0000000..936a522 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_subscribe.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_tree.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_tree.png new file mode 100644 index 0000000..9eede1d Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_tree.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_up.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_up.png new file mode 100644 index 0000000..2524ad3 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_up.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_user.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_user.png new file mode 100644 index 0000000..a1e24a6 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_user.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_warn.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_warn.png new file mode 100644 index 0000000..c27aa4e Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/ico_warn.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/input.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/input.png new file mode 100644 index 0000000..a2f0751 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/input.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_bg.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_bg.png new file mode 100644 index 0000000..0e1facd Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_bg.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_box.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_box.png new file mode 100644 index 0000000..acccbf0 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_box.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_btn_hover.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_btn_hover.png new file mode 100644 index 0000000..54cd6f1 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_btn_hover.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_btn_normal.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_btn_normal.png new file mode 100644 index 0000000..7812701 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_btn_normal.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_shadow.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_shadow.png new file mode 100644 index 0000000..834f363 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/login_shadow.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/logo.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/logo.png new file mode 100644 index 0000000..94308f9 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/logo.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/main_bg.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/main_bg.png new file mode 100644 index 0000000..332c8ed Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/main_bg.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_bg.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_bg.png new file mode 100644 index 0000000..6ced278 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_bg.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg22.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg22.png new file mode 100644 index 0000000..3601181 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg22.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg3.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg3.png new file mode 100644 index 0000000..d5742a2 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg3.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg33.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg33.png new file mode 100644 index 0000000..bfaccc6 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg33.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg44.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg44.png new file mode 100644 index 0000000..5f03443 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_btn_bg44.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_pass.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_pass.png new file mode 100644 index 0000000..3561328 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_pass.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_selected.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_selected.png new file mode 100644 index 0000000..9ece20b Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/nav_selected.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_close.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_close.png new file mode 100644 index 0000000..14dcdaa Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_close.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_left.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_left.png new file mode 100644 index 0000000..3c8668d Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_left.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_leftbottom.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_leftbottom.png new file mode 100644 index 0000000..5c8a5bf Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_leftbottom.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_lefttop_small.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_lefttop_small.png new file mode 100644 index 0000000..34c1478 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_lefttop_small.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_midbottom.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_midbottom.png new file mode 100644 index 0000000..4c39433 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_midbottom.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_midtop_small.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_midtop_small.png new file mode 100644 index 0000000..d036814 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_midtop_small.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_right.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_right.png new file mode 100644 index 0000000..1bbbb32 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_right.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_rightbottom.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_rightbottom.png new file mode 100644 index 0000000..5c32a9f Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_rightbottom.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_righttop_small.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_righttop_small.png new file mode 100644 index 0000000..983ecc4 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/pop_righttop_small.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_active.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_active.png new file mode 100644 index 0000000..4bf1d32 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_active.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_btn.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_btn.png new file mode 100644 index 0000000..844d016 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_btn.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_global_m.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_global_m.png new file mode 100644 index 0000000..7c00491 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_global_m.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_input.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_input.png new file mode 100644 index 0000000..b5691b5 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_input.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_line.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_line.png new file mode 100644 index 0000000..d9c9dbb Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/search_line.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tab_active.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tab_active.png new file mode 100644 index 0000000..34de8bc Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tab_active.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/table_title_bg.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/table_title_bg.png new file mode 100644 index 0000000..2586d23 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/table_title_bg.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_choose.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_choose.png new file mode 100644 index 0000000..a92cbbd Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_choose.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_confirm.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_confirm.png new file mode 100644 index 0000000..83a03b1 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_confirm.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_del.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_del.png new file mode 100644 index 0000000..cfaf2a2 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_del.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_succeed.png b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_succeed.png new file mode 100644 index 0000000..bfb298a Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tip_succeed.png differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-blank.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-blank.gif new file mode 100644 index 0000000..17cf25b Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-blank.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-down-left.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-down-left.gif new file mode 100644 index 0000000..1131c00 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-down-left.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-down.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-down.gif new file mode 100644 index 0000000..84d38c2 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-down.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-left-up.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-left-up.gif new file mode 100644 index 0000000..f69e719 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-left-up.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-right-down.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-right-down.gif new file mode 100644 index 0000000..2a90da8 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-right-down.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-up-right.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-up-right.gif new file mode 100644 index 0000000..1db49d8 Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-up-right.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-up.gif b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-up.gif new file mode 100644 index 0000000..a135d8f Binary files /dev/null and b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/images/tree-up.gif differ diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/ajax.js b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/ajax.js new file mode 100644 index 0000000..3ae7ad7 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/ajax.js @@ -0,0 +1,89 @@ +/* + * 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. + */ + +var Ajax = { + get: function (url, fn) { + XR.open("GET", url, true); + XR.onreadystatechange = function () { + if (XR.readyState == 4) { + try { + fn(eval("(" + XR.responseText + ")")); + } catch (e) { + fn(null); + } + } + }; + XR.send(null) + }, + post: function (url, fn) { + XR.open("POST", url, true); + XR.onreadystatechange = function () { + if (XR.readyState == 4) { + try { + fn(eval("(" + XR.responseText + ")")); + } catch (e) { + fn(null); + } + } + }; + XR.send(null) + }, + put: function (url, fn) { + XR.open("PUT", url, true); + XR.onreadystatechange = function () { + if (XR.readyState == 4) { + try { + fn(eval("(" + XR.responseText + ")")); + } catch (e) { + fn(null); + } + } + }; + XR.send(null) + }, + delete: function (url, fn) { + XR.open("DELETE", url, true); + XR.onreadystatechange = function () { + if (XR.readyState == 4) { + try { + fn(eval("(" + XR.responseText + ")")); + } catch (e) { + fn(null); + } + } + }; + XR.send(null) + } +}; +var XR = false; +try { + XR = new XMLHttpRequest() +} catch (trymicrosoft) { + try { + XR = new ActiveXObject("Msxml2.XMLHTTP") + } catch (othermicrosoft) { + try { + XR = new ActiveXObject("Microsoft.XMLHTTP") + } catch (failed) { + XR = false + } + } +} +if (!XR) { + alert("Error Initializing XMLHttpRequest!") +} +; \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/box.js b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/box.js new file mode 100644 index 0000000..607916f --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/box.js @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* eg: Box.show(div) */ +var Box = { + show: function (id) { + var isIE = (document.all) ? true : false; + var isIE6 = isIE && ( [/MSIE (\d)\.0/i.exec(navigator.userAgent)][0][1] == 6); + var box = document.getElementById(id); + if (!box) { + return; + } + box.style.zIndex = "9999"; + box.style.display = "block" + box.style.position = !isIE6 ? "fixed" : "absolute"; + box.style.top = box.style.left = "50%"; + box.style.marginTop = -box.offsetHeight / 2 + "px"; + box.style.marginLeft = -box.offsetWidth / 2 + "px"; + var layer = document.getElementById("_box_layer"); + if (!layer) { + layer = document.createElement("div"); + layer.id = "_box_layer"; + layer.style.width = layer.style.height = "100%"; + layer.style.position = !isIE6 ? "fixed" : "absolute"; + layer.style.top = layer.style.left = 0; + layer.style.backgroundColor = "#000"; + layer.style.zIndex = "9998"; + layer.style.opacity = "0.6"; + document.body.appendChild(layer); + } else { + layer.style.display = ""; + } + var selects = document.getElementsByTagName("select"); + if (selects) { + for (var i = 0; i < selects.length; i++) { + selects[i].style.visibility = "hidden"; + } + } + function layer_iestyle() { + layer.style.width = Math.max(document.documentElement.scrollWidth, + document.documentElement.clientWidth) + + "px"; + layer.style.height = Math.max(document.documentElement.scrollHeight, + document.documentElement.clientHeight) + + "px"; + } + + function box_iestyle() { + box.style.marginTop = document.documentElement.scrollTop + - box.offsetHeight / 2 + "px"; + box.style.marginLeft = document.documentElement.scrollLeft + - box.offsetWidth / 2 + "px"; + } + + if (isIE) { + layer.style.filter = "alpha(opacity=60)"; + } + if (isIE6) { + layer_iestyle() + box_iestyle(); + window.attachEvent("onscroll", function () { + box_iestyle(); + }) + window.attachEvent("onresize", layer_iestyle) + } + }, + hide: function (id) { + var box = document.getElementById(id); + if (box) { + box.style.display = "none"; + } + var layer = document.getElementById("_box_layer"); + if (layer) { + layer.style.display = "none"; + } + var selects = document.getElementsByTagName("select"); + if (selects) { + for (var i = 0; i < selects.length; i++) { + selects[i].style.visibility = "visible"; + } + } + } +} \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/dubbo.js b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/dubbo.js new file mode 100644 index 0000000..6433e65 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/dubbo.js @@ -0,0 +1,546 @@ +/* + * 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. + */ + +//==== init ==== +function init() { + initScroll(); + preloadImage(); + scanAlphaPNG(); + addChangeRowEvent(); +} +// ==== utils ==== +var isIE = (window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf(" msie ") != -1); +var isIE6 = (isIE && (navigator.userAgent.toLowerCase().indexOf(" msie 5.") > -1 +|| navigator.userAgent.toLowerCase().indexOf(" msie 6.") > -1)); +String.prototype.trim = function () { + return this.replace(/(^\\s*)|(\\s*$)/g, ""); +} +function checkNumber() { + if (event.keyCode == 8 || event.keyCode == 46 + || (event.keyCode >= 37 && event.keyCode <= 40) + || (event.keyCode >= 48 && event.keyCode <= 57) + || (event.keyCode >= 96 && event.keyCode <= 105)) + return true; + return false; +} +function randPassword() { + var text = ['ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz', '1234567890', '~_-+=']; + var rand = function (min, max) { + return Math.floor(Math.max(min, Math.random() * (max + 1))); + } + var len = 16 + rand(0, 16); + var pwd = ''; + for (i = 0; i < len; ++i) { + var part = text[rand(0, 3)]; + pwd += part.charAt(rand(0, part.length)); + } + return pwd; +} +function byId(x) { + if (typeof x == "string") + return document.getElementById(x); + return x; +} + +function addParameter(address, value) { + var url = new URL(address) + url.searchParams.set("lang", value) + window.location.href = url.href +} + +// ==== cookie ==== +function setCookie(key, value) { + var date = new Date(); + date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000)); + document.cookie = key + "=" + escape(value) + "; path=/; expires=" + date.toGMTString(); +} +function getCookie(objName) { + var arrStr = document.cookie.split("; "); + for (var i = 0; i < arrStr.length; i++) { + var temp = arrStr[i].split("="); + if (temp[0] == objName) { + return unescape(temp[1]); + } + } +} +function addCookie(objName, objValue, objHours) { + var str = objName + "=" + escape(objValue); + if (objHours > 0) { + var date = new Date(); + var ms = objHours * 3600 * 1000; + date.setTime(date.getTime() + ms); + str += ";path=/;expires=" + date.toGMTString(); + } + document.cookie = str; +} +// ==== search table ==== +var lastSequence = 0; +function searchTable(id, column, keyword) { + var table = byId(id); + if (table) { + lastSequence++; + var sequence = lastSequence; + for (var i = 1; i < table.rows.length && sequence == lastSequence; i++) { + var row = table.rows[i]; + var cell = row.cells[column]; + if (keyword == null || keyword.length == 0 + || cell.innerHTML.toLowerCase().indexOf(keyword.toLowerCase()) >= 0) { + row.style.display = ''; + } else { + row.style.display = 'none'; + } + } + } +} +function addChangeRowEvent() { + var content = document.getElementById('table_o'); + if (content) { + for (var i = 0; i < content.rows.length; i++) { + var cell = content.rows[i].cells[0]; + if (cell.nodeName != "TH" && cell.nodeName != "th") { + var moveFunc = function (ii) { + return function () { + content.rows[ii].style.background = "#F8F8F8"; + } + }(i); + var outFunc = function (ii) { + return function () { + content.rows[ii].style.background = "#FFFFFF"; + } + }(i); + if (isIE) { + content.rows[i].onmousemove = moveFunc; + content.rows[i].onmouseout = outFunc; + } else { + content.rows[i].addEventListener("mousemove", moveFunc, false); + content.rows[i].addEventListener("mouseout", outFunc, false); + } + } + } + } +} +// ==== tab ==== +function setTab(name, cursel, n) { + for (i = 1; i <= n; i++) { + var menu = byId(name + i); + var con = byId("con_" + name + "_" + i); + menu.className = i == cursel ? "active" : ""; + con.style.display = i == cursel ? "block" : "none"; + } +} +function setActiveTab(i) { + if (i == 1) { + document.getElementById("unique_tab" + i).className = "current_nosub"; + } else { + document.getElementById("unique_tab" + i).className = "current"; + } +} + +// ==== check box ==== +function checkAll(tableId, checkboxName, checked) { + var checkboxs = document.getElementsByName(checkboxName); + var checktable = document.getElementById(tableId); + for (var i = 0; i < checkboxs.length; i++) { + if (checktable && checktable.rows.length > i + 1 && checktable.rows[i + 1].style.display == 'none') { + checkboxs[i].checked = false; + } else { + checkboxs[i].checked = checked; + } + } +} +function hasCheckbox(name) { + var checkboxs = document.getElementsByName(name); + return checkboxs && checkboxs.length > 0; +} +function hasChecked(name) { + var checkboxs = document.getElementsByName(name); + if (checkboxs && checkboxs.length > 0) { + for (var i = 0; i < checkboxs.length; i++) { + if (checkboxs[i].checked) { + return true; + } + } + } + return false; +} +function getChecked(name) { + var result = ""; + var checkboxs = document.getElementsByName(name); + for (var i = 0; i < checkboxs.length; i++) { + if (checkboxs[i].checked) { + if (result.length > 0) { + result = result + ","; + } + result = result + checkboxs[i].value; + } + } + return result; +} +// ==== show box ==== +var confirmUrl = ""; +function confirmRedirect(msg, data, url) { + showConfirm(msg, data, url); +} +function showConfirm(msg, data, url) { + if (!url) { + url = data; + data = ""; + } + if (url == null || url == "") { + return; + } + if (msg == null || msg == "") { + msg = "Confirm?"; + } + confirmUrl = url; + byId("confirmText").innerHTML = msg; + byId("confirmData").innerHTML = data; + Box.show("confirmBox"); +} +function confirmOK() { + Box.hide("confirmBox"); + if (confirmUrl == null || confirmUrl == "") { + return; + } + window.location.href = confirmUrl; +} +function confirmCancel() { + Box.hide("confirmBox"); +} +var alertId = ""; +function showAlert(msg, data, id) { + if (id) { + alertId = id; + } else { + alertId = ""; + } + if (msg == null || msg == "") { + msg = "Please input!"; + } + if (data == null) { + data = ""; + } + byId("alertText").innerHTML = msg; + byId("alertData").innerHTML = data; + Box.show("alertBox"); +} +function alertOK() { + Box.hide("alertBox"); + if (alertId == null || alertId == "") { + return; + } + byId(alertId).focus(); +} +// ==== scroll bar ==== +var marqueeInterval = null; +function moveScroll() { + var marqueeBox = document.getElementById("marqueeBox"); + var marqueeText = document.getElementById("marqueeText"); + if (marqueeBox.scrollLeft >= marqueeText.offsetWidth - 3000) { + marqueeBox.scrollLeft = 0; + } else { + marqueeBox.scrollLeft = marqueeBox.scrollLeft + 1; + } +} +function startScroll() { + marqueeInterval = window.setInterval(moveScroll, 30) +} +function stopScroll() { + window.clearInterval(marqueeInterval) +} +function initScroll() { + var marqueeText = document.getElementById("marqueeText"); + if (marqueeText == null) { + return; + } + var str = marqueeText.innerHTML; + var i = str.indexOf(">"); + if (i > 0) { + str = str.substring(i + 1); + } + var len = str.length + str.replace(/\x00-\x7f/g, '').length; + marqueeText.style.width = (len * 6 + 30) + "px"; + startScroll(); +} +// ==== show modal ==== +$(function () { + function showModal(src, height, width) { + jQuery.modal('') + .css($.extend(s.o.iframeCss, { + display: 'none', + opacity: 0, + position: 'fixed', + height: w[0], + width: w[1], + zIndex: s.o.zIndex, + top: 0, + left: 0 + })) + .appendTo(s.o.appendTo); + } + + // create the overlay + s.d.overlay = $('
') + .attr('id', s.o.overlayId) + .addClass('simplemodal-overlay') + .css($.extend(s.o.overlayCss, { + display: 'none', + opacity: s.o.opacity / 100, + height: s.o.modal ? w[0] : 0, + width: s.o.modal ? w[1] : 0, + position: 'fixed', + left: 0, + top: 0, + zIndex: s.o.zIndex + 1 + })) + .appendTo(s.o.appendTo); + + // create the container + s.d.container = $('
') + .attr('id', s.o.containerId) + .addClass('simplemodal-container') + .css($.extend(s.o.containerCss, { + display: 'none', + position: 'fixed', + zIndex: s.o.zIndex + 2 + })) + .append(s.o.close && s.o.closeHTML + ? $(s.o.closeHTML).addClass(s.o.closeClass) + : '') + .appendTo(s.o.appendTo); + + s.d.wrap = $('
') + .attr('tabIndex', -1) + .addClass('simplemodal-wrap') + .css({height: '100%', outline: 0, width: '100%'}) + .appendTo(s.d.container); + + // add styling and attributes to the data + // append to body to get correct dimensions, then move to wrap + s.d.data = data + .attr('id', data.attr('id') || s.o.dataId) + .addClass('simplemodal-data') + .css($.extend(s.o.dataCss, { + display: 'none' + })) + .appendTo('body'); + data = null; + + s.setContainerDimensions(); + s.d.data.appendTo(s.d.wrap); + + // fix issues with IE + if (ie6 || ieQuirks) { + s.fixIE(); + } + }, + /* + * Bind events + */ + bindEvents: function () { + var s = this; + + // bind the close event to any element with the closeClass class + $('.' + s.o.closeClass).bind('click.simplemodal', function (e) { + e.preventDefault(); + s.close(); + }); + + // bind the overlay click to the close function, if enabled + if (s.o.modal && s.o.close && s.o.overlayClose) { + s.d.overlay.bind('click.simplemodal', function (e) { + e.preventDefault(); + s.close(); + }); + } + + // bind keydown events + $(document).bind('keydown.simplemodal', function (e) { + if (s.o.modal && e.keyCode === 9) { // TAB + s.watchTab(e); + } + else if ((s.o.close && s.o.escClose) && e.keyCode === 27) { // ESC + e.preventDefault(); + s.close(); + } + }); + + // update window size + $(window).bind('resize.simplemodal', function () { + // redetermine the window width/height + w = s.getDimensions(); + + // reposition the dialog + s.o.autoResize ? s.setContainerDimensions() : s.o.autoPosition && s.setPosition(); + + if (ie6 || ieQuirks) { + s.fixIE(); + } + else if (s.o.modal) { + // update the iframe & overlay + s.d.iframe && s.d.iframe.css({height: w[0], width: w[1]}); + s.d.overlay.css({height: w[0], width: w[1]}); + } + }); + }, + /* + * Unbind events + */ + unbindEvents: function () { + $('.' + this.o.closeClass).unbind('click.simplemodal'); + $(document).unbind('keydown.simplemodal'); + $(window).unbind('resize.simplemodal'); + this.d.overlay.unbind('click.simplemodal'); + }, + /* + * Fix issues in IE6 and IE7 in quirks mode + */ + fixIE: function () { + var s = this, p = s.o.position; + + // simulate fixed position - adapted from BlockUI + $.each([s.d.iframe || null, !s.o.modal ? null : s.d.overlay, s.d.container], function (i, el) { + if (el) { + var bch = 'document.body.clientHeight', bcw = 'document.body.clientWidth', + bsh = 'document.body.scrollHeight', bsl = 'document.body.scrollLeft', + bst = 'document.body.scrollTop', bsw = 'document.body.scrollWidth', + ch = 'document.documentElement.clientHeight', cw = 'document.documentElement.clientWidth', + sl = 'document.documentElement.scrollLeft', st = 'document.documentElement.scrollTop', + s = el[0].style; + + s.position = 'absolute'; + if (i < 2) { + s.removeExpression('height'); + s.removeExpression('width'); + s.setExpression('height', '' + bsh + ' > ' + bch + ' ? ' + bsh + ' : ' + bch + ' + "px"'); + s.setExpression('width', '' + bsw + ' > ' + bcw + ' ? ' + bsw + ' : ' + bcw + ' + "px"'); + } + else { + var te, le; + if (p && p.constructor === Array) { + var top = p[0] + ? typeof p[0] === 'number' ? p[0].toString() : p[0].replace(/px/, '') + : el.css('top').replace(/px/, ''); + te = top.indexOf('%') === -1 + ? top + ' + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"' + : parseInt(top.replace(/%/, '')) + ' * ((' + ch + ' || ' + bch + ') / 100) + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"'; + + if (p[1]) { + var left = typeof p[1] === 'number' ? p[1].toString() : p[1].replace(/px/, ''); + le = left.indexOf('%') === -1 + ? left + ' + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"' + : parseInt(left.replace(/%/, '')) + ' * ((' + cw + ' || ' + bcw + ') / 100) + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"'; + } + } + else { + te = '(' + ch + ' || ' + bch + ') / 2 - (this.offsetHeight / 2) + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"'; + le = '(' + cw + ' || ' + bcw + ') / 2 - (this.offsetWidth / 2) + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"'; + } + s.removeExpression('top'); + s.removeExpression('left'); + s.setExpression('top', te); + s.setExpression('left', le); + } + } + }); + }, + /* + * Place focus on the first or last visible input + */ + focus: function (pos) { + var s = this, p = pos && $.inArray(pos, ['first', 'last']) !== -1 ? pos : 'first'; + + // focus on dialog or the first visible/enabled input element + var input = $(':input:enabled:visible:' + p, s.d.wrap); + setTimeout(function () { + input.length > 0 ? input.focus() : s.d.wrap.focus(); + }, 10); + }, + getDimensions: function () { + var el = $(window); + + // fix a jQuery/Opera bug with determining the window height + var h = $.browser.opera && $.browser.version > '9.5' && $.fn.jquery < '1.3' + || $.browser.opera && $.browser.version < '9.5' && $.fn.jquery > '1.2.6' + ? el[0].innerHeight : el.height(); + + return [h, el.width()]; + }, + getVal: function (v, d) { + return v ? (typeof v === 'number' ? v + : v === 'auto' ? 0 + : v.indexOf('%') > 0 ? ((parseInt(v.replace(/%/, '')) / 100) * (d === 'h' ? w[0] : w[1])) + : parseInt(v.replace(/px/, ''))) + : null; + }, + /* + * Update the container. Set new dimensions, if provided. + * Focus, if enabled. Re-bind events. + */ + update: function (height, width) { + var s = this; + + // prevent update if dialog does not exist + if (!s.d.data) { + return false; + } + + // reset orig values + s.d.origHeight = s.getVal(height, 'h'); + s.d.origWidth = s.getVal(width, 'w'); + + // hide data to prevent screen flicker + s.d.data.hide(); + height && s.d.container.css('height', height); + width && s.d.container.css('width', width); + s.setContainerDimensions(); + s.d.data.show(); + s.o.focus && s.focus(); + + // rebind events + s.unbindEvents(); + s.bindEvents(); + }, + setContainerDimensions: function () { + var s = this; + + // get the dimensions for the container and data + var ch = s.d.origHeight ? s.d.origHeight : $.browser.opera ? s.d.container.height() : s.getVal(s.d.container.css('height'), 'h'), + cw = s.d.origWidth ? s.d.origWidth : $.browser.opera ? s.d.container.width() : s.getVal(s.d.container.css('width'), 'w'), + dh = s.d.data.outerHeight(true), dw = s.d.data.outerWidth(true); + + s.d.origHeight = s.d.origHeight || ch; + s.d.origWidth = s.d.origWidth || cw; + + // mxoh = max option height, mxow = max option width + var mxoh = s.o.maxHeight ? s.getVal(s.o.maxHeight, 'h') : null, + mxow = s.o.maxWidth ? s.getVal(s.o.maxWidth, 'w') : null, + mh = mxoh && mxoh < w[0] ? mxoh : w[0], + mw = mxow && mxow < w[1] ? mxow : w[1]; + + // moh = min option height + var moh = s.o.minHeight ? s.getVal(s.o.minHeight, 'h') : 'auto'; + if (!ch) { + if (!dh) { + ch = moh; + } + else { + if (dh > mh) { + ch = mh; + } + else if (s.o.minHeight && moh !== 'auto' && dh < moh) { + ch = moh; + } + else { + ch = dh; + } + } + } + else { + ch = s.o.autoResize && ch > mh ? mh : ch; + } + + // mow = min option width + var mow = s.o.minWidth ? s.getVal(s.o.minWidth, 'w') : 'auto'; + if (!cw) { + if (!dw) { + cw = mow; + } + else { + if (dw > mw) { + cw = mw; + } + else if (s.o.minWidth && mow !== 'auto' && dw < mow) { + cw = mow; + } + else { + cw = dw; + } + } + } + else { + cw = s.o.autoResize && cw > mw ? mw : cw; + } + + s.d.container.css({height: ch, width: cw}); + s.d.wrap.css({overflow: (dh > ch || dw > cw) ? 'auto' : 'visible'}); + s.o.autoPosition && s.setPosition(); + }, + setPosition: function () { + var s = this, top, left, + hc = (w[0] / 2) - (s.d.container.outerHeight(true) / 2), + vc = (w[1] / 2) - (s.d.container.outerWidth(true) / 2); + + if (s.o.position && Object.prototype.toString.call(s.o.position) === '[object Array]') { + top = s.o.position[0] || hc; + left = s.o.position[1] || vc; + } else { + top = hc; + left = vc; + } + s.d.container.css({left: left, top: top}); + }, + watchTab: function (e) { + var s = this; + + if ($(e.target).parents('.simplemodal-container').length > 0) { + // save the list of inputs + s.inputs = $(':input:enabled:visible:first, :input:enabled:visible:last', s.d.data[0]); + + // if it's the first or last tabbable element, refocus + if ((!e.shiftKey && e.target === s.inputs[s.inputs.length - 1]) || + (e.shiftKey && e.target === s.inputs[0]) || + s.inputs.length === 0) { + e.preventDefault(); + var pos = e.shiftKey ? 'last' : 'first'; + s.focus(pos); + } + } + else { + // might be necessary when custom onShow callback is used + e.preventDefault(); + s.focus(); + } + }, + /* + * Open the modal dialog elements + * - Note: If you use the onOpen callback, you must "show" the + * overlay and container elements manually + * (the iframe will be handled by SimpleModal) + */ + open: function () { + var s = this; + // display the iframe + s.d.iframe && s.d.iframe.show(); + + if ($.isFunction(s.o.onOpen)) { + // execute the onOpen callback + s.o.onOpen.apply(s, [s.d]); + } + else { + // display the remaining elements + s.d.overlay.show(); + s.d.container.show(); + s.d.data.show(); + } + + s.o.focus && s.focus(); + + // bind default events + s.bindEvents(); + }, + /* + * Close the modal dialog + * - Note: If you use an onClose callback, you must remove the + * overlay, container and iframe elements manually + * + * @param {boolean} external Indicates whether the call to this + * function was internal or external. If it was external, the + * onClose callback will be ignored + */ + close: function () { + var s = this; + + // prevent close when dialog does not exist + if (!s.d.data) { + return false; + } + + // remove the default events + s.unbindEvents(); + + if ($.isFunction(s.o.onClose) && !s.occb) { + // set the onClose callback flag + s.occb = true; + + // execute the onClose callback + s.o.onClose.apply(s, [s.d]); + } + else { + // if the data came from the DOM, put it back + if (s.d.placeholder) { + var ph = $('#simplemodal-placeholder'); + // save changes to the data? + if (s.o.persist) { + // insert the (possibly) modified data back into the DOM + ph.replaceWith(s.d.data.removeClass('simplemodal-data').css('display', s.display)); + } + else { + // remove the current and insert the original, + // unmodified data back into the DOM + s.d.data.hide().remove(); + ph.replaceWith(s.d.orig); + } + } + else { + // otherwise, remove it + s.d.data.hide().remove(); + } + + // remove the remaining elements + s.d.container.hide().remove(); + s.d.overlay.hide(); + s.d.iframe && s.d.iframe.hide().remove(); + setTimeout(function () { + // opera work-around + s.d.overlay.remove(); + + // reset the dialog object + s.d = {}; + }, 10); + } + } + }; +})(jQuery); diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/menu.js b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/menu.js new file mode 100644 index 0000000..5ae496b --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/menu.js @@ -0,0 +1,69 @@ +/* + * 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. + */ + +// JavaScript Document + +$(function () { + function megaHoverOver() { + $(this).find(".sub").stop().fadeTo('fast', 1).show(); + //Calculate width of all ul's + (function ($) { + jQuery.fn.calcSubWidth = function () { + rowWidth = 0; + //Calculate row + $(this).find("ul").each(function () { + rowWidth += $(this).width(); + }); + }; + })(jQuery); + + if ($(this).find(".row").length > 0) { //If row exists... + var biggestRow = 0; + //Calculate each row + $(this).find(".row").each(function () { + $(this).calcSubWidth(); + //Find biggest row + if (rowWidth > biggestRow) { + biggestRow = rowWidth; + } + }); + //Set width + $(this).find(".sub").css({'width': biggestRow}); + $(this).find(".row:last").css({'margin': '0'}); + } else { //If row does not exist... + $(this).calcSubWidth(); + //Set Width + $(this).find(".sub").css({'width': rowWidth}); + } + } + + function megaHoverOut() { + $(this).find(".sub").stop().fadeTo('fast', 0, function () { + $(this).hide(); + }); + } + + var config = { + sensitivity: 1, // number = sensitivity threshold (must be 1 or higher) + interval: 100, // number = milliseconds for onMouseOver polling interval + over: megaHoverOver, // function = onMouseOver callback (REQUIRED) + timeout: 200, // number = milliseconds delay before onMouseOut + out: megaHoverOut // function = onMouseOut callback (REQUIRED) + }; + $("ul#topnav li .sub").css({'opacity': '0'}); + $("ul#topnav li").hoverIntent(config); +}); diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/pop.js b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/pop.js new file mode 100644 index 0000000..247b368 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/static/js/pop.js @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// JavaScript Document +$(function () { + + function showModal(src, height, width) { + jQuery.modal(' + + + #else + + + + + #parse("/templates/home/control/menu.vm") +## $control.setTemplate("home:menu.vm") + + + + + +
+

#springMessageText("addresses", "addresses")

+
#springMessageText("home", "home") > #springMessageText("addresses", "addresses")
+ + + +
+ + + + #end + \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/home/screen/services.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/home/screen/services.vm new file mode 100644 index 0000000..63192d7 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/home/screen/services.vm @@ -0,0 +1,26 @@ +##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. + + + + + Dubbo Registry + + + + + \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/default.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/default.vm new file mode 100644 index 0000000..5e18d04 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/default.vm @@ -0,0 +1,148 @@ +##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. + + + + + Dubbo Admin + + + + + + #if($_method == "index") + + #end + + + + + +## $control.setTemplate("home:menu.vm") + #parse("/templates/home/control/menu.vm") + + +
+
+ +
+
+ $screen_content +
+
+
+
+ + + + \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/redirect.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/redirect.vm new file mode 100644 index 0000000..91700d2 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/redirect.vm @@ -0,0 +1,29 @@ +##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. + + + + + dubbo + + + + + + + $screen_placeholder + + \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/search.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/search.vm new file mode 100644 index 0000000..30c0a04 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/layout/search.vm @@ -0,0 +1,15 @@ +##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. +$screen_placeholder \ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/dumps/index.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/dumps/index.vm new file mode 100644 index 0000000..8648ff9 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/dumps/index.vm @@ -0,0 +1,76 @@ +##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. +#set($layout = "/templates/sysinfo/layout/default.vm") +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
#springMessageText("property.name", "property.name"):  #springMessageText("property.count", "property.count")
+ #springMessageText("noProvider", "noProvider") + + #springMessageText( + "property.count","property.count") + ($noProviderServices.size()) +
+ #springMessageText("services", "services") + + #springMessageText( + "property.count","property.count") + ($services.size()) +
+ #springMessageText("providers", "providers") + + #springMessageText( + "property.count","property.count") + ($providers.size()) +
+ #springMessageText("consumers", "consumers") + + #springMessageText( + "property.count","property.count") + ($consumers.size()) +
+ #springMessageText("versions", "versions") + + #set ($client=$providers.size()+$consumers.size()) + #springMessageText( + "property.count","property.count")($client) +
\ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/envs/index.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/envs/index.vm new file mode 100644 index 0000000..fb78d32 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/envs/index.vm @@ -0,0 +1,35 @@ +##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. +#set($layout = "/templates/sysinfo/layout/default.vm") +
+
+
+ + + + + + #foreach($entry in $properties.entrySet()) + + + + + #end +
#springMessageText("property.name", "property.name"):  #springMessageText("property.value", "property.value"):  
#springMessageText($entry.key, $entry.key)$entry.value
\ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/logs/index.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/logs/index.vm new file mode 100644 index 0000000..4a00104 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/logs/index.vm @@ -0,0 +1,55 @@ +##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. +#set($layout = "/templates/sysinfo/layout/default.vm") +
+ #if($currentUser.role == "R") + + + #springMessageText("change.log.level", "change.log.level") + + #end +
+
+ + + + + + + + + #if($paginatorBar) + + #end + +
+ #springMessageText("logs.file", "logs.file"): $name (#springMessageText("logs.size", "logs.size"): $size / #springMessageText( + "logs.modify","logs.modify"): $modified) #springMessageText("logs.level", "logs.level"): $level + :   +
$tool.unescape($!content.replaceAll("\n", "
"))
+ $tool.unescape($!paginatorBar) +
\ No newline at end of file diff --git a/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/redirect.vm b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/redirect.vm new file mode 100644 index 0000000..f9352f8 --- /dev/null +++ b/52.Dubbo-OPS-Mointor/dubbo-admin/src/main/resources/templates/sysinfo/screen/redirect.vm @@ -0,0 +1,71 @@ +##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. +