Add init parameter to support unifying web context name in Sentinel Web CommonFilter (#1111)
This commit is contained in:
parent
b05502f8c2
commit
f0e3348caf
|
|
@ -42,18 +42,27 @@ import com.alibaba.csp.sentinel.util.StringUtil;
|
|||
/***
|
||||
* Servlet filter that integrates with Sentinel.
|
||||
*
|
||||
* @author zhaoyuguang
|
||||
* @author youji.zj
|
||||
* @author Eric Zhao
|
||||
*/
|
||||
public class CommonFilter implements Filter {
|
||||
|
||||
private final static String HTTP_METHOD_SPECIFY = "HTTP_METHOD_SPECIFY";
|
||||
/**
|
||||
* Use the path of the url as the context, if necessary, but pay attention to the number of context EntranceNode
|
||||
*/
|
||||
public final static String WEB_CONTEXT_UNIFY = "WEB_CONTEXT_UNIFY";
|
||||
private final static String COLON = ":";
|
||||
private boolean httpMethodSpecify = false;
|
||||
private boolean webContextUnify = true;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) {
|
||||
httpMethodSpecify = Boolean.parseBoolean(filterConfig.getInitParameter(HTTP_METHOD_SPECIFY));
|
||||
if (filterConfig.getInitParameter(WEB_CONTEXT_UNIFY) != null) {
|
||||
webContextUnify = Boolean.parseBoolean(filterConfig.getInitParameter(WEB_CONTEXT_UNIFY));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -78,7 +87,7 @@ public class CommonFilter implements Filter {
|
|||
if (!StringUtil.isEmpty(target)) {
|
||||
// Parse the request origin using registered origin parser.
|
||||
String origin = parseOrigin(sRequest);
|
||||
ContextUtil.enter(WebServletConfig.WEB_SERVLET_CONTEXT_NAME, origin);
|
||||
ContextUtil.enter(webContextUnify ? WebServletConfig.WEB_SERVLET_CONTEXT_NAME : target, origin);
|
||||
urlEntry = SphU.entry(target, EntryType.IN);
|
||||
// Add method specification if necessary
|
||||
if (httpMethodSpecify) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import java.util.Collections;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.alibaba.csp.sentinel.Constants;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.DefaultUrlCleaner;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlCleaner;
|
||||
|
|
@ -26,6 +27,8 @@ import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
|
|||
import com.alibaba.csp.sentinel.adapter.servlet.config.WebServletConfig;
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.util.FilterUtil;
|
||||
import com.alibaba.csp.sentinel.node.ClusterNode;
|
||||
import com.alibaba.csp.sentinel.node.EntranceNode;
|
||||
import com.alibaba.csp.sentinel.node.Node;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
|
||||
|
|
@ -43,7 +46,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
/**
|
||||
|
|
@ -76,6 +79,7 @@ public class CommonFilterTest {
|
|||
|
||||
@Test
|
||||
public void testCommonFilterMiscellaneous() throws Exception {
|
||||
Constants.ROOT.removeChildList();
|
||||
String url = "/hello";
|
||||
this.mvc.perform(get(url))
|
||||
.andExpect(status().isOk())
|
||||
|
|
@ -85,6 +89,17 @@ public class CommonFilterTest {
|
|||
assertNotNull(cn);
|
||||
assertEquals(1, cn.passQps(), 0.01);
|
||||
|
||||
String context = "";
|
||||
for (Node n : Constants.ROOT.getChildList()) {
|
||||
if (n instanceof EntranceNode) {
|
||||
String id = ((EntranceNode) n).getId().getName();
|
||||
if (url.equals(id)) {
|
||||
context = ((EntranceNode) n).getId().getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
assertEquals("", context);
|
||||
|
||||
testCommonBlockAndRedirectBlockPage(url, cn);
|
||||
|
||||
// Test for url cleaner.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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.adapter.servletcontext;
|
||||
|
||||
import com.alibaba.csp.sentinel.Constants;
|
||||
import com.alibaba.csp.sentinel.node.ClusterNode;
|
||||
import com.alibaba.csp.sentinel.node.EntranceNode;
|
||||
import com.alibaba.csp.sentinel.node.Node;
|
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
|
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
|
||||
import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* @author zhaoyuguang
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = TestContextApplication.class,
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@AutoConfigureMockMvc
|
||||
public class CommonFilterContextTest {
|
||||
|
||||
private static final String HELLO_STR = "Hello!";
|
||||
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
|
||||
private void configureRulesFor(String resource, int count) {
|
||||
configureRulesFor(resource, count, "default");
|
||||
}
|
||||
|
||||
private void configureRulesFor(String resource, int count, String limitApp) {
|
||||
FlowRule rule = new FlowRule()
|
||||
.setCount(count)
|
||||
.setGrade(RuleConstant.FLOW_GRADE_QPS);
|
||||
rule.setResource(resource);
|
||||
if (StringUtil.isNotBlank(limitApp)) {
|
||||
rule.setLimitApp(limitApp);
|
||||
}
|
||||
FlowRuleManager.loadRules(Collections.singletonList(rule));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommonFilterMiscellaneous() throws Exception {
|
||||
String url = "/hello";
|
||||
this.mvc.perform(get(url))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(HELLO_STR));
|
||||
|
||||
ClusterNode cn = ClusterBuilderSlot.getClusterNode(url);
|
||||
assertNotNull(cn);
|
||||
assertEquals(1, cn.passQps(), 0.01);
|
||||
String context = "";
|
||||
for (Node n : Constants.ROOT.getChildList()) {
|
||||
if (n instanceof EntranceNode) {
|
||||
String id = ((EntranceNode) n).getId().getName();
|
||||
if (url.equals(id)) {
|
||||
context = ((EntranceNode) n).getId().getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
assertEquals(url, context);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
FlowRuleManager.loadRules(null);
|
||||
ClusterBuilderSlot.resetClusterNodes();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.adapter.servletcontext;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author zhaoyuguang
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterContextConfig {
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean sentinelFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setFilter(new CommonFilter());
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
|
||||
registration.setName("sentinelFilter");
|
||||
registration.setOrder(1);
|
||||
|
||||
return registration;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.adapter.servletcontext;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author zhaoyuguang
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class TestContextApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TestContextApplication.class, args);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.adapter.servletcontext;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author zhaoyuguang
|
||||
*/
|
||||
@RestController
|
||||
public class TestContextController {
|
||||
|
||||
@GetMapping("/hello")
|
||||
public String apiHello() {
|
||||
return "Hello!";
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue