mirror of https://github.com/halo-dev/halo
Refactor reconcilers registration (#2737)
#### What type of PR is this? /kind cleanup /kind improvement /area core /milestone 2.0.0 #### What this PR does / why we need it: This PR mainly refactors registration of reconcilers to register reconciler more convinient. After that, it is possible to reigster and start reconciler in plugin. #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/2305 #### Does this PR introduce a user-facing change? ```release-note None ```pull/2746/head^2
parent
98db7c6aff
commit
0df7857ef8
|
@ -1,65 +1,18 @@
|
||||||
package run.halo.app.config;
|
package run.halo.app.config;
|
||||||
|
|
||||||
import io.micrometer.core.instrument.MeterRegistry;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
import run.halo.app.content.ContentService;
|
|
||||||
import run.halo.app.content.PostService;
|
|
||||||
import run.halo.app.content.permalinks.CategoryPermalinkPolicy;
|
|
||||||
import run.halo.app.content.permalinks.PostPermalinkPolicy;
|
|
||||||
import run.halo.app.content.permalinks.TagPermalinkPolicy;
|
|
||||||
import run.halo.app.core.extension.Category;
|
|
||||||
import run.halo.app.core.extension.Comment;
|
|
||||||
import run.halo.app.core.extension.Menu;
|
|
||||||
import run.halo.app.core.extension.MenuItem;
|
|
||||||
import run.halo.app.core.extension.Plugin;
|
|
||||||
import run.halo.app.core.extension.Post;
|
|
||||||
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.SinglePage;
|
|
||||||
import run.halo.app.core.extension.Tag;
|
|
||||||
import run.halo.app.core.extension.Theme;
|
|
||||||
import run.halo.app.core.extension.User;
|
|
||||||
import run.halo.app.core.extension.attachment.Attachment;
|
|
||||||
import run.halo.app.core.extension.reconciler.CategoryReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.CommentReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.MenuItemReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.MenuReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.PluginReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.PostReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.ReverseProxyReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.RoleBindingReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.RoleReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.SinglePageReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.SystemSettingReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.TagReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.ThemeReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.UserReconciler;
|
|
||||||
import run.halo.app.core.extension.reconciler.attachment.AttachmentReconciler;
|
|
||||||
import run.halo.app.core.extension.service.RoleService;
|
|
||||||
import run.halo.app.extension.ConfigMap;
|
|
||||||
import run.halo.app.extension.DefaultSchemeManager;
|
import run.halo.app.extension.DefaultSchemeManager;
|
||||||
import run.halo.app.extension.DefaultSchemeWatcherManager;
|
import run.halo.app.extension.DefaultSchemeWatcherManager;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.ReactiveExtensionClient;
|
import run.halo.app.extension.ReactiveExtensionClient;
|
||||||
import run.halo.app.extension.SchemeManager;
|
import run.halo.app.extension.SchemeManager;
|
||||||
import run.halo.app.extension.SchemeWatcherManager;
|
import run.halo.app.extension.SchemeWatcherManager;
|
||||||
import run.halo.app.extension.controller.Controller;
|
import run.halo.app.extension.controller.DefaultControllerManager;
|
||||||
import run.halo.app.extension.controller.ControllerBuilder;
|
|
||||||
import run.halo.app.extension.controller.ControllerManager;
|
|
||||||
import run.halo.app.extension.router.ExtensionCompositeRouterFunction;
|
import run.halo.app.extension.router.ExtensionCompositeRouterFunction;
|
||||||
import run.halo.app.infra.ExternalUrlSupplier;
|
|
||||||
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
|
||||||
import run.halo.app.infra.properties.HaloProperties;
|
|
||||||
import run.halo.app.metrics.CounterService;
|
|
||||||
import run.halo.app.plugin.ExtensionComponentsFinder;
|
|
||||||
import run.halo.app.plugin.HaloPluginManager;
|
|
||||||
import run.halo.app.plugin.resources.ReverseProxyRouterFunctionRegistry;
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
public class ExtensionConfiguration {
|
public class ExtensionConfiguration {
|
||||||
|
@ -87,150 +40,10 @@ public class ExtensionConfiguration {
|
||||||
static class ExtensionControllerConfiguration {
|
static class ExtensionControllerConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
ControllerManager controllerManager() {
|
DefaultControllerManager controllerManager(ExtensionClient client) {
|
||||||
return new ControllerManager();
|
return new DefaultControllerManager(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller userController(ExtensionClient client) {
|
|
||||||
return new ControllerBuilder("user", client)
|
|
||||||
.reconciler(new UserReconciler(client))
|
|
||||||
.extension(new User())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller roleController(ExtensionClient client, RoleService roleService) {
|
|
||||||
return new ControllerBuilder("role", client)
|
|
||||||
.reconciler(new RoleReconciler(client, roleService))
|
|
||||||
.extension(new Role())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller roleBindingController(ExtensionClient client) {
|
|
||||||
return new ControllerBuilder("role-binding", client)
|
|
||||||
.reconciler(new RoleBindingReconciler(client))
|
|
||||||
.extension(new RoleBinding())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller pluginController(ExtensionClient client, HaloPluginManager haloPluginManager) {
|
|
||||||
return new ControllerBuilder("plugin", client)
|
|
||||||
.reconciler(new PluginReconciler(client, haloPluginManager))
|
|
||||||
.extension(new Plugin())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller menuController(ExtensionClient client) {
|
|
||||||
return new ControllerBuilder("menu", client)
|
|
||||||
.reconciler(new MenuReconciler(client))
|
|
||||||
.extension(new Menu())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller menuItemController(ExtensionClient client) {
|
|
||||||
return new ControllerBuilder("menu-item", client)
|
|
||||||
.reconciler(new MenuItemReconciler(client))
|
|
||||||
.extension(new MenuItem())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller themeController(ExtensionClient client, HaloProperties haloProperties) {
|
|
||||||
return new ControllerBuilder("theme", client)
|
|
||||||
.reconciler(new ThemeReconciler(client, haloProperties))
|
|
||||||
.extension(new Theme())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller postController(ExtensionClient client, ContentService contentService,
|
|
||||||
PostPermalinkPolicy postPermalinkPolicy, CounterService counterService,
|
|
||||||
PostService postService, ApplicationContext applicationContext) {
|
|
||||||
return new ControllerBuilder("post", client)
|
|
||||||
.reconciler(new PostReconciler(client, contentService, postService,
|
|
||||||
postPermalinkPolicy,
|
|
||||||
counterService, applicationContext))
|
|
||||||
.extension(new Post())
|
|
||||||
// TODO Make it configurable
|
|
||||||
.workerCount(10)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller categoryController(ExtensionClient client,
|
|
||||||
CategoryPermalinkPolicy categoryPermalinkPolicy) {
|
|
||||||
return new ControllerBuilder("category", client)
|
|
||||||
.reconciler(new CategoryReconciler(client, categoryPermalinkPolicy))
|
|
||||||
.extension(new Category())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller tagController(ExtensionClient client, TagPermalinkPolicy tagPermalinkPolicy) {
|
|
||||||
return new ControllerBuilder("tag", client)
|
|
||||||
.reconciler(new TagReconciler(client, tagPermalinkPolicy))
|
|
||||||
.extension(new Tag())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller systemSettingController(ExtensionClient client,
|
|
||||||
SystemConfigurableEnvironmentFetcher environmentFetcher,
|
|
||||||
ApplicationContext applicationContext) {
|
|
||||||
return new ControllerBuilder("system-setting", client)
|
|
||||||
.reconciler(new SystemSettingReconciler(client, environmentFetcher,
|
|
||||||
applicationContext))
|
|
||||||
.extension(new ConfigMap())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller attachmentController(ExtensionClient client,
|
|
||||||
ExtensionComponentsFinder extensionComponentsFinder,
|
|
||||||
ExternalUrlSupplier externalUrl) {
|
|
||||||
return new ControllerBuilder("attachment", client)
|
|
||||||
.reconciler(
|
|
||||||
new AttachmentReconciler(client, extensionComponentsFinder, externalUrl))
|
|
||||||
.extension(new Attachment())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller singlePageController(ExtensionClient client, ContentService contentService,
|
|
||||||
ApplicationContext applicationContext, CounterService counterService,
|
|
||||||
ExternalUrlSupplier externalUrlSupplier) {
|
|
||||||
return new ControllerBuilder("single-page", client)
|
|
||||||
.reconciler(new SinglePageReconciler(client, contentService,
|
|
||||||
applicationContext, counterService, externalUrlSupplier)
|
|
||||||
)
|
|
||||||
.extension(new SinglePage())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller commentController(ExtensionClient client, MeterRegistry meterRegistry,
|
|
||||||
SchemeManager schemeManager) {
|
|
||||||
return new ControllerBuilder("comment", client)
|
|
||||||
// TODO Make it configurable
|
|
||||||
.workerCount(10)
|
|
||||||
.reconciler(new CommentReconciler(client, meterRegistry, schemeManager))
|
|
||||||
.extension(new Comment())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller reverseProxyController(ExtensionClient client,
|
|
||||||
ReverseProxyRouterFunctionRegistry reverseProxyRouterFunctionRegistry) {
|
|
||||||
return new ControllerBuilder("reverse-proxy", client)
|
|
||||||
.reconciler(new ReverseProxyReconciler(client, reverseProxyRouterFunctionRegistry))
|
|
||||||
.extension(new ReverseProxy())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,13 @@ import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.content.permalinks.CategoryPermalinkPolicy;
|
import run.halo.app.content.permalinks.CategoryPermalinkPolicy;
|
||||||
import run.halo.app.core.extension.Category;
|
import run.halo.app.core.extension.Category;
|
||||||
import run.halo.app.core.extension.Post;
|
import run.halo.app.core.extension.Post;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.infra.utils.JsonUtils;
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
|
|
||||||
|
@ -25,6 +28,7 @@ import run.halo.app.infra.utils.JsonUtils;
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
public class CategoryReconciler implements Reconciler<Reconciler.Request> {
|
public class CategoryReconciler implements Reconciler<Reconciler.Request> {
|
||||||
private static final String FINALIZER_NAME = "category-protection";
|
private static final String FINALIZER_NAME = "category-protection";
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -54,6 +58,13 @@ public class CategoryReconciler implements Reconciler<Reconciler.Request> {
|
||||||
.orElseGet(() -> new Result(false, null));
|
.orElseGet(() -> new Result(false, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Category())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void addFinalizerIfNecessary(Category oldCategory) {
|
private void addFinalizerIfNecessary(Category oldCategory) {
|
||||||
Set<String> finalizers = oldCategory.getMetadata().getFinalizers();
|
Set<String> finalizers = oldCategory.getMetadata().getFinalizers();
|
||||||
if (finalizers != null && finalizers.contains(FINALIZER_NAME)) {
|
if (finalizers != null && finalizers.contains(FINALIZER_NAME)) {
|
||||||
|
|
|
@ -13,12 +13,15 @@ import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.core.extension.Comment;
|
import run.halo.app.core.extension.Comment;
|
||||||
import run.halo.app.core.extension.Reply;
|
import run.halo.app.core.extension.Reply;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.GroupVersionKind;
|
import run.halo.app.extension.GroupVersionKind;
|
||||||
import run.halo.app.extension.Ref;
|
import run.halo.app.extension.Ref;
|
||||||
import run.halo.app.extension.SchemeManager;
|
import run.halo.app.extension.SchemeManager;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.infra.utils.JsonUtils;
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
import run.halo.app.metrics.MeterUtils;
|
import run.halo.app.metrics.MeterUtils;
|
||||||
|
@ -29,6 +32,7 @@ import run.halo.app.metrics.MeterUtils;
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
public class CommentReconciler implements Reconciler<Reconciler.Request> {
|
public class CommentReconciler implements Reconciler<Reconciler.Request> {
|
||||||
public static final String FINALIZER_NAME = "comment-protection";
|
public static final String FINALIZER_NAME = "comment-protection";
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -58,6 +62,13 @@ public class CommentReconciler implements Reconciler<Reconciler.Request> {
|
||||||
.orElseGet(() -> new Result(false, null));
|
.orElseGet(() -> new Result(false, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Comment())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isDeleted(Comment comment) {
|
private boolean isDeleted(Comment comment) {
|
||||||
return comment.getMetadata().getDeletionTimestamp() != null;
|
return comment.getMetadata().getDeletionTimestamp() != null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package run.halo.app.core.extension.reconciler;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import run.halo.app.core.extension.Category;
|
import run.halo.app.core.extension.Category;
|
||||||
import run.halo.app.core.extension.MenuItem;
|
import run.halo.app.core.extension.MenuItem;
|
||||||
|
@ -12,9 +13,12 @@ import run.halo.app.core.extension.SinglePage;
|
||||||
import run.halo.app.core.extension.Tag;
|
import run.halo.app.core.extension.Tag;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.Ref;
|
import run.halo.app.extension.Ref;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.controller.Reconciler.Request;
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
|
|
||||||
|
@Component
|
||||||
public class MenuItemReconciler implements Reconciler<Request> {
|
public class MenuItemReconciler implements Reconciler<Request> {
|
||||||
|
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -46,6 +50,13 @@ public class MenuItemReconciler implements Reconciler<Request> {
|
||||||
}).orElseGet(() -> new Result(false, null));
|
}).orElseGet(() -> new Result(false, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new MenuItem())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private Result handleCategoryRef(String menuItemName, MenuItemStatus status, Ref categoryRef) {
|
private Result handleCategoryRef(String menuItemName, MenuItemStatus status, Ref categoryRef) {
|
||||||
client.fetch(Category.class, categoryRef.getName())
|
client.fetch(Category.class, categoryRef.getName())
|
||||||
.filter(category -> category.getStatus() != null)
|
.filter(category -> category.getStatus() != null)
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package run.halo.app.core.extension.reconciler;
|
|
||||||
|
|
||||||
import run.halo.app.extension.ExtensionClient;
|
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
|
||||||
|
|
||||||
public class MenuReconciler implements Reconciler<Reconciler.Request> {
|
|
||||||
|
|
||||||
private final ExtensionClient client;
|
|
||||||
|
|
||||||
public MenuReconciler(ExtensionClient client) {
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result reconcile(Request request) {
|
|
||||||
return new Result(false, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -17,10 +17,13 @@ import org.pf4j.PluginRuntimeException;
|
||||||
import org.pf4j.PluginState;
|
import org.pf4j.PluginState;
|
||||||
import org.pf4j.PluginWrapper;
|
import org.pf4j.PluginWrapper;
|
||||||
import org.pf4j.RuntimeMode;
|
import org.pf4j.RuntimeMode;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.core.extension.Plugin;
|
import run.halo.app.core.extension.Plugin;
|
||||||
import run.halo.app.core.extension.ReverseProxy;
|
import run.halo.app.core.extension.ReverseProxy;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.Metadata;
|
import run.halo.app.extension.Metadata;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.controller.Reconciler.Request;
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
import run.halo.app.infra.utils.JsonUtils;
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
|
@ -37,6 +40,7 @@ import run.halo.app.plugin.resources.BundleResourceUtils;
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class PluginReconciler implements Reconciler<Request> {
|
public class PluginReconciler implements Reconciler<Request> {
|
||||||
private static final String FINALIZER_NAME = "plugin-protection";
|
private static final String FINALIZER_NAME = "plugin-protection";
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -63,6 +67,13 @@ public class PluginReconciler implements Reconciler<Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Plugin())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void reconcilePluginState(String name) {
|
private void reconcilePluginState(String name) {
|
||||||
if (haloPluginManager.getPlugin(name) == null) {
|
if (haloPluginManager.getPlugin(name) == null) {
|
||||||
ensurePluginLoaded();
|
ensurePluginLoaded();
|
||||||
|
|
|
@ -10,6 +10,7 @@ import lombok.AllArgsConstructor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import run.halo.app.content.ContentService;
|
import run.halo.app.content.ContentService;
|
||||||
import run.halo.app.content.PostService;
|
import run.halo.app.content.PostService;
|
||||||
|
@ -23,6 +24,8 @@ import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.ExtensionOperator;
|
import run.halo.app.extension.ExtensionOperator;
|
||||||
import run.halo.app.extension.ExtensionUtil;
|
import run.halo.app.extension.ExtensionUtil;
|
||||||
import run.halo.app.extension.Ref;
|
import run.halo.app.extension.Ref;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.infra.Condition;
|
import run.halo.app.infra.Condition;
|
||||||
import run.halo.app.infra.ConditionList;
|
import run.halo.app.infra.ConditionList;
|
||||||
|
@ -45,6 +48,7 @@ import run.halo.app.metrics.MeterUtils;
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@Component
|
||||||
public class PostReconciler implements Reconciler<Reconciler.Request> {
|
public class PostReconciler implements Reconciler<Reconciler.Request> {
|
||||||
private static final String FINALIZER_NAME = "post-protection";
|
private static final String FINALIZER_NAME = "post-protection";
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -73,6 +77,15 @@ public class PostReconciler implements Reconciler<Reconciler.Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Post())
|
||||||
|
// TODO Make it configurable
|
||||||
|
.workerCount(10)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void reconcileSpec(String name) {
|
private void reconcileSpec(String name) {
|
||||||
client.fetch(Post.class, name).ifPresent(post -> {
|
client.fetch(Post.class, name).ifPresent(post -> {
|
||||||
// un-publish post if necessary
|
// un-publish post if necessary
|
||||||
|
|
|
@ -4,8 +4,11 @@ import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.core.extension.ReverseProxy;
|
import run.halo.app.core.extension.ReverseProxy;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.plugin.PluginConst;
|
import run.halo.app.plugin.PluginConst;
|
||||||
import run.halo.app.plugin.resources.ReverseProxyRouterFunctionRegistry;
|
import run.halo.app.plugin.resources.ReverseProxyRouterFunctionRegistry;
|
||||||
|
@ -16,6 +19,7 @@ import run.halo.app.plugin.resources.ReverseProxyRouterFunctionRegistry;
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
public class ReverseProxyReconciler implements Reconciler<Reconciler.Request> {
|
public class ReverseProxyReconciler implements Reconciler<Reconciler.Request> {
|
||||||
private static final String FINALIZER_NAME = "reverse-proxy-protection";
|
private static final String FINALIZER_NAME = "reverse-proxy-protection";
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -42,6 +46,13 @@ public class ReverseProxyReconciler implements Reconciler<Reconciler.Request> {
|
||||||
.orElse(new Result(false, null));
|
.orElse(new Result(false, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new ReverseProxy())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void registerReverseProxy(ReverseProxy reverseProxy) {
|
private void registerReverseProxy(ReverseProxy reverseProxy) {
|
||||||
String pluginId = getPluginId(reverseProxy);
|
String pluginId = getPluginId(reverseProxy);
|
||||||
routerFunctionRegistry.register(pluginId, reverseProxy).block();
|
routerFunctionRegistry.register(pluginId, reverseProxy).block();
|
||||||
|
|
|
@ -9,16 +9,20 @@ import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.util.Lazy;
|
import org.springframework.data.util.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.core.extension.Role;
|
import run.halo.app.core.extension.Role;
|
||||||
import run.halo.app.core.extension.RoleBinding;
|
import run.halo.app.core.extension.RoleBinding;
|
||||||
import run.halo.app.core.extension.RoleBinding.Subject;
|
import run.halo.app.core.extension.RoleBinding.Subject;
|
||||||
import run.halo.app.core.extension.User;
|
import run.halo.app.core.extension.User;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.controller.Reconciler.Request;
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
import run.halo.app.infra.utils.JsonUtils;
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class RoleBindingReconciler implements Reconciler<Request> {
|
public class RoleBindingReconciler implements Reconciler<Request> {
|
||||||
|
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -68,4 +72,11 @@ public class RoleBindingReconciler implements Reconciler<Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new RoleBinding())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,12 @@ import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.core.extension.Role;
|
import run.halo.app.core.extension.Role;
|
||||||
import run.halo.app.core.extension.service.RoleService;
|
import run.halo.app.core.extension.service.RoleService;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.controller.Reconciler.Request;
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
import run.halo.app.infra.utils.JsonUtils;
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
|
@ -23,6 +26,7 @@ import run.halo.app.infra.utils.JsonUtils;
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class RoleReconciler implements Reconciler<Request> {
|
public class RoleReconciler implements Reconciler<Request> {
|
||||||
|
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -65,6 +69,13 @@ public class RoleReconciler implements Reconciler<Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Role())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private List<String> aggregateUiPermissions(List<Role> dependencyRoles) {
|
private List<String> aggregateUiPermissions(List<Role> dependencyRoles) {
|
||||||
return dependencyRoles.stream()
|
return dependencyRoles.stream()
|
||||||
.filter(role -> role.getMetadata().getAnnotations() != null)
|
.filter(role -> role.getMetadata().getAnnotations() != null)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import run.halo.app.content.ContentService;
|
import run.halo.app.content.ContentService;
|
||||||
import run.halo.app.content.permalinks.ExtensionLocator;
|
import run.halo.app.content.permalinks.ExtensionLocator;
|
||||||
|
@ -26,6 +27,8 @@ import run.halo.app.extension.ExtensionOperator;
|
||||||
import run.halo.app.extension.ExtensionUtil;
|
import run.halo.app.extension.ExtensionUtil;
|
||||||
import run.halo.app.extension.GroupVersionKind;
|
import run.halo.app.extension.GroupVersionKind;
|
||||||
import run.halo.app.extension.Ref;
|
import run.halo.app.extension.Ref;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.infra.Condition;
|
import run.halo.app.infra.Condition;
|
||||||
import run.halo.app.infra.ConditionList;
|
import run.halo.app.infra.ConditionList;
|
||||||
|
@ -51,6 +54,7 @@ import run.halo.app.theme.router.PermalinkIndexDeleteCommand;
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@Component
|
||||||
public class SinglePageReconciler implements Reconciler<Reconciler.Request> {
|
public class SinglePageReconciler implements Reconciler<Reconciler.Request> {
|
||||||
private static final String FINALIZER_NAME = "single-page-protection";
|
private static final String FINALIZER_NAME = "single-page-protection";
|
||||||
private static final GroupVersionKind GVK = GroupVersionKind.fromExtension(SinglePage.class);
|
private static final GroupVersionKind GVK = GroupVersionKind.fromExtension(SinglePage.class);
|
||||||
|
@ -81,6 +85,13 @@ public class SinglePageReconciler implements Reconciler<Reconciler.Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new SinglePage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void reconcileSpec(String name) {
|
private void reconcileSpec(String name) {
|
||||||
client.fetch(SinglePage.class, name).ifPresent(page -> {
|
client.fetch(SinglePage.class, name).ifPresent(page -> {
|
||||||
// un-publish if necessary
|
// un-publish if necessary
|
||||||
|
|
|
@ -8,9 +8,12 @@ import java.util.Set;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.extension.ConfigMap;
|
import run.halo.app.extension.ConfigMap;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.Metadata;
|
import run.halo.app.extension.Metadata;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
|
||||||
import run.halo.app.infra.SystemSetting;
|
import run.halo.app.infra.SystemSetting;
|
||||||
|
@ -26,6 +29,7 @@ import run.halo.app.theme.router.PermalinkRuleChangedEvent;
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class SystemSettingReconciler implements Reconciler<Reconciler.Request> {
|
public class SystemSettingReconciler implements Reconciler<Reconciler.Request> {
|
||||||
public static final String OLD_THEME_ROUTE_RULES = "halo.run/old-theme-route-rules";
|
public static final String OLD_THEME_ROUTE_RULES = "halo.run/old-theme-route-rules";
|
||||||
public static final String FINALIZER_NAME = "system-setting-protection";
|
public static final String FINALIZER_NAME = "system-setting-protection";
|
||||||
|
@ -59,6 +63,13 @@ public class SystemSettingReconciler implements Reconciler<Reconciler.Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new ConfigMap())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void customizeSystem(String name) {
|
private void customizeSystem(String name) {
|
||||||
if (!SystemSetting.SYSTEM_CONFIG_DEFAULT.equals(name)) {
|
if (!SystemSetting.SYSTEM_CONFIG_DEFAULT.equals(name)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -5,10 +5,13 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.content.permalinks.TagPermalinkPolicy;
|
import run.halo.app.content.permalinks.TagPermalinkPolicy;
|
||||||
import run.halo.app.core.extension.Post;
|
import run.halo.app.core.extension.Post;
|
||||||
import run.halo.app.core.extension.Tag;
|
import run.halo.app.core.extension.Tag;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.infra.utils.JsonUtils;
|
import run.halo.app.infra.utils.JsonUtils;
|
||||||
|
|
||||||
|
@ -18,6 +21,7 @@ import run.halo.app.infra.utils.JsonUtils;
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
public class TagReconciler implements Reconciler<Reconciler.Request> {
|
public class TagReconciler implements Reconciler<Reconciler.Request> {
|
||||||
private static final String FINALIZER_NAME = "tag-protection";
|
private static final String FINALIZER_NAME = "tag-protection";
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -46,6 +50,13 @@ public class TagReconciler implements Reconciler<Reconciler.Request> {
|
||||||
.orElseGet(() -> new Result(false, null));
|
.orElseGet(() -> new Result(false, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Tag())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void cleanUpResources(Tag tag) {
|
private void cleanUpResources(Tag tag) {
|
||||||
// remove permalink from permalink indexer
|
// remove permalink from permalink indexer
|
||||||
tagPermalinkPolicy.onPermalinkDelete(tag);
|
tagPermalinkPolicy.onPermalinkDelete(tag);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.FileSystemUtils;
|
import org.springframework.util.FileSystemUtils;
|
||||||
import run.halo.app.core.extension.Setting;
|
import run.halo.app.core.extension.Setting;
|
||||||
|
@ -16,6 +17,8 @@ import run.halo.app.core.extension.Theme;
|
||||||
import run.halo.app.extension.ConfigMap;
|
import run.halo.app.extension.ConfigMap;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.Metadata;
|
import run.halo.app.extension.Metadata;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.controller.Reconciler.Request;
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
import run.halo.app.infra.exception.ThemeUninstallException;
|
import run.halo.app.infra.exception.ThemeUninstallException;
|
||||||
|
@ -29,6 +32,7 @@ import run.halo.app.theme.ThemePathPolicy;
|
||||||
* @author guqing
|
* @author guqing
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
public class ThemeReconciler implements Reconciler<Request> {
|
public class ThemeReconciler implements Reconciler<Request> {
|
||||||
|
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -52,6 +56,13 @@ public class ThemeReconciler implements Reconciler<Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Theme())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
private void reconcileStatus(String name) {
|
private void reconcileStatus(String name) {
|
||||||
client.fetch(Theme.class, name).ifPresent(theme -> {
|
client.fetch(Theme.class, name).ifPresent(theme -> {
|
||||||
Theme oldTheme = JsonUtils.deepCopy(theme);
|
Theme oldTheme = JsonUtils.deepCopy(theme);
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
package run.halo.app.core.extension.reconciler;
|
package run.halo.app.core.extension.reconciler;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import run.halo.app.core.extension.User;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.controller.Reconciler.Request;
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class UserReconciler implements Reconciler<Request> {
|
public class UserReconciler implements Reconciler<Request> {
|
||||||
|
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -20,4 +25,11 @@ public class UserReconciler implements Reconciler<Request> {
|
||||||
return new Result(false, null);
|
return new Result(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new User())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.util.UriUtils;
|
import org.springframework.web.util.UriUtils;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
@ -17,6 +18,8 @@ import run.halo.app.core.extension.attachment.endpoint.AttachmentHandler;
|
||||||
import run.halo.app.core.extension.attachment.endpoint.AttachmentHandler.DeleteOption;
|
import run.halo.app.core.extension.attachment.endpoint.AttachmentHandler.DeleteOption;
|
||||||
import run.halo.app.extension.ConfigMap;
|
import run.halo.app.extension.ConfigMap;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.controller.Reconciler.Request;
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
import run.halo.app.infra.ExternalUrlSupplier;
|
import run.halo.app.infra.ExternalUrlSupplier;
|
||||||
|
@ -24,6 +27,7 @@ import run.halo.app.infra.exception.NotFoundException;
|
||||||
import run.halo.app.plugin.ExtensionComponentsFinder;
|
import run.halo.app.plugin.ExtensionComponentsFinder;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class AttachmentReconciler implements Reconciler<Request> {
|
public class AttachmentReconciler implements Reconciler<Request> {
|
||||||
|
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -92,6 +96,13 @@ public class AttachmentReconciler implements Reconciler<Request> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return builder
|
||||||
|
.extension(new Attachment())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
void updateStatus(String attachmentName, AttachmentStatus status) {
|
void updateStatus(String attachmentName, AttachmentStatus status) {
|
||||||
client.fetch(Attachment.class, attachmentName)
|
client.fetch(Attachment.class, attachmentName)
|
||||||
.filter(attachment -> !Objects.deepEquals(attachment.getStatus(), status))
|
.filter(attachment -> !Objects.deepEquals(attachment.getStatus(), status))
|
||||||
|
|
|
@ -37,10 +37,11 @@ public class ControllerBuilder {
|
||||||
|
|
||||||
private int workerCount = 1;
|
private int workerCount = 1;
|
||||||
|
|
||||||
public ControllerBuilder(String name, ExtensionClient client) {
|
public ControllerBuilder(Reconciler<Request> reconciler, ExtensionClient client) {
|
||||||
Assert.hasText(name, "Extension name is required");
|
Assert.notNull(reconciler, "Reconciler must not be null");
|
||||||
Assert.notNull(client, "Extension client must not be null");
|
Assert.notNull(client, "Extension client must not be null");
|
||||||
this.name = name;
|
this.name = reconciler.getClass().getName();
|
||||||
|
this.reconciler = reconciler;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,11 +55,6 @@ public class ControllerBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControllerBuilder reconciler(Reconciler<Request> reconciler) {
|
|
||||||
this.reconciler = reconciler;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ControllerBuilder nowSupplier(Supplier<Instant> nowSupplier) {
|
public ControllerBuilder nowSupplier(Supplier<Instant> nowSupplier) {
|
||||||
this.nowSupplier = nowSupplier;
|
this.nowSupplier = nowSupplier;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -1,42 +1,19 @@
|
||||||
package run.halo.app.extension.controller;
|
package run.halo.app.extension.controller;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
public interface ControllerManager {
|
||||||
import org.springframework.beans.BeansException;
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.ApplicationContextAware;
|
|
||||||
import org.springframework.context.ApplicationListener;
|
|
||||||
|
|
||||||
@Slf4j
|
/**
|
||||||
public class ControllerManager implements ApplicationListener<ApplicationReadyEvent>,
|
* Register and start a reconciler.
|
||||||
ApplicationContextAware, DisposableBean {
|
*
|
||||||
|
* @param reconciler reconciler must not be null.
|
||||||
|
*/
|
||||||
|
void start(Reconciler<Reconciler.Request> reconciler);
|
||||||
|
|
||||||
private ApplicationContext applicationContext;
|
/**
|
||||||
|
* Unregister and stop a reconciler.
|
||||||
|
*
|
||||||
|
* @param reconciler reconciler must not be null.
|
||||||
|
*/
|
||||||
|
void stop(Reconciler<Reconciler.Request> reconciler);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onApplicationEvent(ApplicationReadyEvent event) {
|
|
||||||
applicationContext.getBeansOfType(Controller.class).values().forEach(Controller::start);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroy() {
|
|
||||||
var controllers =
|
|
||||||
applicationContext.getBeansOfType(Controller.class).values();
|
|
||||||
log.info("Shutting down {} controllers...", controllers.size());
|
|
||||||
controllers.forEach(
|
|
||||||
controller -> {
|
|
||||||
try {
|
|
||||||
controller.dispose();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error("Failed to dispose controller {}", controller.getName(), t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
log.info("Shutdown {} controllers.", controllers.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
|
||||||
this.applicationContext = applicationContext;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package run.halo.app.extension.controller;
|
||||||
|
|
||||||
|
import static org.springframework.core.ResolvableType.forClassWithGenerics;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import run.halo.app.extension.ExtensionClient;
|
||||||
|
import run.halo.app.extension.controller.Reconciler.Request;
|
||||||
|
import run.halo.app.infra.SchemeInitializedEvent;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class DefaultControllerManager
|
||||||
|
implements ApplicationListener<SchemeInitializedEvent>,
|
||||||
|
ApplicationContextAware, DisposableBean, ControllerManager {
|
||||||
|
|
||||||
|
private final ExtensionClient client;
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map with key: reconciler class name, value: controller self.
|
||||||
|
*/
|
||||||
|
private final ConcurrentHashMap<String, Controller> controllers;
|
||||||
|
|
||||||
|
public DefaultControllerManager(ExtensionClient client) {
|
||||||
|
this.client = client;
|
||||||
|
controllers = new ConcurrentHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Reconciler<Request> reconciler) {
|
||||||
|
var builder = new ControllerBuilder(reconciler, client);
|
||||||
|
var controller = reconciler.setupWith(builder);
|
||||||
|
controllers.put(reconciler.getClass().getName(), controller);
|
||||||
|
controller.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(Reconciler<Request> reconciler) {
|
||||||
|
var controller = controllers.remove(reconciler.getClass().getName());
|
||||||
|
// destroy it
|
||||||
|
disposeSilently(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void disposeSilently(Controller controller) {
|
||||||
|
if (controller == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
log.info("Shutting down controller {}...", controller.getName());
|
||||||
|
controller.dispose();
|
||||||
|
log.info("Shutdown controller {} successfully", controller.getName());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.error("Failed to dispose controller {}", controller.getName(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
log.info("Shutting down {} controllers...", controllers.size());
|
||||||
|
controllers.forEach((name, controller) -> disposeSilently(controller));
|
||||||
|
log.info("Shutdown {} controllers.", controllers.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(SchemeInitializedEvent event) {
|
||||||
|
// register reconcilers in system after scheme initialized
|
||||||
|
applicationContext.<Reconciler<Request>>getBeanProvider(
|
||||||
|
forClassWithGenerics(Reconciler.class, Request.class))
|
||||||
|
.orderedStream()
|
||||||
|
.forEach(this::start);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,8 @@ public interface Reconciler<R> {
|
||||||
|
|
||||||
Result reconcile(R request);
|
Result reconcile(R request);
|
||||||
|
|
||||||
|
Controller setupWith(ControllerBuilder builder);
|
||||||
|
|
||||||
record Request(String name) {
|
record Request(String name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package run.halo.app.extension.gc;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import run.halo.app.extension.ExtensionClient;
|
|
||||||
import run.halo.app.extension.ExtensionConverter;
|
|
||||||
import run.halo.app.extension.SchemeManager;
|
|
||||||
import run.halo.app.extension.controller.Controller;
|
|
||||||
import run.halo.app.extension.controller.DefaultController;
|
|
||||||
import run.halo.app.extension.controller.DefaultDelayQueue;
|
|
||||||
import run.halo.app.extension.store.ExtensionStoreClient;
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
public class GarbageCollectorConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
Controller garbageCollector(ExtensionClient client,
|
|
||||||
ExtensionStoreClient storeClient,
|
|
||||||
ExtensionConverter converter,
|
|
||||||
SchemeManager schemeManager) {
|
|
||||||
var reconciler = new GcReconciler(client, storeClient, converter);
|
|
||||||
var queue = new DefaultDelayQueue<GcRequest>(Instant::now, Duration.ofMillis(500));
|
|
||||||
var synchronizer = new GcSynchronizer(client, queue, schemeManager);
|
|
||||||
return new DefaultController<>(
|
|
||||||
"garbage-collector-controller",
|
|
||||||
reconciler,
|
|
||||||
queue,
|
|
||||||
synchronizer,
|
|
||||||
Duration.ofMillis(500),
|
|
||||||
Duration.ofSeconds(1000),
|
|
||||||
// TODO Make it configurable
|
|
||||||
10);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package run.halo.app.extension.gc;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.infra.SchemeInitializedEvent;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class GcControllerInitializer
|
||||||
|
implements ApplicationListener<SchemeInitializedEvent>, DisposableBean {
|
||||||
|
|
||||||
|
private final Controller gcController;
|
||||||
|
|
||||||
|
public GcControllerInitializer(GcReconciler gcReconciler) {
|
||||||
|
this.gcController = gcReconciler.setupWith(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(SchemeInitializedEvent event) {
|
||||||
|
gcController.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() throws Exception {
|
||||||
|
gcController.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,24 @@
|
||||||
package run.halo.app.extension.gc;
|
package run.halo.app.extension.gc;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import run.halo.app.extension.Extension;
|
import run.halo.app.extension.Extension;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.ExtensionConverter;
|
import run.halo.app.extension.ExtensionConverter;
|
||||||
|
import run.halo.app.extension.SchemeManager;
|
||||||
|
import run.halo.app.extension.controller.Controller;
|
||||||
|
import run.halo.app.extension.controller.ControllerBuilder;
|
||||||
|
import run.halo.app.extension.controller.DefaultController;
|
||||||
|
import run.halo.app.extension.controller.DefaultDelayQueue;
|
||||||
import run.halo.app.extension.controller.Reconciler;
|
import run.halo.app.extension.controller.Reconciler;
|
||||||
import run.halo.app.extension.store.ExtensionStoreClient;
|
import run.halo.app.extension.store.ExtensionStoreClient;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
class GcReconciler implements Reconciler<GcRequest> {
|
class GcReconciler implements Reconciler<GcRequest> {
|
||||||
|
|
||||||
private final ExtensionClient client;
|
private final ExtensionClient client;
|
||||||
|
@ -18,11 +27,14 @@ class GcReconciler implements Reconciler<GcRequest> {
|
||||||
|
|
||||||
private final ExtensionConverter converter;
|
private final ExtensionConverter converter;
|
||||||
|
|
||||||
|
private final SchemeManager schemeManager;
|
||||||
|
|
||||||
GcReconciler(ExtensionClient client, ExtensionStoreClient storeClient,
|
GcReconciler(ExtensionClient client, ExtensionStoreClient storeClient,
|
||||||
ExtensionConverter converter) {
|
ExtensionConverter converter, SchemeManager schemeManager) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.storeClient = storeClient;
|
this.storeClient = storeClient;
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
|
this.schemeManager = schemeManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,6 +53,21 @@ class GcReconciler implements Reconciler<GcRequest> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
var queue = new DefaultDelayQueue<GcRequest>(Instant::now, Duration.ofMillis(500));
|
||||||
|
var synchronizer = new GcSynchronizer(client, queue, schemeManager);
|
||||||
|
return new DefaultController<>(
|
||||||
|
"garbage-collector-controller",
|
||||||
|
this,
|
||||||
|
queue,
|
||||||
|
synchronizer,
|
||||||
|
Duration.ofMillis(500),
|
||||||
|
Duration.ofSeconds(1000),
|
||||||
|
// TODO Make it configurable
|
||||||
|
10);
|
||||||
|
}
|
||||||
|
|
||||||
private Predicate<Extension> deletable() {
|
private Predicate<Extension> deletable() {
|
||||||
return extension -> CollectionUtils.isEmpty(extension.getMetadata().getFinalizers())
|
return extension -> CollectionUtils.isEmpty(extension.getMetadata().getFinalizers())
|
||||||
&& extension.getMetadata().getDeletionTimestamp() != null;
|
&& extension.getMetadata().getDeletionTimestamp() != null;
|
||||||
|
|
|
@ -20,28 +20,23 @@ class ControllerBuilderTest {
|
||||||
ExtensionClient client;
|
ExtensionClient client;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void buildWithBlankName() {
|
void buildWithNullReconciler() {
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> new ControllerBuilder("", client).build());
|
() -> new ControllerBuilder(null, client).build(), "Reconciler must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void buildWithNullClient() {
|
void buildWithNullClient() {
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> new ControllerBuilder("fake-name", null).build());
|
() -> new ControllerBuilder(new FakeReconciler(), null).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void buildTest() {
|
void buildTest() {
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> new ControllerBuilder("fake-name", client)
|
() -> new ControllerBuilder(new FakeReconciler(), client)
|
||||||
.build(),
|
.build(),
|
||||||
"Extension must not be null");
|
"Extension must not be null");
|
||||||
assertThrows(IllegalArgumentException.class,
|
|
||||||
() -> new ControllerBuilder("fake-name", client)
|
|
||||||
.extension(new FakeExtension())
|
|
||||||
.build(),
|
|
||||||
"Reconciler must not be null");
|
|
||||||
|
|
||||||
assertNotNull(fakeBuilder().build());
|
assertNotNull(fakeBuilder().build());
|
||||||
|
|
||||||
|
@ -92,9 +87,21 @@ class ControllerBuilderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerBuilder fakeBuilder() {
|
ControllerBuilder fakeBuilder() {
|
||||||
return new ControllerBuilder("fake-name", client)
|
return new ControllerBuilder(new FakeReconciler(), client)
|
||||||
.extension(new FakeExtension())
|
.extension(new FakeExtension());
|
||||||
.reconciler(request -> new Reconciler.Result(false, null));
|
}
|
||||||
|
|
||||||
|
static class FakeReconciler implements Reconciler<Reconciler.Request> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result reconcile(Request request) {
|
||||||
|
return new Reconciler.Result(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Controller setupWith(ControllerBuilder builder) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue