mirror of https://github.com/halo-dev/halo
feat: add plugin status manage (#2177)
* feat: add plugin status manage * feat: add plugin state changed listener * refactor: plugin status * refactor: pluginpull/2190/head
parent
c24df6fb05
commit
273ffaad48
|
@ -1,7 +1,8 @@
|
|||
package run.halo.app.plugin;
|
||||
package run.halo.app.core.extension;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -10,8 +11,10 @@ import lombok.EqualsAndHashCode;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.pf4j.PluginState;
|
||||
import run.halo.app.extension.AbstractExtension;
|
||||
import run.halo.app.extension.GVK;
|
||||
import run.halo.app.plugin.BasePlugin;
|
||||
|
||||
/**
|
||||
* A custom resource for Plugin.
|
||||
|
@ -29,6 +32,8 @@ public class Plugin extends AbstractExtension {
|
|||
@Schema(required = true)
|
||||
private PluginSpec spec;
|
||||
|
||||
private PluginStatus status;
|
||||
|
||||
@Data
|
||||
public static class PluginSpec {
|
||||
|
||||
|
@ -55,6 +60,8 @@ public class Plugin extends AbstractExtension {
|
|||
private String requires = "*";
|
||||
|
||||
private String pluginClass = BasePlugin.class.getName();
|
||||
|
||||
private Boolean enabled = false;
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
@ -71,4 +78,22 @@ public class Plugin extends AbstractExtension {
|
|||
this.url = "";
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class PluginStatus {
|
||||
|
||||
private PluginState phase;
|
||||
|
||||
private String reason;
|
||||
|
||||
private String message;
|
||||
|
||||
private Instant lastStartTime;
|
||||
|
||||
private Instant lastTransitionTime;
|
||||
|
||||
private String entry;
|
||||
|
||||
private String stylesheet;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package run.halo.app.plugin.resources;
|
||||
package run.halo.app.core.extension;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
@ -21,9 +21,9 @@ import run.halo.app.extension.GVK;
|
|||
public class ReverseProxy extends AbstractExtension {
|
||||
private List<ReverseProxyRule> rules;
|
||||
|
||||
record ReverseProxyRule(String path, FileReverseProxyProvider file) {
|
||||
public record ReverseProxyRule(String path, FileReverseProxyProvider file) {
|
||||
}
|
||||
|
||||
record FileReverseProxyProvider(String directory, String filename) {
|
||||
public record FileReverseProxyProvider(String directory, String filename) {
|
||||
}
|
||||
}
|
|
@ -4,11 +4,12 @@ import org.springframework.boot.context.event.ApplicationStartedEvent;
|
|||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.core.extension.ReverseProxy;
|
||||
import run.halo.app.core.extension.Role;
|
||||
import run.halo.app.core.extension.RoleBinding;
|
||||
import run.halo.app.core.extension.User;
|
||||
import run.halo.app.extension.SchemeManager;
|
||||
import run.halo.app.plugin.Plugin;
|
||||
import run.halo.app.security.authentication.pat.PersonalAccessToken;
|
||||
|
||||
@Component
|
||||
|
@ -27,5 +28,6 @@ public class SchemeInitializer implements ApplicationListener<ApplicationStarted
|
|||
schemeManager.register(Plugin.class);
|
||||
schemeManager.register(RoleBinding.class);
|
||||
schemeManager.register(User.class);
|
||||
schemeManager.register(ReverseProxy.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ package run.halo.app.plugin;
|
|||
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.ExtensionClient;
|
||||
|
||||
/**
|
||||
* Load plugins after application ready.
|
||||
|
@ -14,14 +17,29 @@ import org.springframework.stereotype.Component;
|
|||
public class PluginInitializationLoadOnApplicationReady
|
||||
implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
private final PluginService pluginService;
|
||||
|
||||
private final HaloPluginManager haloPluginManager;
|
||||
|
||||
public PluginInitializationLoadOnApplicationReady(HaloPluginManager haloPluginManager) {
|
||||
private final ExtensionClient extensionClient;
|
||||
|
||||
public PluginInitializationLoadOnApplicationReady(PluginService pluginService,
|
||||
HaloPluginManager haloPluginManager, ExtensionClient extensionClient) {
|
||||
this.pluginService = pluginService;
|
||||
this.haloPluginManager = haloPluginManager;
|
||||
this.extensionClient = extensionClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
||||
public void onApplicationEvent(@NonNull ApplicationReadyEvent event) {
|
||||
haloPluginManager.loadPlugins();
|
||||
initStartupPlugins();
|
||||
}
|
||||
|
||||
private void initStartupPlugins() {
|
||||
extensionClient.list(Plugin.class,
|
||||
predicate -> predicate.getSpec().getEnabled(),
|
||||
null)
|
||||
.forEach(plugin -> pluginService.startup(plugin.getMetadata().getName()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,12 @@ package run.halo.app.plugin;
|
|||
|
||||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.pf4j.PluginState;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
|
||||
/**
|
||||
* Plugin manager controller.
|
||||
|
@ -20,13 +21,10 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
@RequestMapping("/apis/plugin.halo.run/v1alpha1/plugins")
|
||||
public class PluginLifeCycleManagerController {
|
||||
|
||||
private final PluginServiceImpl pluginService;
|
||||
private final HaloPluginManager pluginManager;
|
||||
private final PluginService pluginService;
|
||||
|
||||
public PluginLifeCycleManagerController(PluginServiceImpl pluginService,
|
||||
HaloPluginManager pluginManager) {
|
||||
public PluginLifeCycleManagerController(PluginService pluginService) {
|
||||
this.pluginService = pluginService;
|
||||
this.pluginManager = pluginManager;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
|
@ -34,13 +32,13 @@ public class PluginLifeCycleManagerController {
|
|||
return pluginService.list();
|
||||
}
|
||||
|
||||
@GetMapping("/{pluginName}/startup")
|
||||
public PluginState start(@PathVariable String pluginName) {
|
||||
return pluginManager.startPlugin(pluginName);
|
||||
@PutMapping("/{pluginName}/startup")
|
||||
public Plugin start(@PathVariable String pluginName) {
|
||||
return pluginService.startup(pluginName);
|
||||
}
|
||||
|
||||
@GetMapping("/{pluginName}/stop")
|
||||
public PluginState stop(@PathVariable String pluginName) {
|
||||
return pluginManager.stopPlugin(pluginName);
|
||||
@PutMapping("/{pluginName}/stop")
|
||||
public Plugin stop(@PathVariable String pluginName) {
|
||||
return pluginService.stop(pluginName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,10 @@ package run.halo.app.plugin;
|
|||
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.ExtensionClient;
|
||||
import run.halo.app.extension.SchemeManager;
|
||||
import run.halo.app.infra.utils.YamlUnstructuredLoader;
|
||||
import run.halo.app.plugin.event.HaloPluginLoadedEvent;
|
||||
import run.halo.app.plugin.resources.ReverseProxy;
|
||||
|
||||
/**
|
||||
* @author guqing
|
||||
|
@ -17,15 +13,13 @@ import run.halo.app.plugin.resources.ReverseProxy;
|
|||
*/
|
||||
@Component
|
||||
public class PluginLoadedListener implements ApplicationListener<HaloPluginLoadedEvent> {
|
||||
private static final String REVERSE_PROXY_NAME = "extensions/reverseProxy.yaml";
|
||||
private final ExtensionClient extensionClient;
|
||||
|
||||
public PluginLoadedListener(ExtensionClient extensionClient, SchemeManager schemeManager) {
|
||||
this.extensionClient = extensionClient;
|
||||
private final PluginUnstructuredResourceLoader pluginUnstructuredResourceLoader;
|
||||
|
||||
// TODO Optimize schemes register
|
||||
schemeManager.register(Plugin.class);
|
||||
schemeManager.register(ReverseProxy.class);
|
||||
public PluginLoadedListener(ExtensionClient extensionClient) {
|
||||
this.extensionClient = extensionClient;
|
||||
pluginUnstructuredResourceLoader = new PluginUnstructuredResourceLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,14 +29,10 @@ public class PluginLoadedListener implements ApplicationListener<HaloPluginLoade
|
|||
// load plugin.yaml
|
||||
YamlPluginFinder yamlPluginFinder = new YamlPluginFinder();
|
||||
Plugin plugin = yamlPluginFinder.find(pluginWrapper.getPluginPath());
|
||||
DefaultResourceLoader defaultResourceLoader =
|
||||
new DefaultResourceLoader(pluginWrapper.getPluginClassLoader());
|
||||
extensionClient.create(plugin);
|
||||
// load reverse proxy
|
||||
Resource resource = defaultResourceLoader.getResource(REVERSE_PROXY_NAME);
|
||||
if (resource.exists()) {
|
||||
YamlUnstructuredLoader unstructuredLoader = new YamlUnstructuredLoader(resource);
|
||||
unstructuredLoader.load().forEach(extensionClient::create);
|
||||
}
|
||||
|
||||
// load plugin unstructured resource
|
||||
pluginUnstructuredResourceLoader.loadUnstructured(pluginWrapper)
|
||||
.forEach(extensionClient::create);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package run.halo.app.plugin;
|
||||
|
||||
import org.pf4j.PluginRuntimeException;
|
||||
|
||||
/**
|
||||
* Exception for plugin not found.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class PluginNotFoundException extends PluginRuntimeException {
|
||||
public PluginNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PluginNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package run.halo.app.plugin;
|
||||
|
||||
import java.util.List;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
|
||||
/**
|
||||
* Service for plugin.
|
||||
|
@ -16,4 +17,22 @@ public interface PluginService {
|
|||
* @return all loaded plugins.
|
||||
*/
|
||||
List<Plugin> list();
|
||||
|
||||
/**
|
||||
* Start the plugin according to the plugin name.
|
||||
*
|
||||
* @param pluginName plugin name
|
||||
* @return plugin custom resource
|
||||
*/
|
||||
Plugin startup(String pluginName);
|
||||
|
||||
Plugin stop(String pluginName);
|
||||
|
||||
/**
|
||||
* Gets {@link Plugin} by plugin name.
|
||||
*
|
||||
* @param pluginName plugin name
|
||||
* @return plugin custom resource
|
||||
*/
|
||||
Plugin getByName(String pluginName);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package run.halo.app.plugin;
|
||||
|
||||
import java.util.List;
|
||||
import org.pf4j.PluginState;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.ExtensionClient;
|
||||
import run.halo.app.plugin.resources.JsBundleRuleProvider;
|
||||
import run.halo.app.plugin.resources.ReverseProxyRouterFunctionFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link PluginService}.
|
||||
|
@ -15,8 +20,15 @@ public class PluginServiceImpl implements PluginService {
|
|||
|
||||
private final ExtensionClient extensionClient;
|
||||
|
||||
public PluginServiceImpl(ExtensionClient extensionClient) {
|
||||
private final HaloPluginManager haloPluginManager;
|
||||
|
||||
private final JsBundleRuleProvider jsBundleRule;
|
||||
|
||||
public PluginServiceImpl(ExtensionClient extensionClient,
|
||||
HaloPluginManager haloPluginManager, JsBundleRuleProvider jsBundleRule) {
|
||||
this.extensionClient = extensionClient;
|
||||
this.haloPluginManager = haloPluginManager;
|
||||
this.jsBundleRule = jsBundleRule;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,4 +39,59 @@ public class PluginServiceImpl implements PluginService {
|
|||
public List<Plugin> list() {
|
||||
return extensionClient.list(Plugin.class, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin startup(String pluginName) {
|
||||
Assert.notNull(pluginName, "The pluginName must not be null.");
|
||||
PluginState currentState = haloPluginManager.startPlugin(pluginName);
|
||||
|
||||
Plugin plugin = handleStatus(pluginName, currentState, PluginState.STARTED);
|
||||
Plugin.PluginStatus status = plugin.getStatus();
|
||||
// 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);
|
||||
extensionClient.update(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
private Plugin handleStatus(String pluginName, PluginState currentState,
|
||||
PluginState desiredState) {
|
||||
Plugin plugin = getByName(pluginName);
|
||||
Plugin.PluginStatus status = plugin.getStatus();
|
||||
if (status == null) {
|
||||
status = new Plugin.PluginStatus();
|
||||
}
|
||||
status.setPhase(currentState);
|
||||
if (desiredState.equals(currentState)) {
|
||||
plugin.getSpec().setEnabled(true);
|
||||
} else {
|
||||
PluginStartingError startingError =
|
||||
haloPluginManager.getPluginStartingError(pluginName);
|
||||
status.setReason(startingError.getMessage());
|
||||
status.setMessage(startingError.getDevMessage());
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin stop(String pluginName) {
|
||||
Assert.notNull(pluginName, "The pluginName must not be null.");
|
||||
PluginState currentState = haloPluginManager.stopPlugin(pluginName);
|
||||
Plugin plugin = handleStatus(pluginName, currentState, PluginState.STOPPED);
|
||||
extensionClient.update(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getByName(String pluginName) {
|
||||
Assert.notNull(pluginName, "The pluginName must not be null.");
|
||||
return extensionClient.fetch(Plugin.class, pluginName)
|
||||
.orElseThrow(() ->
|
||||
new PluginNotFoundException(String.format("Plugin [%s] not found", pluginName)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.pf4j.PluginDescriptor;
|
|||
import org.pf4j.PluginDescriptorFinder;
|
||||
import org.pf4j.util.FileUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
|
||||
/**
|
||||
* Find a plugin descriptor for a plugin path.
|
||||
|
|
|
@ -7,9 +7,11 @@ import java.nio.file.Paths;
|
|||
import java.util.List;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.pf4j.PluginRuntimeException;
|
||||
import org.pf4j.PluginState;
|
||||
import org.pf4j.util.FileUtils;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.Unstructured;
|
||||
import run.halo.app.infra.utils.YamlUnstructuredLoader;
|
||||
|
||||
|
@ -58,7 +60,13 @@ public class YamlPluginFinder {
|
|||
}
|
||||
|
||||
public Plugin find(Path pluginPath) {
|
||||
return readPluginDescriptor(pluginPath);
|
||||
Plugin plugin = readPluginDescriptor(pluginPath);
|
||||
if (plugin.getStatus() == null) {
|
||||
Plugin.PluginStatus pluginStatus = new Plugin.PluginStatus();
|
||||
pluginStatus.setPhase(PluginState.RESOLVED);
|
||||
plugin.setStatus(pluginStatus);
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
protected Plugin readPluginDescriptor(Path pluginPath) {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package run.halo.app.plugin.resources;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import run.halo.app.core.extension.ReverseProxy;
|
||||
|
||||
/**
|
||||
* TODO Optimize code to support user customize js bundle rules.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Component
|
||||
public class JsBundleRuleProvider {
|
||||
|
||||
/**
|
||||
* Gets plugin js bundle rule.
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plugin stylesheet rule.
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import static org.springframework.http.MediaType.ALL;
|
|||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -18,11 +19,12 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
|||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
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.extension.ExtensionClient;
|
||||
import run.halo.app.infra.utils.PathUtils;
|
||||
import run.halo.app.plugin.PluginApplicationContext;
|
||||
import run.halo.app.plugin.resources.ReverseProxy.FileReverseProxyProvider;
|
||||
import run.halo.app.plugin.resources.ReverseProxy.ReverseProxyRule;
|
||||
|
||||
/**
|
||||
* <p>Plugin's reverse proxy router factory.</p>
|
||||
|
@ -41,8 +43,12 @@ public class ReverseProxyRouterFunctionFactory {
|
|||
|
||||
private final ExtensionClient extensionClient;
|
||||
|
||||
public ReverseProxyRouterFunctionFactory(ExtensionClient extensionClient) {
|
||||
private final JsBundleRuleProvider jsBundleRuleProvider;
|
||||
|
||||
public ReverseProxyRouterFunctionFactory(ExtensionClient extensionClient,
|
||||
JsBundleRuleProvider jsBundleRuleProvider) {
|
||||
this.extensionClient = extensionClient;
|
||||
this.jsBundleRuleProvider = jsBundleRuleProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +95,7 @@ public class ReverseProxyRouterFunctionFactory {
|
|||
}
|
||||
|
||||
private List<ReverseProxyRule> getReverseProxyRules(String pluginId) {
|
||||
return extensionClient.list(ReverseProxy.class,
|
||||
List<ReverseProxyRule> rules = extensionClient.list(ReverseProxy.class,
|
||||
reverseProxy -> {
|
||||
String pluginName = reverseProxy.getMetadata()
|
||||
.getLabels()
|
||||
|
@ -101,9 +107,27 @@ public class ReverseProxyRouterFunctionFactory {
|
|||
.map(ReverseProxy::getRules)
|
||||
.flatMap(List::stream)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// populate plugin js bundle rules.
|
||||
rules.addAll(getJsBundleRules(pluginId));
|
||||
return rules;
|
||||
}
|
||||
|
||||
private String buildRoutePath(String pluginId, ReverseProxyRule reverseProxyRule) {
|
||||
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);
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
public static String buildRoutePath(String pluginId, ReverseProxyRule reverseProxyRule) {
|
||||
return PathUtils.combinePath(REVERSE_PROXY_API_PREFIX, pluginId, reverseProxyRule.path());
|
||||
}
|
||||
|
||||
|
|
|
@ -68,19 +68,19 @@ class PluginLifeCycleManagerControllerTest {
|
|||
|
||||
@Test
|
||||
void start() {
|
||||
webClient.get()
|
||||
webClient.put()
|
||||
.uri(prefix + "/apples/startup")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk();
|
||||
.is5xxServerError();
|
||||
}
|
||||
|
||||
@Test
|
||||
void stop() {
|
||||
webClient.get()
|
||||
webClient.put()
|
||||
.uri(prefix + "/apples/stop")
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk();
|
||||
.is5xxServerError();
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ import org.skyscreamer.jsonassert.JSONAssert;
|
|||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.security.util.InMemoryResource;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import run.halo.app.core.extension.Plugin;
|
||||
import run.halo.app.extension.Unstructured;
|
||||
import run.halo.app.infra.utils.JsonUtils;
|
||||
|
||||
|
@ -52,12 +53,24 @@ class YamlPluginFinderTest {
|
|||
},
|
||||
"homepage": "https://github.com/guqing/halo-plugin-1",
|
||||
"description": "Tell me more about this plugin.",
|
||||
"license": [{
|
||||
"license": [
|
||||
{
|
||||
"name": "MIT",
|
||||
"url": ""
|
||||
}],
|
||||
}
|
||||
],
|
||||
"requires": ">=2.0.0",
|
||||
"pluginClass": "run.halo.app.plugin.BasePlugin"
|
||||
"pluginClass": "run.halo.app.plugin.BasePlugin",
|
||||
"enabled": false
|
||||
},
|
||||
"status": {
|
||||
"phase": "RESOLVED",
|
||||
"reason": null,
|
||||
"message": null,
|
||||
"lastStartTime": null,
|
||||
"lastTransitionTime": null,
|
||||
"entry": null,
|
||||
"stylesheet": null
|
||||
},
|
||||
"apiVersion": "plugin.halo.run/v1alpha1",
|
||||
"kind": "Plugin",
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.mockito.Mock;
|
|||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
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.PluginApplicationContext;
|
||||
|
@ -37,7 +38,9 @@ class ReverseProxyRouterFunctionFactoryTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
reverseProxyRouterFunctionFactory = new ReverseProxyRouterFunctionFactory(extensionClient);
|
||||
JsBundleRuleProvider jsBundleRuleProvider = new JsBundleRuleProvider();
|
||||
reverseProxyRouterFunctionFactory = new ReverseProxyRouterFunctionFactory(extensionClient,
|
||||
jsBundleRuleProvider);
|
||||
|
||||
ReverseProxy reverseProxy = mockReverseProxy();
|
||||
|
||||
|
|
Loading…
Reference in New Issue