diff --git a/sentinel-adapter/pom.xml b/sentinel-adapter/pom.xml
index a8ef8810..32965816 100755
--- a/sentinel-adapter/pom.xml
+++ b/sentinel-adapter/pom.xml
@@ -27,6 +27,7 @@
sentinel-spring-cloud-gateway-adapter
sentinel-spring-webmvc-adapter
sentinel-zuul2-adapter
+ sentinel-okhttp-adapter
sentinel-jax-rs-adapter
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/README.md b/sentinel-adapter/sentinel-okhttp-adapter/README.md
new file mode 100755
index 00000000..6b5e61d5
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/README.md
@@ -0,0 +1,63 @@
+# Sentinel OkHttp Adapter
+
+## Introduction
+
+Sentinel provides integration for OkHttp client to enable flow control for web requests.
+
+Add the following dependency in `pom.xml` (if you are using Maven):
+
+```xml
+
+ com.alibaba.csp
+ sentinel-okhttp-adapter
+ x.y.z
+
+```
+
+We can add the `SentinelOkHttpInterceptor` interceptor when `OkHttpClient` at initialization, for example:
+
+```java
+OkHttpClient client = new OkHttpClient.Builder()
+ .addInterceptor(new SentinelOkHttpInterceptor())
+ .build();
+```
+
+## Configuration
+
+- `SentinelOkHttpConfig` configuration:
+
+| name | description | type | default value |
+|------|------------|------|-------|
+| extractor | custom resource extractor | `OkHttpResourceExtractor` | `DefaultOkHttpResourceExtractor` |
+| fallback | handle request when it is blocked | `OkHttpFallback` | `DefaultOkHttpFallback` |
+
+### extractor (resource extractor)
+
+We can define `OkHttpResourceExtractor` to custom resource extractor replace `DefaultOkHttpResourceExtractor`, for example: okhttp:GET:ip:port/okhttp/back/1 ==> /okhttp/back/{id}
+
+```java
+OkHttpResourceExtractor extractor = (request, connection) -> {
+ String resource = request.url().toString();
+ String regex = "/okhttp/back/";
+ if (resource.contains(regex)) {
+ resource = resource.substring(0, resource.indexOf(regex) + regex.length()) + "{id}";
+ }
+ return resource;
+};
+SentinelOkHttpConfig.setExtractor(extractor);
+```
+
+### fallback (Block handling)
+
+We can define `OkHttpFallback` to handle request is blocked according to the actual scenario, for example:
+
+```java
+public class DefaultOkHttpFallback implements OkHttpFallback {
+
+ @Override
+ public Response handle(Request request, Connection connection, BlockException e) {
+ // Just wrap and throw the exception.
+ throw new SentinelRpcException(e);
+ }
+}
+```
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/pom.xml b/sentinel-adapter/sentinel-okhttp-adapter/pom.xml
new file mode 100644
index 00000000..658d4e41
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/pom.xml
@@ -0,0 +1,68 @@
+
+
+
+ sentinel-adapter
+ com.alibaba.csp
+ 1.8.0-SNAPSHOT
+
+ 4.0.0
+
+ sentinel-okhttp-adapter
+ jar
+
+
+ 3.6.0
+ 2.1.3.RELEASE
+ 5.1.5.RELEASE
+
+
+
+
+ com.alibaba.csp
+ sentinel-core
+
+
+
+ com.squareup.okhttp3
+ okhttp
+ ${okhttp.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
+
+
+
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/SentinelOkHttpInterceptor.java b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/SentinelOkHttpInterceptor.java
new file mode 100644
index 00000000..0e8f54a3
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/SentinelOkHttpInterceptor.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.okhttp;
+
+import com.alibaba.csp.sentinel.*;
+import com.alibaba.csp.sentinel.adapter.okhttp.config.SentinelOkHttpConfig;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.alibaba.csp.sentinel.util.StringUtil;
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+import java.io.IOException;
+
+/**
+ * @author zhaoyuguang
+ */
+public class SentinelOkHttpInterceptor implements Interceptor {
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Entry entry = null;
+ try {
+ Request request = chain.request();
+ String name = SentinelOkHttpConfig.getExtractor().extract(request.url().toString(), request, chain.connection());
+ if (!StringUtil.isEmpty(SentinelOkHttpConfig.getPrefix())) {
+ name = SentinelOkHttpConfig.getPrefix() + name;
+ }
+ entry = SphU.entry(name, ResourceTypeConstants.COMMON_WEB, EntryType.OUT);
+ return chain.proceed(request);
+ } catch (BlockException e) {
+ return SentinelOkHttpConfig.getFallback().handle(chain.request(), chain.connection(), e);
+ } catch (Throwable t) {
+ Tracer.traceEntry(t, entry);
+ throw t;
+ } finally {
+ if (entry != null) {
+ entry.exit();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/config/SentinelOkHttpConfig.java b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/config/SentinelOkHttpConfig.java
new file mode 100644
index 00000000..48e986f7
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/config/SentinelOkHttpConfig.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.okhttp.config;
+
+import com.alibaba.csp.sentinel.adapter.okhttp.extractor.DefaultOkHttpResourceExtractor;
+import com.alibaba.csp.sentinel.adapter.okhttp.extractor.OkHttpResourceExtractor;
+import com.alibaba.csp.sentinel.adapter.okhttp.fallback.DefaultOkHttpFallback;
+import com.alibaba.csp.sentinel.adapter.okhttp.fallback.OkHttpFallback;
+import com.alibaba.csp.sentinel.util.AssertUtil;
+
+/**
+ * @author zhaoyuguang
+ */
+public final class SentinelOkHttpConfig {
+
+ private static volatile String prefix = "okhttp:";
+ private static volatile OkHttpResourceExtractor extractor = new DefaultOkHttpResourceExtractor();
+ private static volatile OkHttpFallback fallback = new DefaultOkHttpFallback();
+
+ public static String getPrefix() {
+ return prefix;
+ }
+
+ public static void setPrefix(String prefix) {
+ AssertUtil.notNull(prefix, "prefix cannot be null");
+ SentinelOkHttpConfig.prefix = prefix;
+ }
+
+ public static OkHttpResourceExtractor getExtractor() {
+ return extractor;
+ }
+
+ public static void setExtractor(OkHttpResourceExtractor extractor) {
+ AssertUtil.notNull(extractor, "extractor cannot be null");
+ SentinelOkHttpConfig.extractor = extractor;
+ }
+
+ public static OkHttpFallback getFallback() {
+ return fallback;
+ }
+
+ public static void setFallback(OkHttpFallback fallback) {
+ AssertUtil.notNull(fallback, "fallback cannot be null");
+ SentinelOkHttpConfig.fallback = fallback;
+ }
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/DefaultOkHttpResourceExtractor.java b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/DefaultOkHttpResourceExtractor.java
new file mode 100644
index 00000000..1a7cc2bc
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/DefaultOkHttpResourceExtractor.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.okhttp.extractor;
+
+import okhttp3.Connection;
+import okhttp3.Request;
+
+/**
+ * @author zhaoyuguang
+ */
+public class DefaultOkHttpResourceExtractor implements OkHttpResourceExtractor {
+
+ @Override
+ public String extract(String url, Request request, Connection connection) {
+ return request.method() + ":" + request.url().toString();
+ }
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/OkHttpResourceExtractor.java b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/OkHttpResourceExtractor.java
new file mode 100644
index 00000000..2a376d41
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/OkHttpResourceExtractor.java
@@ -0,0 +1,27 @@
+/*
+ * 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.okhttp.extractor;
+
+import okhttp3.Connection;
+import okhttp3.Request;
+
+/**
+ * @author zhaoyuguang
+ */
+public interface OkHttpResourceExtractor {
+
+ String extract(String url, Request request, Connection connection);
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/DefaultOkHttpFallback.java b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/DefaultOkHttpFallback.java
new file mode 100644
index 00000000..6ece854f
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/DefaultOkHttpFallback.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.okhttp.fallback;
+
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
+import okhttp3.Connection;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * @author zhaoyuguang
+ */
+public class DefaultOkHttpFallback implements OkHttpFallback {
+
+ @Override
+ public Response handle(Request request, Connection connection, BlockException e) {
+ // Just wrap and throw the exception.
+ throw new SentinelRpcException(e);
+ }
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/OkHttpFallback.java b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/OkHttpFallback.java
new file mode 100644
index 00000000..4127c195
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/OkHttpFallback.java
@@ -0,0 +1,29 @@
+/*
+ * 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.okhttp.fallback;
+
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import okhttp3.Connection;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * @author zhaoyuguang
+ */
+public interface OkHttpFallback {
+
+ Response handle(Request request, Connection connection, BlockException e);
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/SentinelOkHttpInterceptorTest.java b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/SentinelOkHttpInterceptorTest.java
new file mode 100644
index 00000000..4f831b9b
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/SentinelOkHttpInterceptorTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.okhttp;
+
+import com.alibaba.csp.sentinel.Constants;
+import com.alibaba.csp.sentinel.adapter.okhttp.app.TestApplication;
+import com.alibaba.csp.sentinel.adapter.okhttp.config.SentinelOkHttpConfig;
+import com.alibaba.csp.sentinel.adapter.okhttp.extractor.OkHttpResourceExtractor;
+import com.alibaba.csp.sentinel.node.ClusterNode;
+import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
+import okhttp3.Connection;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+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 static org.junit.Assert.assertNotNull;
+
+/**
+ * @author zhaoyuguang
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = TestApplication.class,
+ webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
+ properties = {
+ "server.port=8086"
+ })
+public class SentinelOkHttpInterceptorTest {
+
+ @Value("${server.port}")
+ private Integer port;
+
+ @Test
+ public void testSentinelOkHttpInterceptor0() throws Exception {
+
+ String url0 = "http://localhost:" + port + "/okhttp/back";
+ SentinelOkHttpConfig.setPrefix("okhttp:");
+ OkHttpClient client = new OkHttpClient.Builder()
+ .addInterceptor(new SentinelOkHttpInterceptor())
+ .build();
+ Request request = new Request.Builder()
+ .url(url0)
+ .build();
+ System.out.println(client.newCall(request).execute().body().string());
+ ClusterNode cn = ClusterBuilderSlot.getClusterNode(SentinelOkHttpConfig.getPrefix() + "GET:" + url0);
+ assertNotNull(cn);
+
+ Constants.ROOT.removeChildList();
+ ClusterBuilderSlot.getClusterNodeMap().clear();
+ }
+
+ @Test
+ public void testSentinelOkHttpInterceptor1() throws Exception {
+
+ String url0 = "http://localhost:" + port + "/okhttp/back/1";
+ SentinelOkHttpConfig.setExtractor(new OkHttpResourceExtractor() {
+ @Override
+ public String extract(String url, Request request, Connection connection) {
+ String regex = "/okhttp/back/";
+ if (url.contains(regex)) {
+ url = url.substring(0, url.indexOf(regex) + regex.length()) + "{id}";
+ }
+ return request.method() + ":" + url;
+ }
+ });
+ OkHttpClient client = new OkHttpClient.Builder()
+ .addInterceptor(new SentinelOkHttpInterceptor())
+ .build();
+ Request request = new Request.Builder()
+ .url(url0)
+ .build();
+ System.out.println(client.newCall(request).execute().body().string());
+
+ String url1 = SentinelOkHttpConfig.getPrefix() + "GET:http://localhost:" + port + "/okhttp/back/{id}";
+ ClusterNode cn = ClusterBuilderSlot.getClusterNode(url1);
+ assertNotNull(cn);
+
+ Constants.ROOT.removeChildList();
+ ClusterBuilderSlot.getClusterNodeMap().clear();
+ }
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/app/TestApplication.java b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/app/TestApplication.java
new file mode 100644
index 00000000..8eef5893
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/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.okhttp.app;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author zhaoyuguang
+ */
+@SpringBootApplication
+public class TestApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(TestApplication.class);
+ }
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/app/controller/TestController.java b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/app/controller/TestController.java
new file mode 100644
index 00000000..96dd3674
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/app/controller/TestController.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.okhttp.app.controller;
+
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author zhaoyuguang
+ */
+@RestController
+public class TestController {
+
+ @RequestMapping("/okhttp/back")
+ public String back() {
+ return "Welcome Back!";
+ }
+
+ @RequestMapping("/okhttp/back/{id}")
+ public String back(@PathVariable String id) {
+ return "Welcome Back! " + id;
+ }
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/config/SentinelOkHttpConfigTest.java b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/config/SentinelOkHttpConfigTest.java
new file mode 100644
index 00000000..b9f60553
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/config/SentinelOkHttpConfigTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.okhttp.config;
+
+import org.junit.Test;
+
+/**
+ * @author zhaoyuguang
+ */
+public class SentinelOkHttpConfigTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConfigSetPrefix() {
+ SentinelOkHttpConfig.setPrefix(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConfigSetCleaner() {
+ SentinelOkHttpConfig.setExtractor(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConfigSetFallback() {
+ SentinelOkHttpConfig.setFallback(null);
+ }
+}
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/OkHttpResourceExtractorTest.java b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/OkHttpResourceExtractorTest.java
new file mode 100644
index 00000000..c414dad9
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/extractor/OkHttpResourceExtractorTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.okhttp.extractor;
+
+import com.alibaba.csp.sentinel.adapter.okhttp.config.SentinelOkHttpConfig;
+import okhttp3.Connection;
+import okhttp3.Request;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author zhaoyuguang
+ */
+public class OkHttpResourceExtractorTest {
+
+ @Test
+ public void testDefaultOkHttpResourceExtractor() {
+ OkHttpResourceExtractor extractor = new DefaultOkHttpResourceExtractor();
+ String url = "http://localhost:8083/okhttp/back";
+ Request request = new Request.Builder()
+ .url(url)
+ .build();
+ extractor.extract(url, request, null);
+ System.out.println(extractor.extract(url, request, null));
+ assertEquals("GET:"+url, extractor.extract(url, request, null));
+ }
+
+ @Test
+ public void testCustomizeOkHttpUrlCleaner() {
+ OkHttpResourceExtractor extractor = new OkHttpResourceExtractor() {
+ @Override
+ public String extract(String url, Request request, Connection connection) {
+ String regex = "/okhttp/back/";
+ if (url.contains(regex)) {
+ url = url.substring(0, url.indexOf(regex) + regex.length()) + "{id}";
+ }
+ return request.method() + ":" + url;
+ }
+ };
+ String url = "http://localhost:8083/okhttp/back/abc";
+ Request request = new Request.Builder()
+ .url(url)
+ .build();
+ extractor.extract(url, request, null);
+ assertEquals("GET:http://localhost:8083/okhttp/back/{id}", extractor.extract(url, request, null));
+ }
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/OkHttpFallbackTest.java b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/OkHttpFallbackTest.java
new file mode 100644
index 00000000..f3552753
--- /dev/null
+++ b/sentinel-adapter/sentinel-okhttp-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/okhttp/fallback/OkHttpFallbackTest.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.okhttp.fallback;
+
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
+import org.junit.Test;
+
+/**
+ * @author zhaoyuguang
+ */
+public class OkHttpFallbackTest {
+
+ @Test(expected = SentinelRpcException.class)
+ public void testDefaultOkHttpFallback() {
+ BlockException e = new FlowException("xxx");
+ OkHttpFallback fallback = new DefaultOkHttpFallback();
+ fallback.handle(null, null, e);
+ }
+}
diff --git a/sentinel-demo/pom.xml b/sentinel-demo/pom.xml
index a5465da0..65076415 100755
--- a/sentinel-demo/pom.xml
+++ b/sentinel-demo/pom.xml
@@ -39,6 +39,7 @@
sentinel-demo-spring-webmvc
sentinel-demo-zuul2-gateway
sentinel-demo-log-logback
+ sentinel-demo-okhttp
sentinel-demo-jax-rs
diff --git a/sentinel-demo/sentinel-demo-okhttp/pom.xml b/sentinel-demo/sentinel-demo-okhttp/pom.xml
new file mode 100644
index 00000000..25897f60
--- /dev/null
+++ b/sentinel-demo/sentinel-demo-okhttp/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+ sentinel-demo
+ com.alibaba.csp
+ 1.8.0-SNAPSHOT
+
+ 4.0.0
+
+ sentinel-demo-okhttp
+
+
+ 2.1.3.RELEASE
+ 3.6.0
+
+
+
+
+ com.alibaba.csp
+ sentinel-transport-simple-http
+
+
+ com.alibaba.csp
+ sentinel-okhttp-adapter
+ ${project.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring.boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ ${spring.boot.version}
+
+
+ com.squareup.okhttp3
+ okhttp
+ ${okhttp.version}
+
+
+
\ No newline at end of file
diff --git a/sentinel-demo/sentinel-demo-okhttp/src/main/java/com/alibaba/csp/sentinel/demo/okhttp/OkHttpDemoApplication.java b/sentinel-demo/sentinel-demo-okhttp/src/main/java/com/alibaba/csp/sentinel/demo/okhttp/OkHttpDemoApplication.java
new file mode 100644
index 00000000..182a62a8
--- /dev/null
+++ b/sentinel-demo/sentinel-demo-okhttp/src/main/java/com/alibaba/csp/sentinel/demo/okhttp/OkHttpDemoApplication.java
@@ -0,0 +1,49 @@
+/*
+ * 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.demo.okhttp;
+
+import com.alibaba.csp.sentinel.adapter.okhttp.config.SentinelOkHttpConfig;
+import com.alibaba.csp.sentinel.adapter.okhttp.extractor.OkHttpResourceExtractor;
+import okhttp3.Connection;
+import okhttp3.Request;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author zhaoyuguang
+ */
+@SpringBootApplication
+public class OkHttpDemoApplication implements CommandLineRunner {
+
+ public static void main(String[] args) {
+ SpringApplication.run(OkHttpDemoApplication.class);
+ }
+
+ @Override
+ public void run(String... args) {
+ SentinelOkHttpConfig.setExtractor(new OkHttpResourceExtractor() {
+ @Override
+ public String extract(String url, Request request, Connection connection) {
+ String regex = "/okhttp/back/";
+ if (url.contains(regex)) {
+ url = url.substring(0, url.indexOf(regex) + regex.length()) + "{id}";
+ }
+ return request.method() + ":" + url;
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/sentinel-demo/sentinel-demo-okhttp/src/main/java/com/alibaba/csp/sentinel/demo/okhttp/controller/OkHttpTestController.java b/sentinel-demo/sentinel-demo-okhttp/src/main/java/com/alibaba/csp/sentinel/demo/okhttp/controller/OkHttpTestController.java
new file mode 100644
index 00000000..a0da1bac
--- /dev/null
+++ b/sentinel-demo/sentinel-demo-okhttp/src/main/java/com/alibaba/csp/sentinel/demo/okhttp/controller/OkHttpTestController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.demo.okhttp.controller;
+
+import com.alibaba.csp.sentinel.adapter.okhttp.SentinelOkHttpInterceptor;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+
+/**
+ * @author zhaoyuguang
+ */
+@RestController
+public class OkHttpTestController {
+
+ @Value("${server.port}")
+ private Integer port;
+
+ @RequestMapping("/okhttp/back")
+ public String back() {
+ return "Welcome Back!";
+ }
+
+ @RequestMapping("/okhttp/back/{id}")
+ public String back(@PathVariable String id) {
+ return "Welcome Back! " + id;
+ }
+
+ @RequestMapping("/okhttp/testcase/{id}")
+ public String testcase(@PathVariable String id) throws Exception {
+ return getRemoteString(id);
+ }
+
+ @RequestMapping("/okhttp/testcase")
+ public String testcase() throws Exception {
+ return getRemoteString(null);
+ }
+
+ private String getRemoteString(String id) throws IOException {
+ OkHttpClient client = new OkHttpClient.Builder()
+ .addInterceptor(new SentinelOkHttpInterceptor())
+ .build();
+ Request request = new Request.Builder()
+ .url("http://localhost:" + port + "/okhttp/back" + (id == null ? "" : "/" + id))
+ .build();
+ Response response = client.newCall(request).execute();
+ return response.body().string();
+ }
+}
\ No newline at end of file
diff --git a/sentinel-demo/sentinel-demo-okhttp/src/main/resources/application.properties b/sentinel-demo/sentinel-demo-okhttp/src/main/resources/application.properties
new file mode 100644
index 00000000..973e6c25
--- /dev/null
+++ b/sentinel-demo/sentinel-demo-okhttp/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+spring.application.name=sentinel-demo-okhttp
+server.port=8085
\ No newline at end of file