不影响编译
This commit is contained in:
parent
2276737efa
commit
0f8f6f837d
12
.idea/CopilotChatHistory.xml
generated
12
.idea/CopilotChatHistory.xml
generated
@ -3,6 +3,18 @@
|
|||||||
<component name="CopilotChatHistory">
|
<component name="CopilotChatHistory">
|
||||||
<option name="conversations">
|
<option name="conversations">
|
||||||
<list>
|
<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>
|
<Conversation>
|
||||||
<option name="createTime" value="1746706460096" />
|
<option name="createTime" value="1746706460096" />
|
||||||
<option name="id" value="0196afd16dc0787d9f1e1f1b29555e6c" />
|
<option name="id" value="0196afd16dc0787d9f1e1f1b29555e6c" />
|
||||||
|
@ -1,28 +1,31 @@
|
|||||||
package cd.casic.plugin;
|
package cd.casic.plugin;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Classname PluginConstants
|
* @Classname PluginConstants
|
||||||
* @Description 常量
|
* @Description 常量
|
||||||
* @Date 2025/5/8 14:51
|
* @Date 2025/5/8 14:51
|
||||||
* @Created by mianbin
|
* @Created by mianbin
|
||||||
*/
|
*/
|
||||||
|
@UtilityClass
|
||||||
public class PluginConstants {
|
public class PluginConstants {
|
||||||
/**
|
/**
|
||||||
* Plugin metadata labels key.
|
* 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, 目前作为现在的情况,这两种就够了
|
// 模式这边后面要考虑下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/";
|
return "/plugins/" + pluginName + "/assets/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package cd.casic.plugin.extension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Classname ExtensionClient
|
||||||
|
* @Description 接口
|
||||||
|
* @Date 2025/5/9 15:43
|
||||||
|
* @Created by mianbin
|
||||||
|
*/
|
||||||
|
public interface ExtensionClient {
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
|
|
||||||
|
}
|
@ -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> {
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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> {
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,8 +22,5 @@
|
|||||||
3. 业务相关
|
3. 业务相关
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<modules>
|
|
||||||
<module>system-plugin-example-web</module>
|
|
||||||
</modules>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user