mirror of https://github.com/halo-dev/halo
refactor: scanning of the jsBundleRule for plugins (#2249)
<!-- Thanks for sending a pull request! Here are some tips for you: 1. 如果这是你的第一次,请阅读我们的贡献指南:<https://github.com/halo-dev/halo/blob/master/CONTRIBUTING.md>。 1. If this is your first time, please read our contributor guidelines: <https://github.com/halo-dev/halo/blob/master/CONTRIBUTING.md>. 2. 请根据你解决问题的类型为 Pull Request 添加合适的标签。 2. Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request. 3. 请确保你已经添加并运行了适当的测试。 3. Ensure you have added or ran the appropriate tests for your PR. --> #### What type of PR is this? /kind improvement /area core /milestone 2.0 <!-- 添加其中一个类别: Add one of the following kinds: /kind bug /kind cleanup /kind documentation /kind feature /kind improvement 适当添加其中一个或多个类别(可选): Optionally add one or more of the following kinds if applicable: /kind api-change /kind deprecation /kind failing-test /kind flake /kind regression --> #### What this PR does / why we need it: 重构 JsBundle 获取方式,增加对 js entry 的文件校验如果不存在,则启用插件时不生成反向代理 APIs #### Which issue(s) this PR fixes: <!-- PR 合并时自动关闭 issue。 Automatically closes linked issue when PR is merged. 用法:`Fixes #<issue 号>`,或者 `Fixes (粘贴 issue 完整链接)` Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`. --> Fixes # #### Special notes for your reviewer: /cc @halo-dev/sig-halo #### Does this PR introduce a user-facing change? <!-- 如果当前 Pull Request 的修改不会造成用户侧的任何变更,在 `release-note` 代码块儿中填写 `NONE`。 否则请填写用户侧能够理解的 Release Note。如果当前 Pull Request 包含破坏性更新(Break Change), Release Note 需要以 `action required` 开头。 If no, just write "NONE" in the release-note block below. If yes, a release note is required: Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required". --> ```release-note None ```pull/2264/head
parent
1571b9bcf8
commit
275df33d75
|
@ -44,7 +44,7 @@ public class Plugin extends AbstractExtension {
|
|||
@JsonIgnore
|
||||
public PluginStatus statusNonNull() {
|
||||
if (this.status == null) {
|
||||
return new PluginStatus();
|
||||
this.status = new PluginStatus();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -87,7 +87,8 @@ public class Plugin extends AbstractExtension {
|
|||
@NonNull
|
||||
@JsonIgnore
|
||||
public List<String> extensionLocationsNonNull() {
|
||||
return Objects.requireNonNullElseGet(extensionLocations, List::of);
|
||||
this.extensionLocations = Objects.requireNonNullElseGet(extensionLocations, List::of);
|
||||
return this.extensionLocations;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,14 +10,12 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.pf4j.PluginRuntimeException;
|
||||
import org.pf4j.PluginState;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.pf4j.RuntimeMode;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.ExtensionClient;
|
||||
import run.halo.app.extension.controller.Reconciler;
|
||||
import run.halo.app.infra.utils.JsonUtils;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.PluginStartingError;
|
||||
import run.halo.app.plugin.YamlPluginFinder;
|
||||
import run.halo.app.plugin.resources.JsBundleRuleProvider;
|
||||
import run.halo.app.plugin.resources.ReverseProxyRouterFunctionFactory;
|
||||
|
||||
|
@ -83,8 +81,6 @@ public class PluginReconciler implements Reconciler {
|
|||
return;
|
||||
}
|
||||
|
||||
ensureSpecUpToDateWhenDevelopmentMode(pluginWrapper, plugin);
|
||||
|
||||
if (!Objects.equals(pluginStatus.getPhase(), pluginWrapper.getPluginState())) {
|
||||
// Set to the correct state
|
||||
pluginStatus.setPhase(pluginWrapper.getPluginState());
|
||||
|
@ -134,12 +130,14 @@ public class PluginReconciler implements Reconciler {
|
|||
Plugin.PluginStatus status = plugin.statusNonNull();
|
||||
// TODO Check whether the JS bundle rule exists. If it does not exist, do not populate
|
||||
// populate stylesheet path
|
||||
String jsBundleRoute = ReverseProxyRouterFunctionFactory.buildRoutePath(pluginName,
|
||||
jsBundleRule.jsRule(pluginName));
|
||||
String cssBundleRoute = ReverseProxyRouterFunctionFactory.buildRoutePath(pluginName,
|
||||
jsBundleRule.cssRule(pluginName));
|
||||
status.setEntry(jsBundleRoute);
|
||||
status.setStylesheet(cssBundleRoute);
|
||||
jsBundleRule.jsRule(pluginName)
|
||||
.map(jsRule -> ReverseProxyRouterFunctionFactory.buildRoutePath(pluginName, jsRule))
|
||||
.ifPresent(status::setEntry);
|
||||
|
||||
jsBundleRule.cssRule(pluginName)
|
||||
.map(cssRule -> ReverseProxyRouterFunctionFactory.buildRoutePath(pluginName, cssRule))
|
||||
.ifPresent(status::setStylesheet);
|
||||
|
||||
status.setLastStartTime(Instant.now());
|
||||
}
|
||||
|
||||
|
@ -170,18 +168,4 @@ public class PluginReconciler implements Reconciler {
|
|||
throw new PluginRuntimeException(startingError.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureSpecUpToDateWhenDevelopmentMode(PluginWrapper pluginWrapper,
|
||||
Plugin oldPlugin) {
|
||||
if (RuntimeMode.DEPLOYMENT.equals(pluginWrapper.getRuntimeMode())) {
|
||||
return;
|
||||
}
|
||||
YamlPluginFinder yamlPluginFinder = new YamlPluginFinder();
|
||||
Plugin pluginFromPath = yamlPluginFinder.find(pluginWrapper.getPluginPath());
|
||||
// ensure plugin spec is up to date
|
||||
Plugin.PluginSpec pluginSpec = JsonUtils.deepCopy(pluginFromPath.getSpec());
|
||||
if (!Objects.equals(oldPlugin.getSpec(), pluginSpec)) {
|
||||
oldPlugin.setSpec(pluginSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package run.halo.app.plugin.resources;
|
||||
|
||||
import java.util.Optional;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.core.extension.ReverseProxy;
|
||||
import run.halo.app.core.extension.ReverseProxy.FileReverseProxyProvider;
|
||||
import run.halo.app.core.extension.ReverseProxy.ReverseProxyRule;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
|
||||
/**
|
||||
* TODO Optimize code to support user customize js bundle rules.
|
||||
|
@ -11,6 +17,20 @@ import run.halo.app.core.extension.ReverseProxy;
|
|||
*/
|
||||
@Component
|
||||
public class JsBundleRuleProvider {
|
||||
private static final String JS_LOCATION = "/admin/main.js";
|
||||
private static final String CSS_LOCATION = "/admin/style.css";
|
||||
|
||||
private static final FileReverseProxyProvider JS_FILE_PROXY =
|
||||
new FileReverseProxyProvider("admin", "main.js");
|
||||
|
||||
private static final FileReverseProxyProvider CSS_FILE_PROXY =
|
||||
new FileReverseProxyProvider("admin", "style.css");
|
||||
|
||||
private final HaloPluginManager haloPluginManager;
|
||||
|
||||
public JsBundleRuleProvider(HaloPluginManager haloPluginManager) {
|
||||
this.haloPluginManager = haloPluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plugin js bundle rule.
|
||||
|
@ -18,10 +38,11 @@ public class JsBundleRuleProvider {
|
|||
* @param pluginName plugin name
|
||||
* @return a js bundle rule
|
||||
*/
|
||||
public ReverseProxy.ReverseProxyRule jsRule(String pluginName) {
|
||||
ReverseProxy.FileReverseProxyProvider
|
||||
file = new ReverseProxy.FileReverseProxyProvider("admin", "main.js");
|
||||
return new ReverseProxy.ReverseProxyRule("/admin/main.js", file);
|
||||
public Optional<ReverseProxyRule> jsRule(String pluginName) {
|
||||
return Optional.of(JS_LOCATION)
|
||||
.filter(path -> createResourceLoader(pluginName)
|
||||
.getResource(path).exists())
|
||||
.map(path -> new ReverseProxyRule(path, JS_FILE_PROXY));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,9 +51,21 @@ public class JsBundleRuleProvider {
|
|||
* @param pluginName plugin name
|
||||
* @return a stylesheet bundle rule
|
||||
*/
|
||||
public ReverseProxy.ReverseProxyRule cssRule(String pluginName) {
|
||||
ReverseProxy.FileReverseProxyProvider
|
||||
file = new ReverseProxy.FileReverseProxyProvider("admin", "style.css");
|
||||
return new ReverseProxy.ReverseProxyRule("/admin/style.css", file);
|
||||
public Optional<ReverseProxyRule> cssRule(String pluginName) {
|
||||
return Optional.of(CSS_LOCATION)
|
||||
.filter(path -> createResourceLoader(pluginName)
|
||||
.getResource(path)
|
||||
.exists())
|
||||
.map(path -> new ReverseProxyRule(path, CSS_FILE_PROXY));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private DefaultResourceLoader createResourceLoader(String pluginName) {
|
||||
PluginWrapper plugin = haloPluginManager.getPlugin(pluginName);
|
||||
if (plugin == null) {
|
||||
return new DefaultResourceLoader();
|
||||
}
|
||||
return new DefaultResourceLoader(plugin.getPluginClassLoader());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -114,15 +114,8 @@ public class ReverseProxyRouterFunctionFactory {
|
|||
|
||||
private List<ReverseProxyRule> getJsBundleRules(String pluginId) {
|
||||
List<ReverseProxyRule> rules = new ArrayList<>(2);
|
||||
ReverseProxyRule jsRule = jsBundleRuleProvider.jsRule(pluginId);
|
||||
if (jsRule != null) {
|
||||
rules.add(jsRule);
|
||||
}
|
||||
|
||||
ReverseProxyRule cssRule = jsBundleRuleProvider.cssRule(pluginId);
|
||||
if (cssRule != null) {
|
||||
rules.add(cssRule);
|
||||
}
|
||||
jsBundleRuleProvider.jsRule(pluginId).ifPresent(rules::add);
|
||||
jsBundleRuleProvider.cssRule(pluginId).ifPresent(rules::add);
|
||||
return rules;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.mockito.Mock;
|
|||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.pf4j.PluginState;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.pf4j.RuntimeMode;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.ExtensionClient;
|
||||
import run.halo.app.extension.controller.Reconciler;
|
||||
|
@ -50,11 +49,10 @@ class PluginReconcilerTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
JsBundleRuleProvider jsBundleRule = new JsBundleRuleProvider();
|
||||
JsBundleRuleProvider jsBundleRule = new JsBundleRuleProvider(haloPluginManager);
|
||||
pluginReconciler = new PluginReconciler(extensionClient, haloPluginManager, jsBundleRule);
|
||||
|
||||
when(haloPluginManager.getPlugin(any())).thenReturn(pluginWrapper);
|
||||
when(pluginWrapper.getRuntimeMode()).thenReturn(RuntimeMode.DEPLOYMENT);
|
||||
when(haloPluginManager.getUnresolvedPlugins()).thenReturn(List.of());
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
|||
import run.halo.app.core.extension.ReverseProxy;
|
||||
import run.halo.app.extension.ExtensionClient;
|
||||
import run.halo.app.extension.Metadata;
|
||||
import run.halo.app.plugin.HaloPluginManager;
|
||||
import run.halo.app.plugin.PluginApplicationContext;
|
||||
import run.halo.app.plugin.PluginConst;
|
||||
|
||||
|
@ -34,12 +35,14 @@ class ReverseProxyRouterFunctionFactoryTest {
|
|||
|
||||
@Mock
|
||||
private PluginApplicationContext pluginApplicationContext;
|
||||
@Mock
|
||||
private HaloPluginManager haloPluginManager;
|
||||
|
||||
private ReverseProxyRouterFunctionFactory reverseProxyRouterFunctionFactory;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
JsBundleRuleProvider jsBundleRuleProvider = new JsBundleRuleProvider();
|
||||
JsBundleRuleProvider jsBundleRuleProvider = new JsBundleRuleProvider(haloPluginManager);
|
||||
reverseProxyRouterFunctionFactory = new ReverseProxyRouterFunctionFactory(extensionClient,
|
||||
jsBundleRuleProvider);
|
||||
|
||||
|
|
Loading…
Reference in New Issue