362 lines
11 KiB
Go
362 lines
11 KiB
Go
package plugins
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// PluginType 插件类型
|
|
type PluginType string
|
|
|
|
// 预定义的插件类型
|
|
const (
|
|
PluginTypeGeneral PluginType = "general" // 通用插件
|
|
PluginTypeStorage PluginType = "storage" // 存储插件
|
|
PluginTypeSecurity PluginType = "security" // 安全插件
|
|
PluginTypeNetwork PluginType = "network" // 网络插件
|
|
PluginTypeUtils PluginType = "utils" // 工具插件
|
|
PluginTypeHardware PluginType = "hardware" // 硬件插件
|
|
PluginTypeUI PluginType = "ui" // 用户界面插件
|
|
// 可以根据需求添加更多插件类型
|
|
)
|
|
|
|
// PluginStatus 插件状态
|
|
type PluginStatus string
|
|
|
|
// 预定义的插件状态
|
|
const (
|
|
PluginStatusUninitialized PluginStatus = "uninitialized" // 未初始化
|
|
PluginStatusInitialized PluginStatus = "initialized" // 已初始化
|
|
PluginStatusRunning PluginStatus = "running" // 运行中
|
|
PluginStatusStopped PluginStatus = "stopped" // 已停止
|
|
PluginStatusError PluginStatus = "error" // 错误状态
|
|
)
|
|
|
|
// PluginDependency 插件依赖
|
|
type PluginDependency struct {
|
|
Name string `json:"name"` // 依赖的插件名称
|
|
MinVersion string `json:"minVersion"` // 最低版本要求
|
|
MaxVersion string `json:"maxVersion"` // 最高版本要求
|
|
IsOptional bool `json:"isOptional"` // 是否为可选依赖
|
|
LoadAfter bool `json:"loadAfter"` // 是否需要在依赖插件之后加载
|
|
InitAfter bool `json:"initAfter"` // 是否需要在依赖插件初始化之后初始化
|
|
StrictVersions bool `json:"strictVersions"` // 是否严格检查版本
|
|
AutoDisableWith bool `json:"autoDisableWith"` // 依赖插件禁用时是否自动禁用
|
|
}
|
|
|
|
// PluginEventType 插件事件类型
|
|
type PluginEventType string
|
|
|
|
// 预定义的插件事件类型
|
|
const (
|
|
PluginEventLoaded PluginEventType = "loaded" // 插件加载事件
|
|
PluginEventInitialized PluginEventType = "initialized" // 插件初始化事件
|
|
PluginEventStarted PluginEventType = "started" // 插件启动事件
|
|
PluginEventStopped PluginEventType = "stopped" // 插件停止事件
|
|
PluginEventEnabled PluginEventType = "enabled" // 插件启用事件
|
|
PluginEventDisabled PluginEventType = "disabled" // 插件禁用事件
|
|
PluginEventError PluginEventType = "error" // 插件错误事件
|
|
PluginEventCustom PluginEventType = "custom" // 自定义事件
|
|
)
|
|
|
|
// IPlugin 插件接口
|
|
// 这个文件定义了所有插件必须实现的接口
|
|
// 注意:这个文件应该与实际插件代码一起编译
|
|
type IPlugin interface {
|
|
// Name 插件名称
|
|
Name() string
|
|
// Version 插件版本
|
|
Version() string
|
|
// Description 插件描述
|
|
Description() string
|
|
// Author 插件作者
|
|
Author() string
|
|
// Type 插件类型
|
|
Type() PluginType
|
|
// Status 获取插件状态
|
|
Status() PluginStatus
|
|
// Dependencies 获取插件依赖
|
|
Dependencies() []PluginDependency
|
|
// Init 初始化插件
|
|
Init(ctx context.Context, config map[string]interface{}) error
|
|
// Start 启动插件
|
|
Start(ctx context.Context) error
|
|
// Stop 停止插件
|
|
Stop(ctx context.Context) error
|
|
// IsEnabled 插件是否启用
|
|
IsEnabled() bool
|
|
// SetEnabled 设置插件启用状态
|
|
SetEnabled(enabled bool)
|
|
// GetOperationInfo 获取操作的参数信息
|
|
GetOperationInfo(operation string) (*OperationInfo, error)
|
|
// GetAllOperations 获取所有操作及其参数信息
|
|
GetAllOperations() []*OperationInfo
|
|
// Execute 执行插件功能 返回操作结果和可能的错误
|
|
Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error)
|
|
// SubscribeEvent 订阅插件事件
|
|
SubscribeEvent(eventType PluginEventType, handler PluginEventHandler)
|
|
// UnsubscribeEvent 取消订阅插件事件
|
|
UnsubscribeEvent(eventType PluginEventType, handler PluginEventHandler)
|
|
// EmitEvent 发送插件事件
|
|
EmitEvent(event PluginEvent) error
|
|
// Reload 重新加载插件
|
|
Reload(ctx context.Context, config map[string]interface{}) error
|
|
// Cleanup 清理插件资源
|
|
Cleanup(ctx context.Context) error
|
|
}
|
|
|
|
// PluginEvent 插件事件
|
|
type PluginEvent struct {
|
|
Type PluginEventType `json:"type"` // 事件类型
|
|
PluginID string `json:"pluginId"` // 插件ID
|
|
Timestamp time.Time `json:"timestamp"` // 事件时间戳
|
|
Data map[string]interface{} `json:"data"` // 事件数据
|
|
}
|
|
|
|
// PluginEventHandler 插件事件处理函数
|
|
type PluginEventHandler func(event PluginEvent) error
|
|
|
|
// OperationParamInfo 操作参数信息
|
|
type OperationParamInfo struct {
|
|
Name string `json:"name"` // 参数名称
|
|
Type string `json:"type"` // 参数类型
|
|
Required bool `json:"required"` // 是否必须
|
|
Default interface{} `json:"default"` // 默认值
|
|
Description string `json:"description"` // 参数描述
|
|
}
|
|
|
|
// OperationInfo 操作信息
|
|
type OperationInfo struct {
|
|
Name string `json:"name"` // 操作名称
|
|
Description string `json:"description"` // 操作描述
|
|
Params []OperationParamInfo `json:"params"` // 操作参数
|
|
Extra map[string]interface{} `json:"extra"` // 额外信息
|
|
}
|
|
|
|
// BasePlugin 提供插件接口的基本实现
|
|
// 插件开发者可以嵌入此结构体,以减少需要实现的方法数量
|
|
type BasePlugin struct {
|
|
name string
|
|
version string
|
|
description string
|
|
author string
|
|
pluginType PluginType
|
|
enabled bool
|
|
status PluginStatus
|
|
dependencies []PluginDependency
|
|
eventHandlers map[PluginEventType][]PluginEventHandler
|
|
}
|
|
|
|
// NewBasePlugin 创建一个基本插件
|
|
func NewBasePlugin(name, version, description, author string, pluginType PluginType) *BasePlugin {
|
|
return &BasePlugin{
|
|
name: name,
|
|
version: version,
|
|
description: description,
|
|
author: author,
|
|
pluginType: pluginType,
|
|
enabled: true,
|
|
status: PluginStatusUninitialized,
|
|
dependencies: []PluginDependency{},
|
|
eventHandlers: make(map[PluginEventType][]PluginEventHandler),
|
|
}
|
|
}
|
|
|
|
// NewBasePluginWithDefaultType 创建一个基本插件,使用默认的通用插件类型
|
|
// 这是一个便捷的构造函数,适用于不需要指定特殊类型的场景
|
|
func NewBasePluginWithDefaultType(name, version, description, author string) *BasePlugin {
|
|
return NewBasePlugin(name, version, description, author, PluginTypeGeneral)
|
|
}
|
|
|
|
// Name 获取插件名称
|
|
func (p *BasePlugin) Name() string {
|
|
return p.name
|
|
}
|
|
|
|
// Version 获取插件版本
|
|
func (p *BasePlugin) Version() string {
|
|
return p.version
|
|
}
|
|
|
|
// Description 获取插件描述
|
|
func (p *BasePlugin) Description() string {
|
|
return p.description
|
|
}
|
|
|
|
// Author 获取插件作者
|
|
func (p *BasePlugin) Author() string {
|
|
return p.author
|
|
}
|
|
|
|
// Type 获取插件类型
|
|
func (p *BasePlugin) Type() PluginType {
|
|
return p.pluginType
|
|
}
|
|
|
|
// Status 获取插件状态
|
|
func (p *BasePlugin) Status() PluginStatus {
|
|
return p.status
|
|
}
|
|
|
|
// Dependencies 获取插件依赖
|
|
func (p *BasePlugin) Dependencies() []PluginDependency {
|
|
return p.dependencies
|
|
}
|
|
|
|
// SetDependencies 设置插件依赖
|
|
func (p *BasePlugin) SetDependencies(dependencies []PluginDependency) {
|
|
p.dependencies = dependencies
|
|
}
|
|
|
|
// AddDependency 添加插件依赖
|
|
func (p *BasePlugin) AddDependency(dependency PluginDependency) {
|
|
p.dependencies = append(p.dependencies, dependency)
|
|
}
|
|
|
|
// IsEnabled 插件是否启用
|
|
func (p *BasePlugin) IsEnabled() bool {
|
|
return p.enabled
|
|
}
|
|
|
|
// SetEnabled 设置插件启用状态
|
|
func (p *BasePlugin) SetEnabled(enabled bool) {
|
|
p.enabled = enabled
|
|
|
|
// 发送启用/禁用事件
|
|
eventType := PluginEventEnabled
|
|
if !enabled {
|
|
eventType = PluginEventDisabled
|
|
}
|
|
|
|
p.EmitEvent(PluginEvent{
|
|
Type: eventType,
|
|
PluginID: p.name,
|
|
Timestamp: time.Now(),
|
|
Data: map[string]interface{}{"enabled": enabled},
|
|
})
|
|
}
|
|
|
|
// Init 初始化插件,子类需要重写此方法
|
|
func (p *BasePlugin) Init(ctx context.Context, config map[string]interface{}) error {
|
|
p.status = PluginStatusInitialized
|
|
|
|
// 发送初始化事件
|
|
p.EmitEvent(PluginEvent{
|
|
Type: PluginEventInitialized,
|
|
PluginID: p.name,
|
|
Timestamp: time.Now(),
|
|
Data: map[string]interface{}{"config": config},
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// Start 启动插件,子类需要重写此方法
|
|
func (p *BasePlugin) Start(ctx context.Context) error {
|
|
p.status = PluginStatusRunning
|
|
|
|
// 发送启动事件
|
|
p.EmitEvent(PluginEvent{
|
|
Type: PluginEventStarted,
|
|
PluginID: p.name,
|
|
Timestamp: time.Now(),
|
|
Data: nil,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// Stop 停止插件,子类需要重写此方法
|
|
func (p *BasePlugin) Stop(ctx context.Context) error {
|
|
p.status = PluginStatusStopped
|
|
|
|
// 发送停止事件
|
|
p.EmitEvent(PluginEvent{
|
|
Type: PluginEventStopped,
|
|
PluginID: p.name,
|
|
Timestamp: time.Now(),
|
|
Data: nil,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetOperationInfo 获取操作的参数信息,子类需要重写此方法
|
|
func (p *BasePlugin) GetOperationInfo(operation string) (*OperationInfo, error) {
|
|
return nil, fmt.Errorf("插件 %s 不支持 %s 操作", p.name, operation)
|
|
}
|
|
|
|
// GetAllOperations 获取所有操作及其参数信息,子类需要重写此方法
|
|
func (p *BasePlugin) GetAllOperations() []*OperationInfo {
|
|
return []*OperationInfo{}
|
|
}
|
|
|
|
// Execute 执行插件功能,子类需要重写此方法
|
|
func (p *BasePlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
|
|
return nil, fmt.Errorf("插件 %s 不支持 %s 操作", p.name, action)
|
|
}
|
|
|
|
// SubscribeEvent 订阅插件事件
|
|
func (p *BasePlugin) SubscribeEvent(eventType PluginEventType, handler PluginEventHandler) {
|
|
if p.eventHandlers[eventType] == nil {
|
|
p.eventHandlers[eventType] = []PluginEventHandler{}
|
|
}
|
|
p.eventHandlers[eventType] = append(p.eventHandlers[eventType], handler)
|
|
}
|
|
|
|
// UnsubscribeEvent 取消订阅插件事件
|
|
func (p *BasePlugin) UnsubscribeEvent(eventType PluginEventType, handler PluginEventHandler) {
|
|
if handlers, exists := p.eventHandlers[eventType]; exists {
|
|
for i, h := range handlers {
|
|
if fmt.Sprintf("%p", h) == fmt.Sprintf("%p", handler) {
|
|
p.eventHandlers[eventType] = append(handlers[:i], handlers[i+1:]...)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// EmitEvent 发送插件事件
|
|
func (p *BasePlugin) EmitEvent(event PluginEvent) error {
|
|
if handlers, exists := p.eventHandlers[event.Type]; exists {
|
|
for _, handler := range handlers {
|
|
if err := handler(event); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Reload 重新加载插件
|
|
func (p *BasePlugin) Reload(ctx context.Context, config map[string]interface{}) error {
|
|
// 默认实现是先停止,然后重新初始化和启动
|
|
if p.status == PluginStatusRunning {
|
|
if err := p.Stop(ctx); err != nil {
|
|
return fmt.Errorf("停止插件失败: %v", err)
|
|
}
|
|
}
|
|
|
|
if err := p.Init(ctx, config); err != nil {
|
|
return fmt.Errorf("重新初始化插件失败: %v", err)
|
|
}
|
|
|
|
if p.enabled {
|
|
if err := p.Start(ctx); err != nil {
|
|
return fmt.Errorf("重新启动插件失败: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Cleanup 清理插件资源
|
|
func (p *BasePlugin) Cleanup(ctx context.Context) error {
|
|
// 默认实现是停止插件
|
|
if p.status == PluginStatusRunning {
|
|
return p.Stop(ctx)
|
|
}
|
|
return nil
|
|
}
|