⬆️ up sentinel 1.8.4
This commit is contained in:
1 parent
20f285d3a4
commit
7a963542cd
107 files changed
+430
-203
No files matched your search
@@ -42,6 +42,7 @@
|
||||
<javaformat.plugin.version>0.0.23</javaformat.plugin.version>
|
||||
<docker.plugin.version>0.33.0</docker.plugin.version>
|
||||
<cloud.plugin.version>1.0.0</cloud.plugin.version>
|
||||
<sentinel.version>1.8.4</sentinel.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -287,6 +288,41 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-web-servlet</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-transport-simple-http</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-parameter-flow-control</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-api-gateway-adapter-common</artifactId>
|
||||
<version>${sentinel.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
+8
-2
@@ -22,11 +22,13 @@ import com.amazonaws.services.s3.model.S3Object;
|
||||
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||
import com.pig4cloud.pigx.common.oss.service.OssTemplate;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Cleanup;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -84,7 +86,9 @@ public class OssEndpoint {
|
||||
@PostMapping("/object/{bucketName}")
|
||||
public S3Object createObject(@RequestBody MultipartFile object, @PathVariable String bucketName) {
|
||||
String name = object.getOriginalFilename();
|
||||
template.putObject(bucketName, name, object.getInputStream(), object.getSize(), object.getContentType());
|
||||
@Cleanup
|
||||
InputStream inputStream = object.getInputStream();
|
||||
template.putObject(bucketName, name, inputStream, object.getSize(), object.getContentType());
|
||||
return template.getObjectInfo(bucketName, name);
|
||||
|
||||
}
|
||||
@@ -93,7 +97,9 @@ public class OssEndpoint {
|
||||
@PostMapping("/object/{bucketName}/{objectName}")
|
||||
public S3Object createObject(@RequestBody MultipartFile object, @PathVariable String bucketName,
|
||||
@PathVariable String objectName) {
|
||||
template.putObject(bucketName, objectName, object.getInputStream(), object.getSize(), object.getContentType());
|
||||
@Cleanup
|
||||
InputStream inputStream = object.getInputStream();
|
||||
template.putObject(bucketName, objectName, inputStream, object.getSize(), object.getContentType());
|
||||
return template.getObjectInfo(bucketName, objectName);
|
||||
|
||||
}
|
||||
|
||||
Executable → Regular
File mode changed.
+1
-1
@@ -16,7 +16,7 @@
|
||||
package com.alibaba.csp.sentinel.dashboard.auth;
|
||||
|
||||
/**
|
||||
* Interface for authentication and authorization.
|
||||
* Interface for authentication and authorization. 不需要改
|
||||
*
|
||||
* @author Carpenter Lee
|
||||
* @since 1.5.0
|
||||
|
||||
+3
-47
@@ -15,59 +15,15 @@
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.auth;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* The web interceptor for privilege-based authorization.
|
||||
* The web interceptor for privilege-based authorization. 不需要改
|
||||
*
|
||||
* @author lkxiaolou
|
||||
* @author wxq
|
||||
* @since 1.7.1
|
||||
*/
|
||||
@Component
|
||||
public class AuthorizationInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
|
||||
Method method = ((HandlerMethod) handler).getMethod();
|
||||
|
||||
AuthAction authAction = method.getAnnotation(AuthAction.class);
|
||||
if (authAction != null) {
|
||||
AuthService.AuthUser authUser = authService.getAuthUser(request);
|
||||
if (authUser == null) {
|
||||
responseNoPrivilegeMsg(response, authAction.message());
|
||||
return false;
|
||||
}
|
||||
String target = request.getParameter(authAction.targetName());
|
||||
|
||||
if (!authUser.authTarget(target, authAction.value())) {
|
||||
responseNoPrivilegeMsg(response, authAction.message());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void responseNoPrivilegeMsg(HttpServletResponse response, String message) throws IOException {
|
||||
Result result = Result.ofFail(-1, message);
|
||||
response.addHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
response.getOutputStream().write(JSON.toJSONBytes(result));
|
||||
}
|
||||
public interface AuthorizationInterceptor extends HandlerInterceptor {
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.auth;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* The web interceptor for privilege-based authorization. 不需要
|
||||
* <p>
|
||||
* move from old {@link AuthorizationInterceptor}.
|
||||
*
|
||||
* @author lkxiaolou
|
||||
* @author wxq
|
||||
* @since 1.7.1
|
||||
*/
|
||||
public class DefaultAuthorizationInterceptor implements AuthorizationInterceptor {
|
||||
|
||||
private final AuthService<HttpServletRequest> authService;
|
||||
|
||||
public DefaultAuthorizationInterceptor(AuthService<HttpServletRequest> authService) {
|
||||
this.authService = authService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
|
||||
Method method = ((HandlerMethod) handler).getMethod();
|
||||
|
||||
AuthAction authAction = method.getAnnotation(AuthAction.class);
|
||||
if (authAction != null) {
|
||||
AuthService.AuthUser authUser = authService.getAuthUser(request);
|
||||
if (authUser == null) {
|
||||
responseNoPrivilegeMsg(response, authAction.message());
|
||||
return false;
|
||||
}
|
||||
String target = request.getParameter(authAction.targetName());
|
||||
|
||||
if (!authUser.authTarget(target, authAction.value())) {
|
||||
responseNoPrivilegeMsg(response, authAction.message());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void responseNoPrivilegeMsg(HttpServletResponse response, String message) throws IOException {
|
||||
Result result = Result.ofFail(-1, message);
|
||||
response.addHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
response.getOutputStream().write(JSON.toJSONBytes(result));
|
||||
}
|
||||
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.auth;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The Servlet filter for authentication.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note: some urls are excluded as they needn't auth, such as:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>index url: {@code /}</li>
|
||||
* <li>authentication request url: {@code /login}, {@code /logout}</li>
|
||||
* <li>machine registry: {@code /registry/machine}</li>
|
||||
* <li>static resources</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The excluded urls and urlSuffixes could be configured in {@code application.properties}
|
||||
* file.
|
||||
*
|
||||
* @author cdfive 不需要
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public class DefaultLoginAuthenticationFilter implements LoginAuthenticationFilter {
|
||||
|
||||
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
|
||||
|
||||
private static final String URL_SUFFIX_DOT = ".";
|
||||
|
||||
/**
|
||||
* 忽略鉴权的url
|
||||
*/
|
||||
@Value("#{'${auth.filter.exclude-urls}'.split(',')}")
|
||||
private List<String> authFilterExcludeUrls;
|
||||
|
||||
/**
|
||||
* 根据后缀不需要鉴权的url
|
||||
*/
|
||||
@Value("#{'${auth.filter.exclude-url-suffixes}'.split(',')}")
|
||||
private List<String> authFilterExcludeUrlSuffixes;
|
||||
|
||||
/**
|
||||
* Authentication using AuthService interface.
|
||||
*/
|
||||
private final AuthService<HttpServletRequest> authService;
|
||||
|
||||
public DefaultLoginAuthenticationFilter(AuthService<HttpServletRequest> authService) {
|
||||
this.authService = authService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
|
||||
String servletPath = httpRequest.getServletPath();
|
||||
|
||||
// Exclude the urls which needn't auth
|
||||
boolean authFilterExcludeMatch = authFilterExcludeUrls.stream()
|
||||
.anyMatch(authFilterExcludeUrl -> PATH_MATCHER.match(authFilterExcludeUrl, servletPath));
|
||||
if (authFilterExcludeMatch) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Exclude the urls with suffixes which needn't auth
|
||||
for (String authFilterExcludeUrlSuffix : authFilterExcludeUrlSuffixes) {
|
||||
if (StringUtils.isBlank(authFilterExcludeUrlSuffix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add . for url suffix so that we needn't add . in property file
|
||||
if (!authFilterExcludeUrlSuffix.startsWith(URL_SUFFIX_DOT)) {
|
||||
authFilterExcludeUrlSuffix = URL_SUFFIX_DOT + authFilterExcludeUrlSuffix;
|
||||
}
|
||||
|
||||
if (servletPath.endsWith(authFilterExcludeUrlSuffix)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AuthService.AuthUser authUser = authService.getAuthUser(httpRequest);
|
||||
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
if (authUser == null) {
|
||||
// If auth fail, set response status code to 401
|
||||
httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
}
|
||||
else {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+8
-2
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.auth;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@@ -25,9 +26,14 @@ import javax.servlet.http.HttpServletRequest;
|
||||
* @author Carpenter Lee
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@Component
|
||||
public class FakeAuthServiceImpl implements AuthService<HttpServletRequest> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
public FakeAuthServiceImpl() {
|
||||
this.logger.warn("there is no auth, use {} by implementation {}", AuthService.class, this.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthUser getAuthUser(HttpServletRequest request) {
|
||||
return new AuthUserImpl();
|
||||
|
||||
+5
-94
@@ -15,18 +15,7 @@
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.auth;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.servlet.Filter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -42,92 +31,14 @@ import java.util.List;
|
||||
* <li>machine registry: {@code /registry/machine}</li>
|
||||
* <li>static resources</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* The excluded urls and urlSuffixes could be configured in {@code application.properties}
|
||||
* file.
|
||||
*
|
||||
* @author cdfive
|
||||
* @author cdfive 不需要
|
||||
* @author wxq
|
||||
* @since 1.6.0
|
||||
*/
|
||||
@Component
|
||||
public class LoginAuthenticationFilter implements Filter {
|
||||
|
||||
private static final String URL_SUFFIX_DOT = ".";
|
||||
|
||||
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
|
||||
|
||||
/**
|
||||
* Some urls which needn't auth, such as /auth/login, /registry/machine and so on.
|
||||
*/
|
||||
@Value("#{'${auth.filter.exclude-urls}'.split(',')}")
|
||||
private List<String> authFilterExcludeUrls;
|
||||
|
||||
/**
|
||||
* Some urls with suffixes which needn't auth, such as htm, html, js and so on.
|
||||
*/
|
||||
@Value("#{'${auth.filter.exclude-url-suffixes}'.split(',')}")
|
||||
private List<String> authFilterExcludeUrlSuffixes;
|
||||
|
||||
/**
|
||||
* Authentication using AuthService interface.
|
||||
*/
|
||||
@Autowired
|
||||
private AuthService<HttpServletRequest> authService;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
|
||||
String servletPath = httpRequest.getServletPath();
|
||||
|
||||
// Exclude the urls which needn't auth
|
||||
if (authFilterExcludeUrls.stream().anyMatch(s -> PATH_MATCHER.match(s, servletPath))) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
if (authFilterExcludeUrls.contains(servletPath)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Exclude the urls with suffixes which needn't auth
|
||||
for (String authFilterExcludeUrlSuffix : authFilterExcludeUrlSuffixes) {
|
||||
if (StringUtils.isBlank(authFilterExcludeUrlSuffix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add . for url suffix so that we needn't add . in property file
|
||||
if (!authFilterExcludeUrlSuffix.startsWith(URL_SUFFIX_DOT)) {
|
||||
authFilterExcludeUrlSuffix = URL_SUFFIX_DOT + authFilterExcludeUrlSuffix;
|
||||
}
|
||||
|
||||
if (servletPath.endsWith(authFilterExcludeUrlSuffix)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AuthService.AuthUser authUser = authService.getAuthUser(httpRequest);
|
||||
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
if (authUser == null) {
|
||||
// If auth fail, set response status code to 401
|
||||
httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
}
|
||||
else {
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
public interface LoginAuthenticationFilter extends Filter {
|
||||
|
||||
}
|
||||
+1
-8
@@ -15,20 +15,13 @@
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.auth;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* @author cdfive
|
||||
* @author cdfive 不需要
|
||||
* @since 1.6.0
|
||||
*/
|
||||
@Component
|
||||
@Primary
|
||||
@ConditionalOnProperty(name = "auth.enabled", matchIfMissing = true)
|
||||
public class SimpleWebAuthServiceImpl implements AuthService<HttpServletRequest> {
|
||||
|
||||
public static final String WEB_SESSION_KEY = "session_sentinel_admin";
|
||||
|
||||
Executable → Regular
+3
-3
@@ -171,8 +171,8 @@ public class SentinelApiClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check wheter target instance (identified by tuple of app-ip:port) supports the form
|
||||
* of "xxxxx; xx=xx" in "Content-Type" header.
|
||||
* Check whether target instance (identified by tuple of app-ip:port) supports the
|
||||
* form of "xxxxx; xx=xx" in "Content-Type" header.
|
||||
* @param app target app name
|
||||
* @param ip target node's address
|
||||
* @param port target node's port
|
||||
@@ -520,7 +520,7 @@ public class SentinelApiClient {
|
||||
AssertUtil.notEmpty(ip, "Bad machine IP");
|
||||
AssertUtil.isTrue(port > 0, "Bad machine port");
|
||||
return fetchItemsAsync(ip, port, GET_PARAM_RULE_PATH, null, ParamFlowRule.class)
|
||||
.thenApply(rules -> rules.stream().map(e -> ParamFlowRuleEntity.fromAuthorityRule(app, ip, port, e))
|
||||
.thenApply(rules -> rules.stream().map(e -> ParamFlowRuleEntity.fromParamFlowRule(app, ip, port, e))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.config;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.*;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(AuthProperties.class)
|
||||
public class AuthConfiguration {
|
||||
|
||||
private final AuthProperties authProperties;
|
||||
|
||||
public AuthConfiguration(AuthProperties authProperties) {
|
||||
this.authProperties = authProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AuthService<HttpServletRequest> httpServletRequestAuthService() {
|
||||
if (this.authProperties.isEnabled()) {
|
||||
return new SimpleWebAuthServiceImpl();
|
||||
}
|
||||
return new FakeAuthServiceImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public LoginAuthenticationFilter loginAuthenticationFilter(
|
||||
AuthService<HttpServletRequest> httpServletRequestAuthService) {
|
||||
return new DefaultLoginAuthenticationFilter(httpServletRequestAuthService);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AuthorizationInterceptor authorizationInterceptor(
|
||||
AuthService<HttpServletRequest> httpServletRequestAuthService) {
|
||||
return new DefaultAuthorizationInterceptor(httpServletRequestAuthService);
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.csp.sentinel.dashboard.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "auth")
|
||||
public class AuthProperties {
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
+16
-9
@@ -16,7 +16,6 @@
|
||||
package com.alibaba.csp.sentinel.dashboard.controller;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
|
||||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineDiscovery;
|
||||
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
@@ -28,6 +27,7 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = "/registry", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@@ -43,20 +43,27 @@ public class MachineRegistryController {
|
||||
public Result<?> receiveHeartBeat(String app,
|
||||
@RequestParam(value = "app_type", required = false, defaultValue = "0") Integer appType, Long version,
|
||||
String v, String hostname, String ip, Integer port) {
|
||||
if (app == null) {
|
||||
app = MachineDiscovery.UNKNOWN_APP_NAME;
|
||||
if (StringUtil.isBlank(app) || app.length() > 256) {
|
||||
return Result.ofFail(-1, "invalid appName");
|
||||
}
|
||||
if (ip == null) {
|
||||
return Result.ofFail(-1, "ip can't be null");
|
||||
if (StringUtil.isBlank(ip) || ip.length() > 128) {
|
||||
return Result.ofFail(-1, "invalid ip: " + ip);
|
||||
}
|
||||
if (port == null) {
|
||||
return Result.ofFail(-1, "port can't be null");
|
||||
if (!IPAddressUtil.isIPv4LiteralAddress(ip) && !IPAddressUtil.isIPv6LiteralAddress(ip)) {
|
||||
return Result.ofFail(-1, "invalid ip: " + ip);
|
||||
}
|
||||
if (port == null || port < -1) {
|
||||
return Result.ofFail(-1, "invalid port");
|
||||
}
|
||||
if (hostname != null && hostname.length() > 256) {
|
||||
return Result.ofFail(-1, "hostname too long");
|
||||
}
|
||||
if (port == -1) {
|
||||
logger.info("Receive heartbeat from " + ip + " but port not set yet");
|
||||
logger.warn("Receive heartbeat from " + ip + " but port not set yet");
|
||||
return Result.ofFail(-1, "your port not set yet");
|
||||
}
|
||||
String sentinelVersion = StringUtil.isEmpty(v) ? "unknown" : v;
|
||||
String sentinelVersion = StringUtil.isBlank(v) ? "unknown" : v;
|
||||
|
||||
version = version == null ? System.currentTimeMillis() : version;
|
||||
try {
|
||||
MachineInfo machineInfo = new MachineInfo();
|
||||
|
||||
Executable → Regular
File mode changed.
+2
-3
@@ -16,7 +16,6 @@
|
||||
package com.alibaba.csp.sentinel.dashboard.controller;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.dashboard.client.CommandNotFoundException;
|
||||
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
|
||||
@@ -111,7 +110,7 @@ public class ParamFlowRuleController {
|
||||
}
|
||||
|
||||
@PostMapping("/rule")
|
||||
@AuthAction(AuthService.PrivilegeType.WRITE_RULE)
|
||||
@AuthAction(PrivilegeType.WRITE_RULE)
|
||||
public Result<ParamFlowRuleEntity> apiAddParamFlowRule(@RequestBody ParamFlowRuleEntity entity) {
|
||||
Result<ParamFlowRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
if (checkResult != null) {
|
||||
@@ -183,7 +182,7 @@ public class ParamFlowRuleController {
|
||||
}
|
||||
|
||||
@PutMapping("/rule/{id}")
|
||||
@AuthAction(AuthService.PrivilegeType.WRITE_RULE)
|
||||
@AuthAction(PrivilegeType.WRITE_RULE)
|
||||
public Result<ParamFlowRuleEntity> apiUpdateParamFlowRule(@PathVariable("id") Long id,
|
||||
@RequestBody ParamFlowRuleEntity entity) {
|
||||
if (id == null || id <= 0) {
|
||||
|
||||
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
+2
-3
@@ -16,7 +16,6 @@
|
||||
package com.alibaba.csp.sentinel.dashboard.controller.v2;
|
||||
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService;
|
||||
import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
|
||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
||||
import com.alibaba.csp.sentinel.dashboard.domain.Result;
|
||||
@@ -127,7 +126,7 @@ public class FlowControllerV2 {
|
||||
}
|
||||
|
||||
@PostMapping("/rule")
|
||||
@AuthAction(value = AuthService.PrivilegeType.WRITE_RULE)
|
||||
@AuthAction(value = PrivilegeType.WRITE_RULE)
|
||||
public Result<FlowRuleEntity> apiAddFlowRule(@RequestBody FlowRuleEntity entity) {
|
||||
|
||||
Result<FlowRuleEntity> checkResult = checkEntityInternal(entity);
|
||||
@@ -152,7 +151,7 @@ public class FlowControllerV2 {
|
||||
}
|
||||
|
||||
@PutMapping("/rule/{id}")
|
||||
@AuthAction(AuthService.PrivilegeType.WRITE_RULE)
|
||||
@AuthAction(PrivilegeType.WRITE_RULE)
|
||||
|
||||
public Result<FlowRuleEntity> apiUpdateFlowRule(@PathVariable("id") Long id, @RequestBody FlowRuleEntity entity) {
|
||||
if (id == null || id <= 0) {
|
||||
|
||||
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
+1
-1
@@ -38,7 +38,7 @@ public class ParamFlowRuleEntity extends AbstractRuleEntity<ParamFlowRule> {
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
public static ParamFlowRuleEntity fromAuthorityRule(String app, String ip, Integer port, ParamFlowRule rule) {
|
||||
public static ParamFlowRuleEntity fromParamFlowRule(String app, String ip, Integer port, ParamFlowRule rule) {
|
||||
ParamFlowRuleEntity entity = new ParamFlowRuleEntity(rule);
|
||||
entity.setApp(app);
|
||||
entity.setIp(ip);
|
||||
|
||||
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
+13
@@ -23,8 +23,21 @@ package com.alibaba.csp.sentinel.dashboard.domain.vo.gateway.api;
|
||||
*/
|
||||
public class ApiPredicateItemVo {
|
||||
|
||||
/**
|
||||
* The pattern for matching url.
|
||||
*/
|
||||
private String pattern;
|
||||
|
||||
/**
|
||||
* The matching Strategy in url. Constants are defined in class
|
||||
* SentinelGatewayConstants.\
|
||||
*
|
||||
* <ul>
|
||||
* <li>0(URL_MATCH_STRATEGY_EXACT): exact match mode</li>
|
||||
* <li>1(URL_MATCH_STRATEGY_PREFIX): prefix match mode</li>
|
||||
* <li>2(URL_MATCH_STRATEGY_REGEX): regex match mode</li>
|
||||
* </ul>
|
||||
*/
|
||||
private Integer matchStrategy;
|
||||
|
||||
public String getPattern() {
|
||||
|
||||
Executable → Regular
+25
-27
@@ -84,7 +84,7 @@ public class MetricFetcher {
|
||||
|
||||
@SuppressWarnings("PMD.ThreadPoolCreationRule")
|
||||
private ScheduledExecutorService fetchScheduleService = Executors.newScheduledThreadPool(1,
|
||||
new NamedThreadFactory("sentinel-dashboard-metrics-fetch-task"));
|
||||
new NamedThreadFactory("sentinel-dashboard-metrics-fetch-task", true));
|
||||
|
||||
private ExecutorService fetchService;
|
||||
|
||||
@@ -96,11 +96,11 @@ public class MetricFetcher {
|
||||
int queueSize = 2048;
|
||||
RejectedExecutionHandler handler = new DiscardPolicy();
|
||||
fetchService = new ThreadPoolExecutor(cores, cores, keepAliveTime, TimeUnit.MILLISECONDS,
|
||||
new ArrayBlockingQueue<>(queueSize), new NamedThreadFactory("sentinel-dashboard-metrics-fetchService"),
|
||||
handler);
|
||||
new ArrayBlockingQueue<>(queueSize),
|
||||
new NamedThreadFactory("sentinel-dashboard-metrics-fetchService", true), handler);
|
||||
fetchWorker = new ThreadPoolExecutor(cores, cores, keepAliveTime, TimeUnit.MILLISECONDS,
|
||||
new ArrayBlockingQueue<>(queueSize), new NamedThreadFactory("sentinel-dashboard-metrics-fetchWorker"),
|
||||
handler);
|
||||
new ArrayBlockingQueue<>(queueSize),
|
||||
new NamedThreadFactory("sentinel-dashboard-metrics-fetchWorker", true), handler);
|
||||
IOReactorConfig ioConfig = IOReactorConfig.custom().setConnectTimeout(3000).setSoTimeout(3000)
|
||||
.setIoThreadCount(Runtime.getRuntime().availableProcessors() * 2).build();
|
||||
|
||||
@@ -249,7 +249,7 @@ public class MetricFetcher {
|
||||
catch (Exception e) {
|
||||
logger.info(msg + " metric, wait http client error:", e);
|
||||
}
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
// long cost = System.currentTimeMillis() - start;
|
||||
// logger.info("finished " + msg + " metric for " + app + ", time intervalMs [" +
|
||||
// startTime + ", " + endTime
|
||||
// + "], total machines=" + machines.size() + ", dead=" + dead + ", fetch
|
||||
@@ -268,7 +268,7 @@ public class MetricFetcher {
|
||||
lastFetchMs = lastFetchMs / 1000 * 1000;
|
||||
long endTime = lastFetchMs + FETCH_INTERVAL_SECOND * 1000;
|
||||
if (endTime > now - 1000 * 2) {
|
||||
// to near
|
||||
// too near
|
||||
return;
|
||||
}
|
||||
// update last_fetch in advance.
|
||||
@@ -336,26 +336,24 @@ public class MetricFetcher {
|
||||
* aggregation metrics by app_resource_timeSecond, ignore ip and port.
|
||||
*/
|
||||
String key = buildMetricKey(machine.getApp(), node.getResource(), node.getTimestamp());
|
||||
MetricEntity entity = map.get(key);
|
||||
if (entity != null) {
|
||||
entity.addPassQps(node.getPassQps());
|
||||
entity.addBlockQps(node.getBlockQps());
|
||||
entity.addRtAndSuccessQps(node.getRt(), node.getSuccessQps());
|
||||
entity.addExceptionQps(node.getExceptionQps());
|
||||
entity.addCount(1);
|
||||
}
|
||||
else {
|
||||
entity = new MetricEntity();
|
||||
entity.setApp(machine.getApp());
|
||||
entity.setTimestamp(new Date(node.getTimestamp()));
|
||||
entity.setPassQps(node.getPassQps());
|
||||
entity.setBlockQps(node.getBlockQps());
|
||||
entity.setRtAndSuccessQps(node.getRt(), node.getSuccessQps());
|
||||
entity.setExceptionQps(node.getExceptionQps());
|
||||
entity.setCount(1);
|
||||
entity.setResource(node.getResource());
|
||||
map.put(key, entity);
|
||||
}
|
||||
|
||||
MetricEntity metricEntity = map.computeIfAbsent(key, s -> {
|
||||
MetricEntity initMetricEntity = new MetricEntity();
|
||||
initMetricEntity.setApp(machine.getApp());
|
||||
initMetricEntity.setTimestamp(new Date(node.getTimestamp()));
|
||||
initMetricEntity.setPassQps(0L);
|
||||
initMetricEntity.setBlockQps(0L);
|
||||
initMetricEntity.setRtAndSuccessQps(0, 0L);
|
||||
initMetricEntity.setExceptionQps(0L);
|
||||
initMetricEntity.setCount(0);
|
||||
initMetricEntity.setResource(node.getResource());
|
||||
return initMetricEntity;
|
||||
});
|
||||
metricEntity.addPassQps(node.getPassQps());
|
||||
metricEntity.addBlockQps(node.getBlockQps());
|
||||
metricEntity.addRtAndSuccessQps(node.getRt(), node.getSuccessQps());
|
||||
metricEntity.addExceptionQps(node.getExceptionQps());
|
||||
metricEntity.addCount(1);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.warn("handleBody line exception, machine: {}, line: {}", machine.toLogString(), line);
|
||||
|
||||
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
+4
-3
@@ -107,7 +107,8 @@ public final class ClusterEntityUtils {
|
||||
if (mode == ClusterStateManager.CLUSTER_SERVER) {
|
||||
String serverAddress = getIp(ip);
|
||||
int port = stateVO.getState().getServer().getPort();
|
||||
map.computeIfAbsent(serverAddress, v -> new ClusterGroupEntity().setBelongToApp(true)
|
||||
String targetAddress = serverAddress + ":" + port;
|
||||
map.computeIfAbsent(targetAddress, v -> new ClusterGroupEntity().setBelongToApp(true)
|
||||
.setMachineId(ip + '@' + stateVO.getCommandPort()).setIp(ip).setPort(port));
|
||||
}
|
||||
}
|
||||
@@ -120,8 +121,8 @@ public final class ClusterEntityUtils {
|
||||
if (StringUtil.isBlank(targetServer) || targetPort == null || targetPort <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ClusterGroupEntity group = map.computeIfAbsent(targetServer, v -> new ClusterGroupEntity()
|
||||
String targetAddress = targetServer + ":" + targetPort;
|
||||
ClusterGroupEntity group = map.computeIfAbsent(targetAddress, v -> new ClusterGroupEntity()
|
||||
.setBelongToApp(true).setMachineId(targetServer).setIp(targetServer).setPort(targetPort));
|
||||
group.getClientSet().add(ip + '@' + stateVO.getCommandPort());
|
||||
}
|
||||
|
||||
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Executable → Regular
File mode changed.
Vendored
Executable → Regular
File mode changed.
Loaded 100 of 107 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user