#502 Add distro annotation

This commit is contained in:
nkorange 2019-02-21 17:32:43 +08:00
parent 918dcf9905
commit 091e2e0cde
3 changed files with 134 additions and 65 deletions

View File

@ -44,8 +44,8 @@ public class AuthFilter implements Filter {
@Autowired
private SwitchDomain switchDomain;
private static ConcurrentMap<String, Method> methodCache = new
ConcurrentHashMap<String, Method>();
@Autowired
private FilterBase filterBase;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
@ -61,13 +61,10 @@ public class AuthFilter implements Filter {
try {
String path = new URI(req.getRequestURI()).getPath();
String target = getMethodName(path);
Method method = methodCache.get(target);
Method method = filterBase.getMethod(req.getMethod(), path);
if (method == null) {
method = mapClass(path).getMethod(target, HttpServletRequest.class, HttpServletResponse.class);
methodCache.put(target, method);
throw new NoSuchMethodException();
}
if (method.isAnnotationPresent(NeedAuth.class) && !switchDomain.isEnableAuthentication()) {
@ -97,52 +94,4 @@ public class AuthFilter implements Filter {
public void destroy() {
}
private Class<?> mapClass(String path) throws NacosException {
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_INSTANCE_CONTEXT)) {
return InstanceController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_SERVICE_CONTEXT)) {
return ServiceController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_CLUSTER_CONTEXT)) {
return ClusterController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_OPERATOR_CONTEXT)) {
return OperatorController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_CATALOG_CONTEXT)) {
return CatalogController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_HEALTH_CONTEXT)) {
return HealthController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_RAFT_CONTEXT)) {
return RaftController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_PARTITION_CONTEXT)) {
return PartitionController.class;
}
throw new NacosException(NacosException.NOT_FOUND, "no matched controller found!");
}
static protected String getMethodName(String path) throws Exception {
String target = path.substring(path.lastIndexOf("/") + 1).trim();
if (StringUtils.isEmpty(target)) {
throw new IllegalArgumentException("URL target required");
}
return target;
}
}

View File

@ -23,13 +23,14 @@ import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.security.AccessControlException;
import java.util.Map;
/**
@ -43,6 +44,9 @@ public class DistroFilter implements Filter {
@Autowired
private SwitchDomain switchDomain;
@Autowired
private FilterBase filterBase;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
@ -54,6 +58,7 @@ public class DistroFilter implements Filter {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
// request limit:
String urlString = req.getRequestURI() + "?" + req.getQueryString();
Map<String, Integer> limitedUrlMap = switchDomain.getLimitedUrlMap();
@ -68,19 +73,15 @@ public class DistroFilter implements Filter {
}
try {
String path = new URI(req.getRequestURI()).getPath();
String serviceName = req.getParameter(CommonParams.SERVICE_NAME);
Method method = filterBase.getMethod(req.getMethod(), path);
boolean isMethodWrite =
(HttpMethod.POST.name().equals(req.getMethod()) || HttpMethod.DELETE.name().equals(req.getMethod()));
boolean isUrlInstance =
path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_INSTANCE_CONTEXT);
if (isUrlInstance && isMethodWrite && !distroMapper.responsible(serviceName)) {
if (method == null) {
throw new NoSuchMethodException(req.getMethod() + " " + path);
}
if (method.isAnnotationPresent(CanDistro.class) && !distroMapper.responsible(serviceName)) {
String url = "http://" + distroMapper.mapSrv(serviceName) +
req.getRequestURI() + "?" + req.getQueryString();
try {
@ -101,10 +102,18 @@ public class DistroFilter implements Filter {
OverrideParameterRequestWrapper requestWrapper = OverrideParameterRequestWrapper.buildRequest(req);
requestWrapper.addParameter(CommonParams.SERVICE_NAME, groupName + UtilsAndCommons.GROUP_SERVICE_CONNECTOR + serviceName);
filterChain.doFilter(requestWrapper, resp);
} catch (AccessControlException e) {
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "access denied: " + UtilsAndCommons.getAllExceptionMsg(e));
return;
} catch (NoSuchMethodException e) {
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "no such api: " + e.getMessage());
return;
} catch (Exception e) {
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Server failed," + UtilsAndCommons.getAllExceptionMsg(e));
return;
}
}
@Override

View File

@ -0,0 +1,111 @@
package com.alibaba.nacos.naming.web;
import com.alibaba.nacos.naming.controllers.*;
import com.alibaba.nacos.naming.exception.NacosException;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author nkorange
* @since 1.0.0
*/
@Component
public class FilterBase {
private ConcurrentMap<String, Method> methodCache = new
ConcurrentHashMap<>();
@PostConstruct
public void init() {
initClassMethod(InstanceController.class);
initClassMethod(ServiceController.class);
initClassMethod(ClusterController.class);
initClassMethod(CatalogController.class);
initClassMethod(HealthController.class);
initClassMethod(RaftController.class);
initClassMethod(PartitionController.class);
initClassMethod(OperatorController.class);
}
public Method getMethod(String httpMethod, String path) {
String key = httpMethod + "-->" + path;
return methodCache.get(key);
}
private void initClassMethod(Class<?> clazz) {
RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
String classPath = requestMapping.value()[0];
for (Method method : clazz.getMethods()) {
requestMapping = method.getAnnotation(RequestMapping.class);
RequestMethod[] requestMethods = requestMapping.method();
if (requestMethods.length == 0) {
requestMethods = new RequestMethod[1];
requestMethods[0] = RequestMethod.GET;
}
for (String methodPath : requestMapping.value()) {
methodCache.put(requestMethods[0].name() + "-->" + classPath + methodPath, method);
}
}
}
public Class<?> mapClass(String path) throws NacosException {
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_INSTANCE_CONTEXT)) {
return InstanceController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_SERVICE_CONTEXT)) {
return ServiceController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_CLUSTER_CONTEXT)) {
return ClusterController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_OPERATOR_CONTEXT)) {
return OperatorController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_CATALOG_CONTEXT)) {
return CatalogController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_HEALTH_CONTEXT)) {
return HealthController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_RAFT_CONTEXT)) {
return RaftController.class;
}
if (path.startsWith(UtilsAndCommons.NACOS_NAMING_CONTEXT + UtilsAndCommons.NACOS_NAMING_PARTITION_CONTEXT)) {
return PartitionController.class;
}
throw new NacosException(NacosException.NOT_FOUND, "no matched controller found!");
}
public String getMethodName(String path) throws Exception {
String target = path.substring(path.lastIndexOf("/") + 1).trim();
if (StringUtils.isEmpty(target)) {
throw new IllegalArgumentException("URL target required");
}
return target;
}
public ConcurrentMap<String, Method> getMethodCache() {
return methodCache;
}
}