Browse Source

Add init parameter to support unifying web context name in Sentinel Web CommonFilter (#1111)

master
于玉桔 Eric Zhao 5 years ago
parent
commit
f0e3348caf
6 changed files with 227 additions and 2 deletions
  1. +10
    -1
      sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java
  2. +16
    -1
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java
  3. +100
    -0
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/CommonFilterContextTest.java
  4. +40
    -0
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/FilterContextConfig.java
  5. +30
    -0
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/TestContextApplication.java
  6. +31
    -0
      sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/TestContextController.java

+ 10
- 1
sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilter.java View File

@@ -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) {


+ 16
- 1
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servlet/CommonFilterTest.java View File

@@ -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.


+ 100
- 0
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/CommonFilterContextTest.java View File

@@ -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();
}
}

+ 40
- 0
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/FilterContextConfig.java View File

@@ -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;
}
}

+ 30
- 0
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/TestContextApplication.java View File

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

+ 31
- 0
sentinel-adapter/sentinel-web-servlet/src/test/java/com/alibaba/csp/sentinel/adapter/servletcontext/TestContextController.java View File

@@ -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…
Cancel
Save