From bcb9b8be1106ae6c9b86051380229c446401c461 Mon Sep 17 00:00:00 2001 From: uuuyuqi Date: Tue, 28 Apr 2026 11:41:15 +0800 Subject: [PATCH 1/5] feat: add Apache HttpClient 5.x adapter for Sentinel Add sentinel-apache-httpclient5-adapter module that integrates Sentinel flow control with Apache HttpClient 5.x outgoing HTTP requests. Features: - ExecChainHandler-based integration (SentinelApacheHttpClient5Handler) - Configurable resource name extraction (METHOD:URL format by default) - Query string and fragment stripping in resource names - Customizable fallback handling (throws SentinelRpcException by default) - Configurable resource name prefix (default: "httpclient:") Follows the same architecture pattern as the existing HttpClient 4.x adapter while adapting to HC5's ExecChainHandler API. Closes #3614 Change-Id: I966295da9419beac99451fc6c9c31b1d75a9e7e6 Co-developed-by: Cursor --- sentinel-adapter/pom.xml | 1 + .../README.md | 77 ++++++++ .../pom.xml | 72 ++++++++ .../SentinelApacheHttpClient5Handler.java | 92 ++++++++++ .../SentinelApacheHttpClientConfig.java | 59 ++++++ .../ApacheHttpClientResourceExtractor.java | 34 ++++ ...aultApacheHttpClientResourceExtractor.java | 55 ++++++ .../fallback/ApacheHttpClientFallback.java | 37 ++++ .../DefaultApacheHttpClientFallback.java | 32 ++++ .../SentinelApacheHttpClientTest.java | 168 ++++++++++++++++++ .../httpclient5/app/TestApplication.java | 30 ++++ .../app/controller/TestController.java | 52 ++++++ .../SentinelApacheHttpClientConfigTest.java | 70 ++++++++ ...ApacheHttpClientResourceExtractorTest.java | 85 +++++++++ .../ApacheHttpClientFallbackTest.java | 34 ++++ 15 files changed, 898 insertions(+) create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/pom.xml create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java create mode 100644 sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java diff --git a/sentinel-adapter/pom.xml b/sentinel-adapter/pom.xml index b075b54f0f..b1b87ac0a9 100755 --- a/sentinel-adapter/pom.xml +++ b/sentinel-adapter/pom.xml @@ -21,6 +21,7 @@ sentinel-apache-dubbo-adapter sentinel-apache-dubbo3-adapter sentinel-apache-httpclient-adapter + sentinel-apache-httpclient5-adapter sentinel-sofa-rpc-adapter sentinel-grpc-adapter sentinel-zuul-adapter diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md b/sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md new file mode 100644 index 0000000000..e7770c2779 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md @@ -0,0 +1,77 @@ +# Sentinel Apache HttpClient 5.x Adapter + +## Introduction + +Sentinel provides integration for Apache HttpClient 5.x to enable flow control for outgoing HTTP requests. + +## Usage + +### Add dependency + +```xml + + com.alibaba.csp + sentinel-apache-httpclient5-adapter + x.y.z + +``` + +### Build the HttpClient + +```java +CloseableHttpClient httpclient = HttpClients.custom() + .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel", + new SentinelApacheHttpClient5Handler()) + .build(); +``` + +Or with custom configuration: + +```java +SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); +config.setPrefix("httpclient:"); +config.setExtractor(myExtractor); +config.setFallback(myFallback); + +CloseableHttpClient httpclient = HttpClients.custom() + .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel", + new SentinelApacheHttpClient5Handler(config)) + .build(); +``` + +### Configuration + +| Name | Description | Type | Default Value | +|------|------------|------|---------------| +| prefix | Customize resource prefix | `String` | `httpclient:` | +| extractor | Customize resource extractor | `ApacheHttpClientResourceExtractor` | `DefaultApacheHttpClientResourceExtractor` | +| fallback | Handle request when it is blocked | `ApacheHttpClientFallback` | `DefaultApacheHttpClientFallback` | + +### Resource Extractor + +The default extractor generates resource names in the format `METHOD:url` (e.g. `GET:http://example.com/api/users`), +with query parameters and fragments stripped. You can customize this by implementing `ApacheHttpClientResourceExtractor`: + +```java +public class MyResourceExtractor implements ApacheHttpClientResourceExtractor { + @Override + public String extractor(ClassicHttpRequest request) { + // custom resource name extraction logic + return request.getMethod() + ":" + request.getRequestUri(); + } +} +``` + +### Fallback + +The default fallback throws `SentinelRpcException`. You can customize the behavior: + +```java +public class MyFallback implements ApacheHttpClientFallback { + @Override + public ClassicHttpResponse handle(ClassicHttpRequest request, BlockException e) { + // return a custom response or throw exception + throw new SentinelRpcException(e); + } +} +``` diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/pom.xml b/sentinel-adapter/sentinel-apache-httpclient5-adapter/pom.xml new file mode 100644 index 0000000000..f7a44438e4 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/pom.xml @@ -0,0 +1,72 @@ + + + + com.alibaba.csp + sentinel-adapter + ${revision} + ../pom.xml + + 4.0.0 + + ${project.groupId}:${project.artifactId} + + sentinel-apache-httpclient5-adapter + jar + + + 5.1 + 2.1.3.RELEASE + 5.1.5.RELEASE + + + + + com.alibaba.csp + sentinel-core + + + org.apache.httpcomponents.client5 + httpclient5 + ${apache.httpclient5.version} + provided + + + + junit + junit + test + + + + org.mockito + mockito-core + test + + + com.alibaba + fastjson + test + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + test + + + org.springframework.boot + spring-boot-test + ${spring.boot.version} + test + + + org.springframework + spring-test + ${spring-test.version} + test + + + diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java new file mode 100644 index 0000000000..2de5aa2f77 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java @@ -0,0 +1,92 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.EntryType; +import com.alibaba.csp.sentinel.ResourceTypeConstants; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.Tracer; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.config.SentinelApacheHttpClientConfig; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.util.StringUtil; +import org.apache.hc.client5.http.classic.ExecChain; +import org.apache.hc.client5.http.classic.ExecChainHandler; +import org.apache.hc.core5.http.ClassicHttpRequest; +import org.apache.hc.core5.http.ClassicHttpResponse; +import org.apache.hc.core5.http.HttpException; + +import java.io.IOException; + +/** + * Apache HttpClient 5.x adapter for Sentinel. + * + *

