From ff7ab4e4f18200242e45881a149f6f259df28309 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Mon, 26 Jun 2023 22:01:57 +0800 Subject: [PATCH] refactor: support for custom api group in plugin controllers (#4065) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.7.x #### What this PR does / why we need it: 插件的 Controllers 支持自定义 API Group 如: ```java @RestController @ApiVersion("fake.halo.run/v1") @RequestMapping("/fake") public class DemoController { } ``` 则生成路由为 `/apis/fake.halo.run/v1/fake` 如果没有 group 默认兼容以前的为 `/apis/api.plugin.halo.run/{version}/plugins/{pluginName}/**` ```java @RestController @ApiVersion("v1alpha1") @RequestMapping("/fake") public class DemoController { } ``` #### Which issue(s) this PR fixes: Fixes #4053 #### Does this PR introduce a user-facing change? ```release-note 插件的 Controllers 支持自定义 API Group ``` --- .../PluginRequestMappingHandlerMapping.java | 15 +++++++----- ...luginRequestMappingHandlerMappingTest.java | 24 ++++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/application/src/main/java/run/halo/app/plugin/PluginRequestMappingHandlerMapping.java b/application/src/main/java/run/halo/app/plugin/PluginRequestMappingHandlerMapping.java index 56ffe6a39..b8a273cf8 100644 --- a/application/src/main/java/run/halo/app/plugin/PluginRequestMappingHandlerMapping.java +++ b/application/src/main/java/run/halo/app/plugin/PluginRequestMappingHandlerMapping.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; -import org.pf4j.PluginRuntimeException; import org.springframework.aop.support.AopUtils; import org.springframework.core.MethodIntrospector; import org.springframework.stereotype.Controller; @@ -117,8 +116,7 @@ public class PluginRequestMappingHandlerMapping extends RequestMappingHandlerMap if (info != null) { ApiVersion apiVersion = handlerType.getAnnotation(ApiVersion.class); if (apiVersion == null) { - throw new PluginRuntimeException( - "The handler [" + handlerType + "] is missing @ApiVersion annotation."); + return info; } info = RequestMappingInfo.paths(buildPrefix(pluginId, apiVersion.value())).build() .combine(info); @@ -126,9 +124,14 @@ public class PluginRequestMappingHandlerMapping extends RequestMappingHandlerMap return info; } - protected String buildPrefix(String pluginId, String version) { - GroupVersion groupVersion = GroupVersion.parseAPIVersion(version); + protected String buildPrefix(String pluginName, String apiVersion) { + GroupVersion groupVersion = GroupVersion.parseAPIVersion(apiVersion); + if (StringUtils.hasText(groupVersion.group())) { + // apis/{group}/{version} + return String.format("/apis/%s/%s", groupVersion.group(), groupVersion.version()); + } + // apis/api.plugin.halo.run/{version}/plugins/{pluginName} return String.format("/apis/api.plugin.halo.run/%s/plugins/%s", groupVersion.version(), - pluginId); + pluginName); } } diff --git a/application/src/test/java/run/halo/app/plugin/PluginRequestMappingHandlerMappingTest.java b/application/src/test/java/run/halo/app/plugin/PluginRequestMappingHandlerMappingTest.java index b73de8009..524bda5ff 100644 --- a/application/src/test/java/run/halo/app/plugin/PluginRequestMappingHandlerMappingTest.java +++ b/application/src/test/java/run/halo/app/plugin/PluginRequestMappingHandlerMappingTest.java @@ -1,7 +1,6 @@ package run.halo.app.plugin; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.springframework.mock.http.server.reactive.MockServerHttpRequest.get; import static org.springframework.mock.http.server.reactive.MockServerHttpRequest.post; @@ -20,7 +19,6 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.pf4j.PluginRuntimeException; import org.springframework.core.MethodIntrospector; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.http.HttpMethod; @@ -74,15 +72,14 @@ class PluginRequestMappingHandlerMappingTest { } @Test - public void shouldFailWhenMissingApiVersion() throws Exception { + public void shouldKeepRawWhenMissingApiVersion() throws Exception { Method method = AppleMissingApiVersionController.class.getMethod("getName"); - assertThatThrownBy(() -> + RequestMappingInfo info = this.handlerMapping.getPluginMappingForMethod("fakePlugin", method, - AppleMissingApiVersionController.class)).isInstanceOf(PluginRuntimeException.class) - .hasMessage( - "The handler [class run.halo.app.plugin" - + ".PluginRequestMappingHandlerMappingTest$AppleMissingApiVersionController] " - + "is missing @ApiVersion annotation."); + AppleMissingApiVersionController.class); + + assertThat(info.getPatternsCondition().getPatterns()) + .isEqualTo(Collections.singleton(new PathPatternParser().parse("/apples"))); } @Test @@ -174,6 +171,15 @@ class PluginRequestMappingHandlerMappingTest { Set.of(HttpMethod.GET, HttpMethod.HEAD))); } + @Test + void buildPrefix() { + String s = handlerMapping.buildPrefix("fakePlugin", "v1"); + assertThat(s).isEqualTo("/apis/api.plugin.halo.run/v1/plugins/fakePlugin"); + + s = handlerMapping.buildPrefix("fakePlugin", "fake.halo.run/v1alpha1"); + assertThat(s).isEqualTo("/apis/fake.halo.run/v1alpha1"); + } + @SuppressWarnings("unchecked") private void assertError(Mono mono, final Class exceptionClass, final Consumer consumer) {