不影响编译

This commit is contained in:
mianbin 2025-05-09 19:28:02 +08:00
parent 2276737efa
commit 0f8f6f837d
12 changed files with 276 additions and 10 deletions

View File

@ -3,6 +3,18 @@
<component name="CopilotChatHistory">
<option name="conversations">
<list>
<Conversation>
<option name="createTime" value="1746752716983" />
<option name="id" value="0196b29340b7776ea658e40b4d205868" />
<option name="title" value="新对话 2025年5月09日 09:05:16" />
<option name="updateTime" value="1746752716983" />
</Conversation>
<Conversation>
<option name="createTime" value="1746752688291" />
<option name="id" value="0196b292d0a37ce19aaa9610c3120cbe" />
<option name="title" value="新对话 2025年5月09日 09:04:48" />
<option name="updateTime" value="1746752688291" />
</Conversation>
<Conversation>
<option name="createTime" value="1746706460096" />
<option name="id" value="0196afd16dc0787d9f1e1f1b29555e6c" />

View File

@ -1,28 +1,31 @@
package cd.casic.plugin;
import lombok.experimental.UtilityClass;
/**
* @Classname PluginConstants
* @Description 常量
* @Date 2025/5/8 14:51
* @Created by mianbin
*/
@UtilityClass
public class PluginConstants {
/**
* Plugin metadata labels key.
*/
static String PLUGIN_NAME_LABEL_NAME = "plugin.ops/plugin-name";
String PLUGIN_NAME_LABEL_NAME = "plugin.ops/plugin-name";
static String SYSTEM_PLUGIN_NAME = "system";
String SYSTEM_PLUGIN_NAME = "system";
static String RELOAD_ANNO = "plugin.ops/reload";
String RELOAD_ANNO = "plugin.ops/reload";
static String REQUEST_TO_UNLOAD_LABEL = "plugin.ops/request-to-unload";
String REQUEST_TO_UNLOAD_LABEL = "plugin.ops/request-to-unload";
static String PLUGIN_PATH = "plugin.ops/plugin-path";
String PLUGIN_PATH = "plugin.ops/plugin-path";
// 模式这边后面要考虑下dev\prod 目前作为现在的情况这两种就够了
static String RUNTIME_MODE_ANNO = "plugin.ops/runtime-mode";
String RUNTIME_MODE_ANNO = "plugin.ops/runtime-mode";
static String assetsRoutePrefix(String pluginName) {
String assetsRoutePrefix(String pluginName) {
return "/plugins/" + pluginName + "/assets/";
}
}

View File

@ -0,0 +1,36 @@
package cd.casic.plugin;
import com.github.zafarkhaja.semver.Version;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.server.ServerWebInputException;
/**
* @Classname VersionUtils
* @Description 版本
* @Date 2025/5/9 17:10
* @Created by mianbin
*/
@UtilityClass
public class VersionUtils {
public static boolean satisfiesRequires(String version, String requires) {
String requiresVersion = StringUtils.trim(requires);
// an exact version x.y.z will implicitly mean the same as >=x.y.z
if (requiresVersion.matches("^\\d+\\.\\d+\\.\\d+$")) {
// If exact versions are not allowed in requires, rewrite to >= expression
requiresVersion = ">=" + requiresVersion;
}
return version.equals("0.0.0") || checkVersionConstraint(version, requiresVersion);
}
public static boolean checkVersionConstraint(String version, String constraint) {
try {
return StringUtils.isBlank(constraint)
|| "*".equals(constraint)
|| Version.parse(version).satisfies(constraint);
} catch (Exception e) {
throw new ServerWebInputException("Illegal requires version expression.", null, e);
}
}
}

View File

@ -0,0 +1,24 @@
package cd.casic.plugin.core;
import org.pf4j.PluginManager;
import org.pf4j.PluginWrapper;
import org.springframework.context.ApplicationContext;
import java.util.List;
/**
* @Classname SpringPluginManager
* @Description 增强插件管理器增加spring上下文管理
* @Date 2025/5/9 14:38
* @Created by mianbin
*/
public interface SpringPluginManager extends PluginManager {
ApplicationContext getRootContext();
ApplicationContext getSharedContext();
/**
* 递归获取所有依赖
*/
List<PluginWrapper> getDependents(String pluginId);
}

View File

@ -0,0 +1,11 @@
package cd.casic.plugin.extension;
/**
* @Classname ExtensionClient
* @Description 接口
* @Date 2025/5/9 15:43
* @Created by mianbin
*/
public interface ExtensionClient {
}

View File

@ -0,0 +1,13 @@
package cd.casic.plugin.extension;
/**
* @Classname ExtensionMatcher
* @Description TODO
* @Date 2025/5/9 17:03
* @Created by mianbin
*/
public interface ExtensionMatcher {
boolean match(Extension extension);
}

View File

@ -0,0 +1,17 @@
package cd.casic.plugin.function;
import reactor.core.Disposable;
/**
* @Classname Controller
* @Description TODO
* @Date 2025/5/9 15:55
* @Created by mianbin
*/
public interface Controller extends Disposable {
String getName();
void start();
}

View File

@ -0,0 +1,13 @@
package cd.casic.plugin.function;
import java.nio.file.Path;
import java.util.function.Supplier;
/**
* @Classname PluginsRootGetter
* @Description 获取插件根路径
* @Date 2025/5/9 14:34
* @Created by mianbin
*/
public interface PluginsRootGetter extends Supplier<Path> {
}

View File

@ -0,0 +1,29 @@
package cd.casic.plugin.function;
import java.time.Duration;
/**
* @Classname Reconciler
* @Description TODO
* @Date 2025/5/9 15:54
* @Created by mianbin
*/
public interface Reconciler<R> {
Result reconcile(R request);
record Request(String name) {
}
record Result(boolean reEnqueue, Duration retryAfter) {
public static Result doNotRetry() {
return new Result(false, null);
}
public static Result requeue(Duration retryAfter) {
return new Result(true, retryAfter);
}
}
}

View File

@ -0,0 +1,14 @@
package cd.casic.plugin.function;
import com.github.zafarkhaja.semver.Version;
import java.util.function.Supplier;
/**
* @Classname SystemVersionSupplier
* @Description TODO
* @Date 2025/5/9 15:43
* @Created by mianbin
*/
public interface SystemVersionSupplier extends Supplier<Version> {
}

View File

@ -0,0 +1,97 @@
package cd.casic.plugin.function;
import cd.casic.plugin.extension.Extension;
import reactor.core.Disposable;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @Classname Watcher
* @Description TODO
* @Date 2025/5/9 15:54
* @Created by mianbin
*/
public interface Watcher extends Disposable {
default void onAdd(Reconciler.Request request) {
// Do nothing here, just for sync all on start.
}
default void onAdd(Extension extension) {
// Do nothing here
}
default void onUpdate(Extension oldExtension, Extension newExtension) {
// Do nothing here
}
default void onDelete(Extension extension) {
// Do nothing here
}
default void registerDisposeHook(Runnable dispose) {
}
class WatcherComposite implements Watcher {
private final List<Watcher> watchers;
private volatile boolean disposed = false;
private Runnable disposeHook;
public WatcherComposite() {
watchers = new CopyOnWriteArrayList<>();
}
@Override
public void onAdd(Extension extension) {
// TODO Deep copy extension and execute onAdd asynchronously
watchers.forEach(watcher -> watcher.onAdd(extension));
}
@Override
public void onUpdate(Extension oldExtension, Extension newExtension) {
// TODO Deep copy extension and execute onUpdate asynchronously
watchers.forEach(watcher -> watcher.onUpdate(oldExtension, newExtension));
}
@Override
public void onDelete(Extension extension) {
// TODO Deep copy extension and execute onDelete asynchronously
watchers.forEach(watcher -> watcher.onDelete(extension));
}
public void addWatcher(Watcher watcher) {
if (!watcher.isDisposed() && !watchers.contains(watcher)) {
watchers.add(watcher);
watcher.registerDisposeHook(() -> removeWatcher(watcher));
}
}
public void removeWatcher(Watcher watcher) {
watchers.remove(watcher);
}
@Override
public void registerDisposeHook(Runnable dispose) {
this.disposeHook = dispose;
}
@Override
public void dispose() {
this.disposed = true;
this.watchers.clear();
if (this.disposeHook != null) {
this.disposeHook.run();
}
}
@Override
public boolean isDisposed() {
return this.disposed;
}
}
}

View File

@ -22,8 +22,5 @@
3. 业务相关
</description>
<modules>
<module>system-plugin-example-web</module>
</modules>
</project>