This handler implements {@link ExecChainHandler} to intercept outgoing HTTP requests + * and protect them with Sentinel flow control.

+ * + *

Usage example:

+ *
{@code
+ * CloseableHttpClient httpclient = HttpClients.custom()
+ *     .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel",
+ *         new SentinelApacheHttpClient5Handler())
+ *     .build();
+ * }
+ * + * @author qihuai.wyq + */ +public class SentinelApacheHttpClient5Handler implements ExecChainHandler { + + private final SentinelApacheHttpClientConfig config; + + public SentinelApacheHttpClient5Handler() { + this.config = new SentinelApacheHttpClientConfig(); + } + + public SentinelApacheHttpClient5Handler(SentinelApacheHttpClientConfig config) { + this.config = config; + } + + @Override + public ClassicHttpResponse execute(ClassicHttpRequest classicHttpRequest, ExecChain.Scope scope, + ExecChain execChain) throws IOException, HttpException { + String name = config.getExtractor().extractor(classicHttpRequest); + if (StringUtil.isEmpty(name)) { + return execChain.proceed(classicHttpRequest, scope); + } + + if (StringUtil.isNotEmpty(config.getPrefix())) { + name = config.getPrefix() + name; + } + + Entry entry = null; + try { + entry = SphU.entry(name, ResourceTypeConstants.COMMON_WEB, EntryType.OUT); + return execChain.proceed(classicHttpRequest, scope); + } catch (BlockException e) { + return config.getFallback().handle(classicHttpRequest, e); + } catch (IOException | HttpException | RuntimeException e) { + Tracer.traceEntry(e, entry); + throw e; + } catch (Throwable t) { + Tracer.traceEntry(t, entry); + throw new RuntimeException(t); + } finally { + if (entry != null) { + entry.exit(); + } + } + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java new file mode 100644 index 0000000000..b52f49a056 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.config; + +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.extractor.ApacheHttpClientResourceExtractor; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.extractor.DefaultApacheHttpClientResourceExtractor; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.fallback.ApacheHttpClientFallback; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.fallback.DefaultApacheHttpClientFallback; +import com.alibaba.csp.sentinel.util.AssertUtil; + +/** + * @author qihuai.wyq + */ +public class SentinelApacheHttpClientConfig { + + private String prefix = "httpclient:"; + private ApacheHttpClientResourceExtractor extractor = new DefaultApacheHttpClientResourceExtractor(); + private ApacheHttpClientFallback fallback = new DefaultApacheHttpClientFallback(); + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + AssertUtil.notNull(prefix, "prefix cannot be null"); + this.prefix = prefix; + } + + public ApacheHttpClientResourceExtractor getExtractor() { + return extractor; + } + + public void setExtractor(ApacheHttpClientResourceExtractor extractor) { + AssertUtil.notNull(extractor, "extractor cannot be null"); + this.extractor = extractor; + } + + public ApacheHttpClientFallback getFallback() { + return fallback; + } + + public void setFallback(ApacheHttpClientFallback fallback) { + AssertUtil.notNull(fallback, "fallback cannot be null"); + this.fallback = fallback; + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java new file mode 100644 index 0000000000..94ab406022 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java @@ -0,0 +1,34 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.extractor; + +import org.apache.hc.core5.http.ClassicHttpRequest; + +/** + * Extracts Sentinel resource name from an Apache HttpClient 5.x request. + * + * @author qihuai.wyq + */ +public interface ApacheHttpClientResourceExtractor { + + /** + * Extract resource name from the given request. + * + * @param request the HTTP request + * @return the resource name, or {@code null}/{@code ""} to skip Sentinel protection + */ + String extractor(ClassicHttpRequest request); +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java new file mode 100644 index 0000000000..7f9fb3adb4 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java @@ -0,0 +1,55 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.extractor; + +import com.alibaba.csp.sentinel.log.RecordLog; +import org.apache.hc.core5.http.ClassicHttpRequest; + +/** + * Default implementation of {@link ApacheHttpClientResourceExtractor}. + * + *

Generates resource name in the format {@code METHOD:url}, with query string + * and fragment stripped. This is consistent with the OkHttp adapter's resource naming + * convention.

+ * + * @author qihuai.wyq + */ +public class DefaultApacheHttpClientResourceExtractor implements ApacheHttpClientResourceExtractor { + + @Override + public String extractor(ClassicHttpRequest request) { + try { + String httpMethod = request.getMethod(); + String originalUrl = request.getUri().toString(); + int firstIndexOfQuery = originalUrl.indexOf('?'); + int firstIndexOfFragment = originalUrl.indexOf('#'); + if (firstIndexOfFragment < 0 && firstIndexOfQuery < 0) { + return httpMethod + ":" + originalUrl; + } + if (firstIndexOfFragment > 0 && firstIndexOfQuery > 0) { + int pos = Math.min(firstIndexOfQuery, firstIndexOfFragment); + return httpMethod + ":" + originalUrl.substring(0, pos); + } else if (firstIndexOfQuery > 0) { + return httpMethod + ":" + originalUrl.substring(0, firstIndexOfQuery); + } else { + return httpMethod + ":" + originalUrl.substring(0, firstIndexOfFragment); + } + } catch (Exception ex) { + RecordLog.warn("Failed to extract resource name of HttpClient 5 request, request={}", request, ex); + return null; + } + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java new file mode 100644 index 0000000000..f3e890ed04 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.fallback; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.apache.hc.core5.http.ClassicHttpRequest; +import org.apache.hc.core5.http.ClassicHttpResponse; + +/** + * Fallback handler for Apache HttpClient 5.x when the request is blocked by Sentinel. + * + * @author qihuai.wyq + */ +public interface ApacheHttpClientFallback { + + /** + * Handle the blocked request. + * + * @param request the original HTTP request + * @param e the block exception + * @return the fallback response + */ + ClassicHttpResponse handle(ClassicHttpRequest request, BlockException e); +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java new file mode 100644 index 0000000000..8136f3922c --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java @@ -0,0 +1,32 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.fallback; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.slots.block.SentinelRpcException; +import org.apache.hc.core5.http.ClassicHttpRequest; +import org.apache.hc.core5.http.ClassicHttpResponse; + +/** + * @author qihuai.wyq + */ +public class DefaultApacheHttpClientFallback implements ApacheHttpClientFallback { + + @Override + public ClassicHttpResponse handle(ClassicHttpRequest request, BlockException e) { + throw new SentinelRpcException(e); + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java new file mode 100644 index 0000000000..72234c6921 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java @@ -0,0 +1,168 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5; + +import com.alibaba.csp.sentinel.Constants; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.app.TestApplication; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.config.SentinelApacheHttpClientConfig; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.extractor.ApacheHttpClientResourceExtractor; +import com.alibaba.csp.sentinel.node.ClusterNode; +import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.ChainElement; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.ClassicHttpRequest; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.ParseException; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.protocol.BasicHttpContext; +import org.apache.hc.core5.http.protocol.HttpContext; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; +import java.net.URISyntaxException; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * @author qihuai.wyq + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, + properties = { + "server.port=8185" + }) +public class SentinelApacheHttpClientTest { + + @Value("${server.port}") + private Integer port; + + @Test + public void testDefaultInterceptor() throws Exception { + CloseableHttpClient httpclient = HttpClients.custom() + .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel", + new SentinelApacheHttpClient5Handler()) + .build(); + + String url = "http://localhost:" + port + "/httpclient/back"; + HttpGet httpGet = new HttpGet(url); + getRemoteString(httpclient, httpGet); + ClusterNode cn = ClusterBuilderSlot.getClusterNode("httpclient:GET:" + url); + assertNotNull(cn); + } + + @Test + public void testWithUrlQuery() throws Exception { + CloseableHttpClient httpclient = HttpClients.custom() + .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel", + new SentinelApacheHttpClient5Handler()) + .build(); + + String urlWithQuery = "http://localhost:" + port + "/httpclient/query?foo=baz&baz=foo"; + String urlWithoutQuery = "http://localhost:" + port + "/httpclient/query"; + HttpGet httpGet = new HttpGet(urlWithQuery); + getRemoteString(httpclient, httpGet); + assertNotNull(ClusterBuilderSlot.getClusterNode("httpclient:GET:" + urlWithoutQuery)); + assertNull(ClusterBuilderSlot.getClusterNode("httpclient:GET:" + urlWithQuery)); + } + + @Test + public void testWithUrlQueryAndFragment() throws Exception { + CloseableHttpClient httpclient = HttpClients.custom() + .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel", + new SentinelApacheHttpClient5Handler()) + .build(); + + String urlPrefix = "http://localhost:" + port + "/httpclient/fragment"; + String suffix = "#foo?baz=xxx"; + HttpGet httpGet = new HttpGet(urlPrefix + suffix); + getRemoteString(httpclient, httpGet); + assertNotNull(ClusterBuilderSlot.getClusterNode("httpclient:GET:" + urlPrefix)); + assertNull(ClusterBuilderSlot.getClusterNode("httpclient:GET:" + urlPrefix + suffix)); + } + + @Test + public void testWithCustomizedResourceExtractor() throws Exception { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + config.setExtractor(new ApacheHttpClientResourceExtractor() { + @Override + public String extractor(ClassicHttpRequest request) { + String contains = "/httpclient/back/"; + String uri; + try { + uri = request.getUri().toString(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + if (uri.contains(contains)) { + uri = uri.substring(0, uri.indexOf(contains) + contains.length()) + "{id}"; + } + return request.getMethod() + ":" + uri; + } + }); + CloseableHttpClient httpclient = HttpClients.custom() + .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel", + new SentinelApacheHttpClient5Handler(config)) + .build(); + + HttpGet httpGet = new HttpGet("http://localhost:" + port + "/httpclient/back/1"); + getRemoteString(httpclient, httpGet); + ClusterNode cn = ClusterBuilderSlot.getClusterNode( + "httpclient:GET:http://localhost:" + port + "/httpclient/back/{id}"); + assertNotNull(cn); + } + + @Test + public void testWithEmptyPrefix() throws Exception { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + config.setPrefix(""); + + CloseableHttpClient httpclient = HttpClients.custom() + .addExecInterceptorBefore(ChainElement.MAIN_TRANSPORT.name(), "sentinel", + new SentinelApacheHttpClient5Handler(config)) + .build(); + + String url = "http://localhost:" + port + "/httpclient/noprefix"; + HttpGet httpGet = new HttpGet(url); + getRemoteString(httpclient, httpGet); + ClusterNode cn = ClusterBuilderSlot.getClusterNode("GET:" + url); + assertNotNull(cn); + } + + private String getRemoteString(CloseableHttpClient httpclient, HttpGet httpGet) + throws IOException, ParseException { + String result; + HttpContext context = new BasicHttpContext(); + CloseableHttpResponse response = httpclient.execute(httpGet, context); + try { + HttpEntity entity = response.getEntity(); + result = EntityUtils.toString(entity, "utf-8"); + EntityUtils.consume(entity); + } finally { + response.close(); + } + httpclient.close(); + return result; + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java new file mode 100644 index 0000000000..a6d382ffaa --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java @@ -0,0 +1,30 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.app; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author qihuai.wyq + */ +@SpringBootApplication +public class TestApplication { + + public static void main(String[] args) { + SpringApplication.run(TestApplication.class, args); + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java new file mode 100644 index 0000000000..f1e1eada37 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java @@ -0,0 +1,52 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.app.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author qihuai.wyq + */ +@RestController +public class TestController { + + @GetMapping("/httpclient/back") + public String back() { + return "Welcome Back!"; + } + + @GetMapping("/httpclient/back/{id}") + public String back(@PathVariable String id) { + return "Welcome Back!"; + } + + @GetMapping("/httpclient/query") + public String query() { + return "Query!"; + } + + @GetMapping("/httpclient/fragment") + public String fragment() { + return "Fragment!"; + } + + @GetMapping("/httpclient/noprefix") + public String noPrefix() { + return "No Prefix!"; + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java new file mode 100644 index 0000000000..dbde163943 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.config; + +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.extractor.DefaultApacheHttpClientResourceExtractor; +import com.alibaba.csp.sentinel.adapter.apache.httpclient5.fallback.DefaultApacheHttpClientFallback; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author qihuai.wyq + */ +public class SentinelApacheHttpClientConfigTest { + + @Test + public void testDefaultConfig() { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + assertEquals("httpclient:", config.getPrefix()); + assertNotNull(config.getExtractor()); + assertNotNull(config.getFallback()); + assertTrue(config.getExtractor() instanceof DefaultApacheHttpClientResourceExtractor); + assertTrue(config.getFallback() instanceof DefaultApacheHttpClientFallback); + } + + @Test + public void testSetPrefix() { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + config.setPrefix("custom:"); + assertEquals("custom:", config.getPrefix()); + } + + @Test + public void testSetEmptyPrefix() { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + config.setPrefix(""); + assertEquals("", config.getPrefix()); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetNullPrefix() { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + config.setPrefix(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetNullExtractor() { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + config.setExtractor(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetNullFallback() { + SentinelApacheHttpClientConfig config = new SentinelApacheHttpClientConfig(); + config.setFallback(null); + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java new file mode 100644 index 0000000000..93b70f3eb8 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.extractor; + +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author qihuai.wyq + */ +public class DefaultApacheHttpClientResourceExtractorTest { + + private final DefaultApacheHttpClientResourceExtractor extractor = + new DefaultApacheHttpClientResourceExtractor(); + + @Test + public void testSimpleUrl() { + HttpGet request = new HttpGet("http://localhost:8080/api/users"); + assertEquals("GET:http://localhost:8080/api/users", extractor.extractor(request)); + } + + @Test + public void testUrlWithQueryString() { + HttpGet request = new HttpGet("http://localhost:8080/api/users?page=1&size=10"); + assertEquals("GET:http://localhost:8080/api/users", extractor.extractor(request)); + } + + @Test + public void testUrlWithFragment() { + HttpGet request = new HttpGet("http://localhost:8080/api/users#section"); + assertEquals("GET:http://localhost:8080/api/users", extractor.extractor(request)); + } + + @Test + public void testUrlWithQueryAndFragment() { + HttpGet request = new HttpGet("http://localhost:8080/api/users?page=1#section"); + assertEquals("GET:http://localhost:8080/api/users", extractor.extractor(request)); + } + + @Test + public void testUrlWithFragmentBeforeQuery() { + HttpGet request = new HttpGet("http://localhost:8080/api/users#section?page=1"); + assertEquals("GET:http://localhost:8080/api/users", extractor.extractor(request)); + } + + @Test + public void testPostMethod() { + HttpPost request = new HttpPost("http://localhost:8080/api/users"); + assertEquals("POST:http://localhost:8080/api/users", extractor.extractor(request)); + } + + @Test + public void testRootPath() { + HttpGet request = new HttpGet("http://localhost:8080/"); + assertEquals("GET:http://localhost:8080/", extractor.extractor(request)); + } + + @Test + public void testRelativePath() { + HttpGet request = new HttpGet("/api/users"); + assertEquals("GET:/api/users", extractor.extractor(request)); + } + + @Test + public void testRelativePathWithQuery() { + HttpGet request = new HttpGet("/api/users?page=1"); + assertEquals("GET:/api/users", extractor.extractor(request)); + } +} diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java new file mode 100644 index 0000000000..86d9be8862 --- /dev/null +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 1999-2020 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.apache.httpclient5.fallback; + +import com.alibaba.csp.sentinel.slots.block.SentinelRpcException; +import com.alibaba.csp.sentinel.slots.block.flow.FlowException; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.junit.Test; + +/** + * @author qihuai.wyq + */ +public class ApacheHttpClientFallbackTest { + + @Test(expected = SentinelRpcException.class) + public void testDefaultFallbackThrowsException() { + DefaultApacheHttpClientFallback fallback = new DefaultApacheHttpClientFallback(); + HttpGet request = new HttpGet("http://localhost:8080/test"); + fallback.handle(request, new FlowException("test")); + } +} From 37ab1cc2d9f77db5d266b938a2dd255b88bc177e Mon Sep 17 00:00:00 2001 From: uuuyuqi Date: Sat, 21 Mar 2026 00:45:37 +0800 Subject: [PATCH 2/5] chore: bump version to 1.8.10-SNAPSHOT After the 1.8.9 release, several PRs have been merged but the development version was not updated. Bump to 1.8.10-SNAPSHOT for next development iteration. Change-Id: I2b7ba2b5b4e9e39d1f9749288d54b9926a512132 Co-developed-by: Cursor --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 423c71ad57..5c1cc2bb6d 100755 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ - 1.8.9 + 1.8.10-SNAPSHOT 1.2.83_noneautotype 1.3.2 From 0083d00f793d53f3cc065810243edace8b4f9b96 Mon Sep 17 00:00:00 2001 From: uuuyuqi Date: Tue, 28 Apr 2026 15:05:48 +0800 Subject: [PATCH 3/5] fix: fix markdown table format to pass document-lint Change-Id: I1fe4682e41185dc7c8ed30541989f2881ba87549 Co-developed-by: Cursor --- sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md b/sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md index e7770c2779..f30a532c4e 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/README.md @@ -42,7 +42,7 @@ CloseableHttpClient httpclient = HttpClients.custom() ### Configuration | Name | Description | Type | Default Value | -|------|------------|------|---------------| +| --- | --- | --- | --- | | prefix | Customize resource prefix | `String` | `httpclient:` | | extractor | Customize resource extractor | `ApacheHttpClientResourceExtractor` | `DefaultApacheHttpClientResourceExtractor` | | fallback | Handle request when it is blocked | `ApacheHttpClientFallback` | `DefaultApacheHttpClientFallback` | From f9d1ce76a87c7173c280481e45aa9c8ad88c41b5 Mon Sep 17 00:00:00 2001 From: uuuyuqi Date: Wed, 29 Apr 2026 10:20:24 +0800 Subject: [PATCH 4/5] fix: update @author from qihuai.wyq to uuuyuqi Change-Id: Ie28f99434badfc00decc914ffd27f83c837d947d Co-developed-by: Cursor --- .vscode/settings.json | 3 +++ .../apache/httpclient5/SentinelApacheHttpClient5Handler.java | 2 +- .../httpclient5/config/SentinelApacheHttpClientConfig.java | 2 +- .../extractor/ApacheHttpClientResourceExtractor.java | 2 +- .../extractor/DefaultApacheHttpClientResourceExtractor.java | 2 +- .../apache/httpclient5/fallback/ApacheHttpClientFallback.java | 2 +- .../httpclient5/fallback/DefaultApacheHttpClientFallback.java | 2 +- .../apache/httpclient5/SentinelApacheHttpClientTest.java | 2 +- .../adapter/apache/httpclient5/app/TestApplication.java | 2 +- .../apache/httpclient5/app/controller/TestController.java | 2 +- .../httpclient5/config/SentinelApacheHttpClientConfigTest.java | 2 +- .../DefaultApacheHttpClientResourceExtractorTest.java | 2 +- .../httpclient5/fallback/ApacheHttpClientFallbackTest.java | 2 +- 13 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..c5f3f6b9c7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java index 2de5aa2f77..90018f2e67 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClient5Handler.java @@ -45,7 +45,7 @@ * .build(); * } * - * @author qihuai.wyq + * @author uuuyuqi */ public class SentinelApacheHttpClient5Handler implements ExecChainHandler { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java index b52f49a056..d27bf903dc 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfig.java @@ -22,7 +22,7 @@ import com.alibaba.csp.sentinel.util.AssertUtil; /** - * @author qihuai.wyq + * @author uuuyuqi */ public class SentinelApacheHttpClientConfig { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java index 94ab406022..e9e29df7c8 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/ApacheHttpClientResourceExtractor.java @@ -20,7 +20,7 @@ /** * Extracts Sentinel resource name from an Apache HttpClient 5.x request. * - * @author qihuai.wyq + * @author uuuyuqi */ public interface ApacheHttpClientResourceExtractor { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java index 7f9fb3adb4..fba7636fe2 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractor.java @@ -25,7 +25,7 @@ * and fragment stripped. This is consistent with the OkHttp adapter's resource naming * convention.

* - * @author qihuai.wyq + * @author uuuyuqi */ public class DefaultApacheHttpClientResourceExtractor implements ApacheHttpClientResourceExtractor { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java index f3e890ed04..60e42dc164 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallback.java @@ -22,7 +22,7 @@ /** * Fallback handler for Apache HttpClient 5.x when the request is blocked by Sentinel. * - * @author qihuai.wyq + * @author uuuyuqi */ public interface ApacheHttpClientFallback { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java index 8136f3922c..3637e7641e 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/DefaultApacheHttpClientFallback.java @@ -21,7 +21,7 @@ import org.apache.hc.core5.http.ClassicHttpResponse; /** - * @author qihuai.wyq + * @author uuuyuqi */ public class DefaultApacheHttpClientFallback implements ApacheHttpClientFallback { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java index 72234c6921..77d1eb5c2c 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/SentinelApacheHttpClientTest.java @@ -45,7 +45,7 @@ import static org.junit.Assert.assertNull; /** - * @author qihuai.wyq + * @author uuuyuqi */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class, diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java index a6d382ffaa..f3cfaa4222 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/TestApplication.java @@ -19,7 +19,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; /** - * @author qihuai.wyq + * @author uuuyuqi */ @SpringBootApplication public class TestApplication { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java index f1e1eada37..12ecb0756e 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/app/controller/TestController.java @@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.RestController; /** - * @author qihuai.wyq + * @author uuuyuqi */ @RestController public class TestController { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java index dbde163943..4b15fadd4e 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/config/SentinelApacheHttpClientConfigTest.java @@ -22,7 +22,7 @@ import static org.junit.Assert.*; /** - * @author qihuai.wyq + * @author uuuyuqi */ public class SentinelApacheHttpClientConfigTest { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java index 93b70f3eb8..bc8ccb446b 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/extractor/DefaultApacheHttpClientResourceExtractorTest.java @@ -22,7 +22,7 @@ import static org.junit.Assert.assertEquals; /** - * @author qihuai.wyq + * @author uuuyuqi */ public class DefaultApacheHttpClientResourceExtractorTest { diff --git a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java index 86d9be8862..a2640ec6ec 100644 --- a/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java +++ b/sentinel-adapter/sentinel-apache-httpclient5-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/apache/httpclient5/fallback/ApacheHttpClientFallbackTest.java @@ -21,7 +21,7 @@ import org.junit.Test; /** - * @author qihuai.wyq + * @author uuuyuqi */ public class ApacheHttpClientFallbackTest { From fe82273e206aeac61277efc660d3b4bd5bfa15c0 Mon Sep 17 00:00:00 2001 From: uuuyuqi Date: Wed, 29 Apr 2026 10:20:41 +0800 Subject: [PATCH 5/5] chore: remove accidentally committed .vscode/settings.json Change-Id: I60caec5b17e92a79827671e531a0818f61163b48 Co-developed-by: Cursor --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c5f3f6b9c7..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "java.configuration.updateBuildConfiguration": "interactive" -} \ No newline at end of file