You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shenyu.apache.org by xi...@apache.org on 2022/12/13 03:20:05 UTC
[shenyu] branch master updated: [type:refactor] decoupled sign plugin (#4261)
This is an automated email from the ASF dual-hosted git repository.
xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new e60d93ef4 [type:refactor] decoupled sign plugin (#4261)
e60d93ef4 is described below
commit e60d93ef426bc168435920e5e1f622ba6e74ceb9
Author: 愿凌飞 <ti...@foxmail.com>
AuthorDate: Tue Dec 13 11:19:56 2022 +0800
[type:refactor] decoupled sign plugin (#4261)
* [refactor] decoupled sign plugin
* deleted unused class
* fix
* fix
---
.../plugin/base/support/RequestDecorator.java} | 9 ++--
.../shenyu/plugin/base/utils/ResponseUtils.java | 4 +-
.../plugin/base/utils/ServerWebExchangeUtils.java | 63 ++++++++++++++++++++++
.../org/apache/shenyu/plugin/sign/SignPlugin.java | 48 ++++++-----------
.../plugin/sign/exception/SignPluginException.java | 35 ++++++++++++
5 files changed, 121 insertions(+), 38 deletions(-)
diff --git a/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/decorator/SignRequestDecorator.java b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/support/RequestDecorator.java
similarity index 83%
rename from shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/decorator/SignRequestDecorator.java
rename to shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/support/RequestDecorator.java
index ef61569af..e6f138d69 100644
--- a/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/decorator/SignRequestDecorator.java
+++ b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/support/RequestDecorator.java
@@ -15,9 +15,8 @@
* limitations under the License.
*/
-package org.apache.shenyu.plugin.sign.decorator;
+package org.apache.shenyu.plugin.base.support;
-import org.apache.shenyu.plugin.base.support.CachedBodyOutputMessage;
import org.apache.shenyu.plugin.base.utils.ResponseUtils;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
@@ -29,14 +28,14 @@ import reactor.util.annotation.NonNull;
/**
* Build and modify the request class.
*/
-public class SignRequestDecorator extends ServerHttpRequestDecorator {
+public class RequestDecorator extends ServerHttpRequestDecorator {
private final CachedBodyOutputMessage cachedBodyOutputMessage;
private final ServerWebExchange exchange;
- public SignRequestDecorator(final ServerWebExchange exchange,
- final CachedBodyOutputMessage cachedBodyOutputMessage) {
+ public RequestDecorator(final ServerWebExchange exchange,
+ final CachedBodyOutputMessage cachedBodyOutputMessage) {
super(exchange.getRequest());
this.cachedBodyOutputMessage = cachedBodyOutputMessage;
this.exchange = exchange;
diff --git a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/ResponseUtils.java b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/ResponseUtils.java
index dd7df43c8..c4b04da41 100644
--- a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/ResponseUtils.java
+++ b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/ResponseUtils.java
@@ -22,6 +22,7 @@ import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
import org.apache.shenyu.plugin.base.support.BodyInserterContext;
import org.apache.shenyu.plugin.base.support.CachedBodyOutputMessage;
import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
@@ -96,10 +97,11 @@ public final class ResponseUtils {
* release source.
*
* @param outputMessage CachedBodyOutputMessage
+ * @param <T> the reified {@link Subscriber} type
* @param throwable Throwable
* @return Mono.
*/
- public static Mono<Void> release(final CachedBodyOutputMessage outputMessage, final Throwable throwable) {
+ public static <T> Mono<T> release(final CachedBodyOutputMessage outputMessage, final Throwable throwable) {
if (Boolean.TRUE.equals(outputMessage.getCache())) {
return outputMessage.getBody().map(DataBufferUtils::release).then(Mono.error(throwable));
}
diff --git a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/ServerWebExchangeUtils.java b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/ServerWebExchangeUtils.java
new file mode 100644
index 000000000..e90e0e0f4
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/ServerWebExchangeUtils.java
@@ -0,0 +1,63 @@
+/*
+ * 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.base.utils;
+
+import org.apache.shenyu.plugin.base.support.BodyInserterContext;
+import org.apache.shenyu.plugin.base.support.CachedBodyOutputMessage;
+import org.apache.shenyu.plugin.base.support.RequestDecorator;
+import org.springframework.http.ReactiveHttpOutputMessage;
+import org.springframework.http.codec.HttpMessageReader;
+import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
+import org.springframework.web.reactive.function.BodyInserter;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.server.ServerRequest;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+import java.util.function.Function;
+
+public class ServerWebExchangeUtils {
+
+ /**
+ * Rewrites Request Body.
+ * @param exchange serverWebExchange
+ * @param readers reader to read request-body
+ * @param convert convert body to new body
+ * @return Mono.
+ */
+ public static Mono<ServerWebExchange> rewriteRequestBody(final ServerWebExchange exchange,
+ final List<HttpMessageReader<?>> readers,
+ final Function<String, Mono<String>> convert) {
+
+ ServerRequest serverRequest = ServerRequest.create(exchange, readers);
+ CachedBodyOutputMessage outputMessage = ResponseUtils.newCachedBodyOutputMessage(exchange);
+
+ return serverRequest.bodyToMono(String.class)
+ .switchIfEmpty(Mono.defer(() -> Mono.just("")))
+ .flatMap(convert)
+ .flatMap(body -> {
+ BodyInserter<String, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromValue(body);
+ return bodyInserter.insert(outputMessage, new BodyInserterContext());
+ }).then(Mono.defer(() -> {
+ ServerHttpRequestDecorator decorator = new RequestDecorator(exchange, outputMessage);
+ return Mono.just(exchange.mutate().request(decorator).build());
+ })).onErrorResume(throwable -> ResponseUtils.release(outputMessage, throwable));
+
+ }
+}
diff --git a/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/SignPlugin.java b/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/SignPlugin.java
index 6d0bd9eea..5c14b14d2 100644
--- a/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/SignPlugin.java
+++ b/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/SignPlugin.java
@@ -27,29 +27,21 @@ import org.apache.shenyu.plugin.api.result.ShenyuResultEnum;
import org.apache.shenyu.plugin.api.result.ShenyuResultWrap;
import org.apache.shenyu.plugin.api.utils.WebFluxResultUtils;
import org.apache.shenyu.plugin.base.AbstractShenyuPlugin;
-import org.apache.shenyu.plugin.base.support.BodyInserterContext;
-import org.apache.shenyu.plugin.base.support.CachedBodyOutputMessage;
import org.apache.shenyu.plugin.base.utils.CacheKeyUtils;
-import org.apache.shenyu.plugin.base.utils.ResponseUtils;
+import org.apache.shenyu.plugin.base.utils.ServerWebExchangeUtils;
import org.apache.shenyu.plugin.sign.api.SignService;
-import org.apache.shenyu.plugin.sign.decorator.SignRequestDecorator;
+import org.apache.shenyu.plugin.sign.api.VerifyResult;
+import org.apache.shenyu.plugin.sign.exception.SignPluginException;
import org.apache.shenyu.plugin.sign.handler.SignPluginDataHandler;
import org.apache.shenyu.plugin.sign.handler.SignRuleHandler;
-import org.apache.shenyu.plugin.sign.api.VerifyResult;
-import org.springframework.http.ReactiveHttpOutputMessage;
import org.springframework.http.codec.HttpMessageReader;
-import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
-import org.springframework.web.reactive.function.BodyInserter;
-import org.springframework.web.reactive.function.BodyInserters;
-import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Map;
-import java.util.function.Function;
/**
* Sign Plugin.
@@ -92,16 +84,19 @@ public class SignPlugin extends AbstractShenyuPlugin {
return chain.execute(exchange);
}
- ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
- return serverRequest.bodyToMono(String.class)
- .switchIfEmpty(Mono.defer(() -> Mono.just("")))
- .flatMap(originalBody -> {
- VerifyResult result = signBody(originalBody, exchange);
- if (result.isSuccess()) {
- return executeChain(originalBody, exchange, chain);
- }
- return handleSignFailed(exchange, result.getReason());
- });
+ return ServerWebExchangeUtils.rewriteRequestBody(exchange, messageReaders, body -> {
+ VerifyResult result = signBody(body, exchange);
+ if (result.isSuccess()) {
+ return Mono.just(body);
+ }
+ throw new SignPluginException(result.getReason());
+ }).flatMap(chain::execute)
+ .onErrorResume(error -> {
+ if (error instanceof SignPluginException) {
+ return handleSignFailed(exchange, error.getMessage());
+ }
+ return Mono.error(error);
+ });
}
private VerifyResult signBody(final String originalBody, final ServerWebExchange exchange) {
@@ -113,17 +108,6 @@ public class SignPlugin extends AbstractShenyuPlugin {
return signService.signVerify(exchange, requestBody, queryParamsSingleValueMap);
}
- private Mono<Void> executeChain(final String requestBody, final ServerWebExchange exchange, final ShenyuPluginChain chain) {
- BodyInserter<String, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromValue(requestBody);
- CachedBodyOutputMessage outputMessage = ResponseUtils.newCachedBodyOutputMessage(exchange);
- return bodyInserter.insert(outputMessage, new BodyInserterContext())
- .then(Mono.defer(() -> {
- ServerHttpRequestDecorator decorator = new SignRequestDecorator(exchange, outputMessage);
- return chain.execute(exchange.mutate().request(decorator).build());
- }
- )).onErrorResume((Function<Throwable, Mono<Void>>) throwable -> ResponseUtils.release(outputMessage, throwable));
- }
-
private Mono<Void> handleSignFailed(final ServerWebExchange exchange, final String reason) {
Object error = ShenyuResultWrap.error(exchange, ShenyuResultEnum.SIGN_IS_NOT_PASS.getCode(), reason, null);
return WebFluxResultUtils.result(exchange, error);
diff --git a/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/exception/SignPluginException.java b/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/exception/SignPluginException.java
new file mode 100644
index 000000000..03f486fb7
--- /dev/null
+++ b/shenyu-plugin/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/exception/SignPluginException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.sign.exception;
+
+import org.apache.shenyu.common.exception.ShenyuException;
+
+public class SignPluginException extends ShenyuException {
+
+ public SignPluginException(final Throwable e) {
+ super(e);
+ }
+
+ public SignPluginException(final String message) {
+ super(message);
+ }
+
+ public SignPluginException(final String message, final Throwable throwable) {
+ super(message, throwable);
+ }
+}