This is an automated email from the ASF dual-hosted git repository.
zhangyonglun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 14e4027 [fix: #2200] fix uri have encode (#2234)
14e4027 is described below
commit 14e40273fb72f0d4f5af78be653414750e4f257b
Author: xiaoyu <[email protected]>
AuthorDate: Thu Oct 21 13:11:38 2021 +0800
[fix: #2200] fix uri have encode (#2234)
* [fix: #2200] fix uri have encode
* [fix: #2200] fix uri have encode
* fix checkstyle
* [fix: #2200] fix uri have encode
---
.../apache/shenyu/common/constant/Constants.java | 11 ++-
.../org/apache/shenyu/common/enums/PluginEnum.java | 7 +-
.../http/controller/HttpTestController.java | 71 ++++++++++-------
shenyu-plugin/pom.xml | 1 +
.../apache/shenyu/plugin/divide/DividePlugin.java | 21 +----
.../shenyu/plugin/divide/DividePluginTest.java | 5 +-
.../plugin/httpclient/NettyHttpClientPlugin.java | 9 ++-
.../shenyu/plugin/httpclient/WebClientPlugin.java | 10 +--
.../httpclient/NettyHttpClientPluginTest.java | 6 +-
.../plugin/httpclient/WebClientPluginTest.java | 6 +-
.../strategy/WebClientMessageWriterTest.java | 2 +-
.../shenyu/plugin/rewrite/RewritePlugin.java | 9 +--
.../shenyu/plugin/rewrite/RewritePluginTest.java | 30 +-------
.../plugin/springcloud/SpringCloudPlugin.java | 20 ++---
shenyu-plugin/shenyu-plugin-uri/pom.xml | 47 ++++++++++++
.../org/apache/shenyu/plugin/uri/URIPlugin.java | 89 ++++++++++++++++++++++
.../shenyu-spring-boot-starter-gateway/pom.xml | 8 ++
.../shenyu-spring-boot-starter-plugin/pom.xml | 1 +
.../shenyu-spring-boot-starter-plugin-uri/pom.xml | 51 +++++++++++++
.../starter/plugin/uri/URIPluginConfiguration.java | 40 ++++++++++
.../src/main/resources/META-INF/spring.factories | 19 +++++
.../src/main/resources/META-INF/spring.provides | 18 +++++
22 files changed, 364 insertions(+), 117 deletions(-)
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
index 971c46c..6308ae5 100644
---
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
@@ -113,9 +113,14 @@ public interface Constants {
String ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR =
"original_response_content_type";
/**
- * The constant HTTP_URL.
+ * The constant HTTP_URI.
*/
- String HTTP_URL = "httpUrl";
+ String HTTP_URI = "httpUri";
+
+ /**
+ * The constant HTTP_DOMAIN.
+ */
+ String HTTP_DOMAIN = "httpDomain";
/**
* The constant RPC_PARAM_TRANSFORM.
@@ -437,7 +442,7 @@ public interface Constants {
* dubbo remote address.
*/
String DUBBO_REMOTE_ADDRESS = "dubboRemoteAddress";
-
+
/**
* dubbo group.
*/
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java
index 7b61743..58250fd 100644
--- a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java
+++ b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/PluginEnum.java
@@ -126,6 +126,11 @@ public enum PluginEnum {
WEB_SOCKET(200, 0, "websocket"),
/**
+ * Uri plugin enum.
+ */
+ URI(205, 0, "uri"),
+
+ /**
* Web client plugin enum.
*/
WEB_CLIENT(210, 0, "webClient"),
@@ -134,7 +139,7 @@ public enum PluginEnum {
* Netty http client plugin enum.
*/
NETTY_HTTP_CLIENT(210, 0, "nettyHttpClient"),
-
+
/**
* ModifyResponse plugin enum.
*/
diff --git
a/shenyu-examples/shenyu-examples-http/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
b/shenyu-examples/shenyu-examples-http/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
index 7ef2078..9fee2f4 100644
---
a/shenyu-examples/shenyu-examples-http/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
+++
b/shenyu-examples/shenyu-examples-http/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
@@ -45,7 +45,7 @@ import java.util.Map;
@RequestMapping("/test")
@ShenyuSpringMvcClient(path = "/test/**")
public class HttpTestController {
-
+
/**
* Post user dto.
*
@@ -56,7 +56,7 @@ public class HttpTestController {
public UserDTO post(@RequestBody final UserDTO userDTO) {
return userDTO;
}
-
+
/**
* Find by user id string.
*
@@ -70,11 +70,26 @@ public class HttpTestController {
userDTO.setUserName("hello world");
return userDTO;
}
-
+
+ /**
+ * Find by page user dto.
+ *
+ * @param keyword the keyword
+ * @param page the page
+ * @param pageSize the page size
+ * @return the user dto
+ */
+ @GetMapping("/findByPage")
+ public UserDTO findByPage(final String keyword, final Integer page, final
Integer pageSize) {
+ UserDTO userDTO = new UserDTO();
+ userDTO.setUserName("hello world keyword is" + keyword + " page is" +
page + " pageSize is" + pageSize);
+ return userDTO;
+ }
+
/**
* Gets path variable.
*
- * @param id the id
+ * @param id the id
* @param name the name
* @return the path variable
*/
@@ -85,8 +100,8 @@ public class HttpTestController {
userDTO.setUserName("hello world");
return userDTO;
}
-
-
+
+
/**
* Test rest ful string.
*
@@ -100,12 +115,12 @@ public class HttpTestController {
userDTO.setUserName("hello world");
return userDTO;
}
-
-
+
+
/**
* Put path variable and body string.
*
- * @param id the id
+ * @param id the id
* @param userDTO the user dto
* @return the string
*/
@@ -115,12 +130,11 @@ public class HttpTestController {
userDTO.setUserName("hello world");
return userDTO;
}
-
+
/**
* the waf pass.
*
- * @return response.
- * @return the string
+ * @return response. result bean
*/
@PostMapping("/waf/pass")
public ResultBean pass() {
@@ -129,11 +143,11 @@ public class HttpTestController {
response.setMsg("pass");
return response;
}
-
+
/**
* the waf deny.
*
- * @return response.
+ * @return response. result bean
*/
@PostMapping("/waf/deny")
public ResultBean deny() {
@@ -142,11 +156,12 @@ public class HttpTestController {
response.setMsg("deny");
return response;
}
-
+
/**
* request Pass.
+ *
* @param requestParameter the requestParameter.
- * @return ResultBean
+ * @return ResultBean result bean
*/
@GetMapping("/request/parameter/pass")
public ResultBean requestParameter(@RequestParam("requestParameter") final
String requestParameter) {
@@ -159,11 +174,12 @@ public class HttpTestController {
response.setData(param);
return response;
}
-
+
/**
* request Pass.
- * @param requestHeader the requestHeader.
- * @return ResultBean
+ *
+ * @param requestHeader the requestHeader.
+ * @return ResultBean result bean
*/
@GetMapping("/request/header/pass")
public ResultBean requestHeader(@RequestHeader("requestHeader") final
String requestHeader) {
@@ -176,11 +192,12 @@ public class HttpTestController {
response.setData(param);
return response;
}
-
+
/**
* request Pass.
- * @param cookie the cookie.
- * @return ResultBean
+ *
+ * @param cookie the cookie.
+ * @return ResultBean result bean
*/
@GetMapping("/request/cookie/pass")
public ResultBean requestCookie(@CookieValue("cookie") final String
cookie) {
@@ -193,10 +210,11 @@ public class HttpTestController {
response.setData(param);
return response;
}
-
+
/**
* post sentinel.
- * @return response.
+ *
+ * @return response. result bean
*/
@PostMapping("/sentinel/pass")
public ResultBean sentinelPass() {
@@ -205,11 +223,12 @@ public class HttpTestController {
response.setMsg("pass");
return response;
}
-
+
/**
* modify response.
+ *
* @param exchange exchange
- * @return response
+ * @return response mono
*/
@GetMapping(path = "/modifyResponse")
public Mono<String> modifyResponse(final ServerWebExchange exchange) {
diff --git a/shenyu-plugin/pom.xml b/shenyu-plugin/pom.xml
index 797a3a5..f668bd5 100644
--- a/shenyu-plugin/pom.xml
+++ b/shenyu-plugin/pom.xml
@@ -57,5 +57,6 @@
<module>shenyu-plugin-cryptor</module>
<module>shenyu-plugin-websocket</module>
<module>shenyu-plugin-dubbo</module>
+ <module>shenyu-plugin-uri</module>
</modules>
</project>
diff --git
a/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
b/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
index ac3479e..a0db4e4 100644
---
a/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
+++
b/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
@@ -88,8 +88,7 @@ public class DividePlugin extends AbstractShenyuPlugin {
}
// set the http url
String domain = buildDomain(upstream);
- String realURL = buildRealURL(domain, shenyuContext, exchange);
- exchange.getAttributes().put(Constants.HTTP_URL, realURL);
+ exchange.getAttributes().put(Constants.HTTP_DOMAIN, domain);
// set the http timeout
exchange.getAttributes().put(Constants.HTTP_TIME_OUT,
ruleHandle.getTimeout());
exchange.getAttributes().put(Constants.HTTP_RETRY,
ruleHandle.getRetry());
@@ -129,22 +128,4 @@ public class DividePlugin extends AbstractShenyuPlugin {
}
return protocol + upstream.getUrl().trim();
}
-
- private String buildRealURL(final String domain, final ShenyuContext
shenyuContext, final ServerWebExchange exchange) {
- String path = domain;
- final String rewriteURI = (String)
exchange.getAttributes().get(Constants.REWRITE_URI);
- if (StringUtils.isNoneBlank(rewriteURI)) {
- path = path + rewriteURI;
- } else {
- final String realUrl = shenyuContext.getRealUrl();
- if (StringUtils.isNoneBlank(realUrl)) {
- path = path + realUrl;
- }
- }
- String query = exchange.getRequest().getURI().getQuery();
- if (StringUtils.isNoneBlank(query)) {
- return path + "?" + query;
- }
- return path;
- }
}
diff --git
a/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
b/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
index e6daa6d..437c1fc 100644
---
a/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
@@ -96,6 +96,7 @@ public final class DividePluginTest {
// mock static
mockCheckUtils = mockStatic(UpstreamCheckUtils.class);
mockCheckUtils.when(() -> UpstreamCheckUtils.checkUrl(anyString(),
anyInt())).thenReturn(true);
+ initMockInfo();
}
@After
@@ -108,7 +109,6 @@ public final class DividePluginTest {
*/
@Test
public void doExecuteTest() {
- initMockInfo();
when(chain.execute(exchange)).thenReturn(Mono.empty());
Mono<Void> result = dividePlugin.doExecute(exchange, chain,
selectorData, ruleData);
StepVerifier.create(result).expectSubscription().verifyComplete();
@@ -119,7 +119,6 @@ public final class DividePluginTest {
*/
@Test
public void doPostExecuteTest() {
- initMockInfo();
when(chain.execute(postExchange)).thenReturn(Mono.empty());
Mono<Void> result = dividePlugin.doExecute(postExchange, chain,
selectorData, ruleData);
StepVerifier.create(result).expectSubscription().verifyComplete();
@@ -130,7 +129,6 @@ public final class DividePluginTest {
*/
@Test
public void skip() {
- initMockInfo();
Assert.assertTrue(dividePlugin.skip(exchange));
}
@@ -163,7 +161,6 @@ public final class DividePluginTest {
DividePluginDataHandler dividePluginDataHandler = new
DividePluginDataHandler();
dividePluginDataHandler.handlerRule(ruleData);
dividePluginDataHandler.handlerSelector(selectorData);
- when(context.getRealUrl()).thenReturn("mock-real");
exchange.getAttributes().put(Constants.CONTEXT, context);
when(chain.execute(exchange)).thenReturn(Mono.empty());
postExchange.getAttributes().put(Constants.CONTEXT, context);
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
index 75dda95..4ba30fd 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPlugin.java
@@ -44,6 +44,7 @@ import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.HttpClientResponse;
+import java.net.URI;
import java.time.Duration;
import java.util.Objects;
import java.util.Optional;
@@ -76,14 +77,14 @@ public class NettyHttpClientPlugin implements ShenyuPlugin {
HttpHeaders filtered = request.getHeaders();
final DefaultHttpHeaders httpHeaders = new DefaultHttpHeaders();
filtered.forEach(httpHeaders::set);
- String url = exchange.getAttribute(Constants.HTTP_URL);
- if (StringUtils.isEmpty(url)) {
+ URI uri = exchange.getAttribute(Constants.HTTP_URI);
+ if (Objects.isNull(uri)) {
Object error =
ShenyuResultWrap.error(ShenyuResultEnum.CANNOT_FIND_URL.getCode(),
ShenyuResultEnum.CANNOT_FIND_URL.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
- LOG.info("you request, The resulting urlPath is: {}", url);
+ LOG.info("you request, The resulting urlPath is: {}",
uri.toASCIIString());
Flux<HttpClientResponse> responseFlux =
this.httpClient.headers(headers -> headers.add(httpHeaders))
- .request(method).uri(url).send((req, nettyOutbound) ->
+ .request(method).uri(uri.toASCIIString()).send((req,
nettyOutbound) ->
nettyOutbound.send(request.getBody().map(dataBuffer ->
((NettyDataBuffer) dataBuffer) .getNativeBuffer())))
.responseConnection((res, connection) -> {
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_ATTR, res);
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
index 19c8c49..26a6efa 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/WebClientPlugin.java
@@ -18,7 +18,6 @@
package org.apache.shenyu.plugin.httpclient;
import io.netty.channel.ConnectTimeoutException;
-import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.common.enums.PluginEnum;
import org.apache.shenyu.common.enums.ResultEnum;
@@ -41,6 +40,7 @@ import reactor.core.publisher.Mono;
import reactor.retry.Backoff;
import reactor.retry.Retry;
+import java.net.URI;
import java.time.Duration;
import java.util.Objects;
import java.util.Optional;
@@ -67,16 +67,16 @@ public class WebClientPlugin implements ShenyuPlugin {
public Mono<Void> execute(final ServerWebExchange exchange, final
ShenyuPluginChain chain) {
final ShenyuContext shenyuContext =
exchange.getAttribute(Constants.CONTEXT);
assert shenyuContext != null;
- String urlPath = exchange.getAttribute(Constants.HTTP_URL);
- if (StringUtils.isEmpty(urlPath)) {
+ URI uri = exchange.getAttribute(Constants.HTTP_URI);
+ if (Objects.isNull(uri)) {
Object error =
ShenyuResultWrap.error(ShenyuResultEnum.CANNOT_FIND_URL.getCode(),
ShenyuResultEnum.CANNOT_FIND_URL.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
long timeout = (long)
Optional.ofNullable(exchange.getAttribute(Constants.HTTP_TIME_OUT)).orElse(3000L);
int retryTimes = (int)
Optional.ofNullable(exchange.getAttribute(Constants.HTTP_RETRY)).orElse(0);
- LOG.info("The request urlPath is {}, retryTimes is {}", urlPath,
retryTimes);
+ LOG.info("The request urlPath is {}, retryTimes is {}",
uri.toASCIIString(), retryTimes);
HttpMethod method =
HttpMethod.valueOf(exchange.getRequest().getMethodValue());
- WebClient.RequestBodySpec requestBodySpec =
webClient.method(method).uri(urlPath);
+ WebClient.RequestBodySpec requestBodySpec =
webClient.method(method).uri(uri);
return handleRequestBody(requestBodySpec, exchange, timeout,
retryTimes, chain);
}
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
index ca255ac..dd12eb1 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/NettyHttpClientPluginTest.java
@@ -38,6 +38,8 @@ import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.test.StepVerifier;
+import java.net.URI;
+
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
@@ -78,7 +80,7 @@ public final class NettyHttpClientPluginTest {
.header(HttpHeaderNames.CONNECTION.toString(),
HttpHeaderValues.KEEP_ALIVE.toString())
.body("test"));
exchange.getAttributes().put(Constants.CONTEXT,
mock(ShenyuContext.class));
- exchange.getAttributes().put(Constants.HTTP_URL, "/test");
+ exchange.getAttributes().put(Constants.HTTP_URI, URI.create("/test"));
StepVerifier.create(nettyHttpClientPlugin.execute(exchange,
chain)).expectSubscription().verifyError();
}
@@ -121,7 +123,7 @@ public final class NettyHttpClientPluginTest {
private ServerWebExchange generateServerWebExchange() {
ServerWebExchange exchange =
MockServerWebExchange.from(MockServerHttpRequest.get("/test").build());
exchange.getAttributes().put(Constants.CONTEXT,
mock(ShenyuContext.class));
- exchange.getAttributes().put(Constants.HTTP_URL, "/test");
+ exchange.getAttributes().put(Constants.HTTP_URI, "/test");
return exchange;
}
}
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
index 8d95acb..f699017 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/WebClientPluginTest.java
@@ -43,6 +43,8 @@ import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
+import java.net.URI;
+
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
@@ -93,7 +95,7 @@ public final class WebClientPluginTest {
ServerWebExchange exchangePostTest = MockServerWebExchange
.from(MockServerHttpRequest.post("/test123?param=1").build());
exchangePostTest.getAttributes().put(Constants.CONTEXT,
mock(ShenyuContext.class));
- exchangePostTest.getAttributes().put(Constants.HTTP_URL,
"/test123?param=1");
+ exchangePostTest.getAttributes().put(Constants.HTTP_URI,
URI.create("/test123?param=1"));
WebClientPlugin webClientPluginPostTest = new
WebClientPlugin(webClientPostTest);
Mono<Void> monoPostTest =
webClientPluginPostTest.execute(exchangePostTest, chainPostTest);
StepVerifier.create(monoPostTest).expectSubscription().verifyError();
@@ -149,7 +151,7 @@ public final class WebClientPluginTest {
private ServerWebExchange generateServerWebExchange() {
ServerWebExchange exchange =
MockServerWebExchange.from(MockServerHttpRequest.get("/test").build());
exchange.getAttributes().put(Constants.CONTEXT,
mock(ShenyuContext.class));
- exchange.getAttributes().put(Constants.HTTP_URL, "/test");
+ exchange.getAttributes().put(Constants.HTTP_URI, URI.create("/test"));
return exchange;
}
diff --git
a/shenyu-plugin/shenyu-plugin-response/src/test/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriterTest.java
b/shenyu-plugin/shenyu-plugin-response/src/test/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriterTest.java
index 6722ce4..8636037 100644
---
a/shenyu-plugin/shenyu-plugin-response/src/test/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriterTest.java
+++
b/shenyu-plugin/shenyu-plugin-response/src/test/java/org/apache/shenyu/plugin/response/strategy/WebClientMessageWriterTest.java
@@ -113,7 +113,7 @@ public class WebClientMessageWriterTest {
.from(MockServerHttpRequest.get("/test").build());
exchange.getAttributes().put(Constants.CONTEXT,
mock(ShenyuContext.class));
- exchange.getAttributes().put(Constants.HTTP_URL, "/test");
+ exchange.getAttributes().put(Constants.HTTP_URI, "/test");
if (haveResponse) {
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_ATTR,
mockResponse);
}
diff --git
a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
index 6c1a14a..6139534 100644
---
a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
+++
b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
@@ -46,21 +46,16 @@ public class RewritePlugin extends AbstractShenyuPlugin {
@Override
protected Mono<Void> doExecute(final ServerWebExchange exchange, final
ShenyuPluginChain chain, final SelectorData selector, final RuleData rule) {
String handle = rule.getHandle();
- final RewriteHandle rewriteHandle =
RewritePluginDataHandler.CACHED_HANDLE.get()
- .obtainHandle(CacheKeyUtils.INST.getKey(rule));
+ RewriteHandle rewriteHandle =
RewritePluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
if (Objects.isNull(rewriteHandle)) {
LOG.error("uri rewrite rule can not configuration:{}", handle);
return chain.execute(exchange);
}
- ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
String rewriteUri = exchange.getRequest().getURI().getPath();
- if (StringUtils.isNotBlank(shenyuContext.getRealUrl())) {
- rewriteUri = shenyuContext.getRealUrl();
- }
if (StringUtils.isNoneBlank(rewriteHandle.getRegex(),
rewriteHandle.getReplace())) {
rewriteUri = rewriteUri.replaceAll(rewriteHandle.getRegex(),
rewriteHandle.getReplace());
+ exchange.getAttributes().put(Constants.REWRITE_URI, rewriteUri);
}
- exchange.getAttributes().put(Constants.REWRITE_URI, rewriteUri);
return chain.execute(exchange);
}
diff --git
a/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
b/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
index cc52bfd..107665f 100644
---
a/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
@@ -17,6 +17,7 @@
package org.apache.shenyu.plugin.rewrite;
+import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.common.dto.RuleData;
import org.apache.shenyu.common.dto.SelectorData;
@@ -26,6 +27,7 @@ import org.apache.shenyu.plugin.api.ShenyuPluginChain;
import org.apache.shenyu.plugin.api.context.ShenyuContext;
import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
import org.apache.shenyu.plugin.rewrite.handler.RewritePluginDataHandler;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -64,39 +66,13 @@ public final class RewritePluginTest {
@Test
public void testRewritePlugin() {
RuleData data = new RuleData();
- data.setHandle("{}");
- RewriteHandle rewriteHandle =
GsonUtils.getGson().fromJson(data.getHandle(), RewriteHandle.class);
-
RewritePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(data),
rewriteHandle);
- when(chain.execute(exchange)).thenReturn(Mono.empty());
- SelectorData selectorData = mock(SelectorData.class);
- StepVerifier.create(rewritePlugin.doExecute(exchange, chain,
selectorData, data)).expectSubscription().verifyComplete();
- assertEquals("/shenyu/test",
exchange.getAttributes().get(Constants.REWRITE_URI));
- }
-
- @Test
- public void shouldReturnOriginURIForRewritePlugin() {
- RuleData data = new RuleData();
data.setHandle("{\"regex\":\"\",\"replace\":\"\"}");
RewriteHandle rewriteHandle =
GsonUtils.getGson().fromJson(data.getHandle(), RewriteHandle.class);
RewritePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(data),
rewriteHandle);
when(chain.execute(exchange)).thenReturn(Mono.empty());
SelectorData selectorData = mock(SelectorData.class);
StepVerifier.create(rewritePlugin.doExecute(exchange, chain,
selectorData, data)).expectSubscription().verifyComplete();
- assertEquals("/shenyu/test",
exchange.getAttributes().get(Constants.REWRITE_URI));
- }
-
- @Test
- public void shouldReturnNewRealUriForRewritePlugin() {
- RuleData data = new RuleData();
- data.setHandle("{\"regex\":\"test\",\"replace\":\"rewrite\"}");
- RewriteHandle rewriteHandle =
GsonUtils.getGson().fromJson(data.getHandle(), RewriteHandle.class);
- ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
- shenyuContext.setRealUrl("/test");
-
RewritePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(data),
rewriteHandle);
- when(chain.execute(exchange)).thenReturn(Mono.empty());
- SelectorData selectorData = mock(SelectorData.class);
- StepVerifier.create(rewritePlugin.doExecute(exchange, chain,
selectorData, data)).expectSubscription().verifyComplete();
- assertEquals("/rewrite",
exchange.getAttributes().get(Constants.REWRITE_URI));
+ Assert.assertTrue(StringUtils.isBlank((String)
exchange.getAttributes().get(Constants.REWRITE_URI)));
}
@Test
diff --git
a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
index 20aec97..b0cc031 100644
---
a/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/SpringCloudPlugin.java
@@ -89,11 +89,8 @@ public class SpringCloudPlugin extends AbstractShenyuPlugin {
.error(ShenyuResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getCode(),
ShenyuResultEnum.SPRINGCLOUD_SERVICEID_IS_ERROR.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
- final URI uri = loadBalancer.reconstructURI(serviceInstance,
URI.create(shenyuContext.getRealUrl()));
-
- String realURL = buildRealURL(uri, exchange,
exchange.getRequest().getURI().getQuery());
-
- exchange.getAttributes().put(Constants.HTTP_URL, realURL);
+ URI uri = loadBalancer.reconstructURI(serviceInstance,
URI.create(shenyuContext.getRealUrl()));
+ setDomain(uri, exchange);
//set time out.
exchange.getAttributes().put(Constants.HTTP_TIME_OUT,
ruleHandle.getTimeout());
return chain.execute(exchange);
@@ -131,15 +128,8 @@ public class SpringCloudPlugin extends
AbstractShenyuPlugin {
return WebFluxResultUtils.noRuleResult(pluginName, exchange);
}
- private String buildRealURL(final URI uri, final ServerWebExchange
exchange, final String query) {
- String url = uri.toASCIIString();
- final String rewriteURI = (String)
exchange.getAttributes().get(Constants.REWRITE_URI);
- if (StringUtils.isNotBlank(rewriteURI)) {
- url = url.replace(uri.getPath(), rewriteURI);
- }
- if (StringUtils.isNotBlank(query)) {
- return url + "?" + query;
- }
- return url;
+ private void setDomain(final URI uri, final ServerWebExchange exchange) {
+ String domain = uri.getScheme() + "://" + uri.getAuthority();
+ exchange.getAttributes().put(Constants.HTTP_DOMAIN, domain);
}
}
diff --git a/shenyu-plugin/shenyu-plugin-uri/pom.xml
b/shenyu-plugin/shenyu-plugin-uri/pom.xml
new file mode 100644
index 0000000..b598a01
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-uri/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-plugin</artifactId>
+ <version>2.4.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>shenyu-plugin-uri</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-plugin-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.projectreactor</groupId>
+ <artifactId>reactor-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git
a/shenyu-plugin/shenyu-plugin-uri/src/main/java/org/apache/shenyu/plugin/uri/URIPlugin.java
b/shenyu-plugin/shenyu-plugin-uri/src/main/java/org/apache/shenyu/plugin/uri/URIPlugin.java
new file mode 100644
index 0000000..f6e81c9
--- /dev/null
+++
b/shenyu-plugin/shenyu-plugin-uri/src/main/java/org/apache/shenyu/plugin/uri/URIPlugin.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.shenyu.plugin.uri;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.common.constant.Constants;
+import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
+import org.apache.shenyu.plugin.api.ShenyuPlugin;
+import org.apache.shenyu.plugin.api.ShenyuPluginChain;
+import org.apache.shenyu.plugin.api.context.ShenyuContext;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.util.UriComponentsBuilder;
+import reactor.core.publisher.Mono;
+
+import java.net.URI;
+import java.util.Objects;
+
+/**
+ * The type Uri plugin.
+ */
+public class URIPlugin implements ShenyuPlugin {
+
+ @Override
+ public Mono<Void> execute(final ServerWebExchange exchange, final
ShenyuPluginChain chain) {
+ ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
+ assert shenyuContext != null;
+ String path = exchange.getAttribute(Constants.HTTP_DOMAIN);
+ String rewriteURI = (String)
exchange.getAttributes().get(Constants.REWRITE_URI);
+ URI uri = exchange.getRequest().getURI();
+ if (StringUtils.isNoneBlank(rewriteURI)) {
+ path = path + rewriteURI;
+ } else {
+ String realUrl = shenyuContext.getRealUrl();
+ if (StringUtils.isNoneBlank(realUrl)) {
+ path = path + realUrl;
+ }
+ }
+ URI realURI;
+ if (StringUtils.isNotEmpty(uri.getRawQuery()) &&
uri.getRawQuery().contains("%")) {
+ path = path + "?" + uri.getRawQuery();
+ realURI =
UriComponentsBuilder.fromHttpUrl(path).build(true).toUri();
+ } else {
+ if (StringUtils.isNotEmpty(uri.getQuery())) {
+ path = path + "?" + uri.getQuery();
+ }
+ assert path != null;
+ realURI =
UriComponentsBuilder.fromHttpUrl(path).build(false).toUri();
+ }
+ exchange.getAttributes().put(Constants.HTTP_URI, realURI);
+ return chain.execute(exchange);
+ }
+
+ @Override
+ public int getOrder() {
+ return PluginEnum.URI.getCode();
+ }
+
+ @Override
+ public String named() {
+ return PluginEnum.URI.getName();
+ }
+
+ @Override
+ public boolean skip(final ServerWebExchange exchange) {
+ ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
+ assert shenyuContext != null;
+ String rpcType = shenyuContext.getRpcType();
+ if (Objects.equals(rpcType, RpcTypeEnum.HTTP.getName())) {
+ return false;
+ }
+ return !Objects.equals(rpcType, RpcTypeEnum.SPRING_CLOUD.getName());
+ }
+}
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/pom.xml
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/pom.xml
index 0c7f236..e4f3000 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/pom.xml
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-gateway/pom.xml
@@ -69,5 +69,13 @@
<version>${project.version}</version>
</dependency>
<!--shenyu response plugin end-->
+
+ <!--shenyu param uri plugin start-->
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin-uri</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!--shenyu param uri end-->
</dependencies>
</project>
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml
index fa98155..73240dd 100644
--- a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml
+++ b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/pom.xml
@@ -55,5 +55,6 @@
<module>shenyu-spring-boot-starter-plugin-cryptor</module>
<module>shenyu-spring-boot-starter-plugin-websocket</module>
<module>shenyu-spring-boot-starter-plugin-dubbo</module>
+ <module>shenyu-spring-boot-starter-plugin-uri</module>
</modules>
</project>
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/pom.xml
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/pom.xml
new file mode 100644
index 0000000..eeee7b2
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-spring-boot-starter-plugin</artifactId>
+ <version>2.4.1-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>shenyu-spring-boot-starter-plugin-uri</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shenyu</groupId>
+ <artifactId>shenyu-plugin-uri</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/java/org/apache/shenyu/springboot/starter/plugin/uri/URIPluginConfiguration.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/java/org/apache/shenyu/springboot/starter/plugin/uri/URIPluginConfiguration.java
new file mode 100644
index 0000000..944b595
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/java/org/apache/shenyu/springboot/starter/plugin/uri/URIPluginConfiguration.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.shenyu.springboot.starter.plugin.uri;
+
+import org.apache.shenyu.plugin.api.ShenyuPlugin;
+import org.apache.shenyu.plugin.uri.URIPlugin;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * The type Uri plugin configuration.
+ */
+@Configuration
+public class URIPluginConfiguration {
+
+ /**
+ * Uri plugin shenyu plugin.
+ *
+ * @return the shenyu plugin
+ */
+ @Bean
+ public ShenyuPlugin uriPlugin() {
+ return new URIPlugin();
+ }
+}
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/resources/META-INF/spring.factories
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..d1b3ddc
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.shenyu.springboot.starter.plugin.uri.URIPluginConfiguration
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/resources/META-INF/spring.provides
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000..b630e78
--- /dev/null
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-uri/src/main/resources/META-INF/spring.provides
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+provides: shenyu-spring-boot-starter-plugin-uri