Files
goproxy/examples/plugin/plugin.go
DarkiT 557059b2d2 增强插件系统:优化插件管理和动态插件实现
- 在插件管理器中引入 DynamicPlugin 结构体,支持动态加载和管理插件,提升插件的灵活性和可扩展性。
- 更新插件接口,添加插件名称、版本、描述、作者、类型和启用状态的获取和设置方法,增强插件信息的管理能力。
- 修改现有插件实现,确保兼容新的动态插件结构,提升插件的统一性和可维护性。
- 更新示例程序,展示如何使用新的动态插件功能,提升用户体验。

此更新提升了插件系统的灵活性和可扩展性,便于开发者更好地管理和使用插件功能。
2025-03-14 07:12:05 +00:00

1871 lines
49 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package plugin
import (
"context"
"encoding/json"
"fmt"
"io/fs"
"os"
"path/filepath"
"plugin"
"reflect"
"runtime"
"strconv"
"strings"
"sync"
)
// Plugin 插件接口
type Plugin interface {
// Name 插件名称
Name() string
// Version 插件版本
Version() string
// Description 插件描述
Description() string
// Author 插件作者
Author() string
// Type 插件类型
Type() PluginType
// 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)
// Execute 执行插件功能
// action: 要执行的操作名称
// params: 操作所需的参数
// 返回操作结果和可能的错误
Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error)
// GetOperationInfo 获取操作的参数信息
GetOperationInfo(operation string) (map[string]interface{}, error)
// GetAllOperations 获取所有操作及其参数信息
GetAllOperations() map[string]map[string]interface{}
}
// PluginHelper 插件辅助器
// 用于自动发现和注册插件方法简化Execute方法的实现
type PluginHelper struct {
instance interface{} // 插件实例
methods map[string]reflect.Method // 注册的方法
methodParams map[string][]reflect.Type // 方法的参数类型
methodRetValues map[string][]reflect.Type // 方法的返回值类型
}
// NewPluginHelper 创建一个新的插件辅助器
func NewPluginHelper(instance interface{}) *PluginHelper {
helper := &PluginHelper{
instance: instance,
methods: make(map[string]reflect.Method),
methodParams: make(map[string][]reflect.Type),
methodRetValues: make(map[string][]reflect.Type),
}
helper.discoverMethods()
return helper
}
// discoverMethods 发现插件的所有可用方法
func (h *PluginHelper) discoverMethods() {
instanceType := reflect.TypeOf(h.instance)
// 遍历实例的所有方法
for i := 0; i < instanceType.NumMethod(); i++ {
method := instanceType.Method(i)
// 跳过特定的内部方法和接口方法
if shouldSkipMethod(method.Name) {
continue
}
// 获取方法的参数和返回值类型
var paramTypes []reflect.Type
var returnTypes []reflect.Type
// 跳过接收者参数 (第一个参数)
for j := 1; j < method.Type.NumIn(); j++ {
paramTypes = append(paramTypes, method.Type.In(j))
}
for j := 0; j < method.Type.NumOut(); j++ {
returnTypes = append(returnTypes, method.Type.Out(j))
}
// 注册方法
actionName := strings.ToLower(method.Name)
h.methods[actionName] = method
h.methodParams[actionName] = paramTypes
h.methodRetValues[actionName] = returnTypes
}
}
// shouldSkipMethod 检查是否应该跳过某些方法
func shouldSkipMethod(name string) bool {
// 跳过Plugin接口的方法和特定的内部方法
skipMethods := map[string]bool{
"Name": true,
"Version": true,
"Description": true,
"Author": true,
"Type": true,
"Init": true,
"Start": true,
"Stop": true,
"IsEnabled": true,
"SetEnabled": true,
"Execute": true,
}
return skipMethods[name]
}
// GetAvailableActions 获取所有可用的动作
func (h *PluginHelper) GetAvailableActions() []string {
actions := make([]string, 0, len(h.methods))
for action := range h.methods {
actions = append(actions, action)
}
return actions
}
// ValidateParams 验证传入的参数是否符合操作的参数定义
func ValidateParams(paramsDef map[string]interface{}, params map[string]interface{}) error {
// 检查参数定义是否存在
if paramsDef == nil {
return nil // 没有参数定义,不需要验证
}
// 获取参数定义中的每个参数
paramsInfo, ok := paramsDef["parameters"].(map[string]interface{})
if !ok {
return nil // 参数定义格式不正确,跳过验证
}
// 遍历每个参数定义进行验证
errors := make([]string, 0)
for paramName, paramInfo := range paramsInfo {
info, ok := paramInfo.(map[string]interface{})
if !ok {
continue // 参数信息格式不正确,跳过
}
// 检查是否为必需参数
required, ok := info["required"].(bool)
if ok && required {
// 对于结构体参数,要检查至少有一个字段被提供
if info["type"] == "struct" {
// 结构体参数的验证
if fields, ok := info["fields"].(map[string]interface{}); ok {
// 检查必填的结构体字段
for fieldName, fieldInfo := range fields {
if fieldInfoMap, ok := fieldInfo.(map[string]interface{}); ok {
fieldRequired, ok := fieldInfoMap["required"].(bool)
if ok && fieldRequired {
if _, exists := params[fieldName]; !exists {
errors = append(errors, fmt.Sprintf("缺少必需的结构体字段: %s", fieldName))
}
}
}
}
}
} else {
// 普通参数验证是否存在
if _, exists := params[paramName]; !exists {
errors = append(errors, fmt.Sprintf("缺少必需参数: %s", paramName))
}
}
}
// 如果参数存在,验证其类型
if value, exists := params[paramName]; exists && info["type"] != nil {
expectedType := info["type"].(string)
// 根据期望的类型验证参数
switch expectedType {
case "string":
if _, ok := value.(string); !ok {
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为字符串", paramName))
}
case "integer":
// 支持多种整数类型
switch value.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
// 这些类型都是可接受的
default:
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为整数", paramName))
}
case "float":
switch value.(type) {
case float32, float64:
// 这些类型是可接受的
default:
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为浮点数", paramName))
}
case "boolean":
if _, ok := value.(bool); !ok {
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为布尔值", paramName))
}
case "array":
if _, ok := value.([]interface{}); !ok {
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为数组", paramName))
}
case "object":
if _, ok := value.(map[string]interface{}); !ok {
errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为对象", paramName))
}
}
}
}
// 如果有错误,返回组合的错误信息
if len(errors) > 0 {
return fmt.Errorf("参数验证失败: %s", strings.Join(errors, "; "))
}
return nil
}
// ExecuteAction 执行指定的动作
func (h *PluginHelper) ExecuteAction(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
// 转换为小写以实现不区分大小写的匹配
action = strings.ToLower(action)
method, exists := h.methods[action]
if !exists {
return nil, fmt.Errorf("未知的操作: %s", action)
}
// 获取操作的参数信息并验证参数
opInfo, err := h.GetParameterInfo(action)
if err == nil {
// 验证参数
if err := ValidateParams(opInfo, params); err != nil {
return nil, err
}
}
paramTypes := h.methodParams[action]
// 准备参数
var args []reflect.Value
// 添加接收者参数
args = append(args, reflect.ValueOf(h.instance))
// 处理context参数
if len(paramTypes) > 0 && paramTypes[0].String() == "context.Context" {
args = append(args, reflect.ValueOf(ctx))
paramTypes = paramTypes[1:] // 移除已处理的context参数
}
// 处理其他参数
for i, paramType := range paramTypes {
paramName := fmt.Sprintf("arg%d", i)
// 如果是结构体参数尝试将整个params映射转换为该结构体
if paramType.Kind() == reflect.Struct {
structValue := reflect.New(paramType).Elem()
if err := mapToStruct(params, structValue); err != nil {
return nil, fmt.Errorf("转换参数失败: %v", err)
}
args = append(args, structValue)
continue
}
// 从params中获取参数
paramValue, ok := params[paramName]
if !ok {
// 尝试使用参数类型名称作为键
typeName := paramType.Name()
paramValue, ok = params[strings.ToLower(typeName)]
if !ok {
return nil, fmt.Errorf("缺少必需参数: %s", paramName)
}
}
// 转换参数类型
convertedValue, err := convertParamValue(paramValue, paramType)
if err != nil {
return nil, err
}
args = append(args, convertedValue)
}
// 调用方法
result := method.Func.Call(args)
// 处理返回值
if len(result) == 0 {
return nil, nil
} else if len(result) == 1 {
return result[0].Interface(), nil
} else {
// 处理多个返回值通常最后一个是error
lastIndex := len(result) - 1
if result[lastIndex].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !result[lastIndex].IsNil() {
return nil, result[lastIndex].Interface().(error)
}
if lastIndex == 0 {
return nil, nil
}
return result[lastIndex-1].Interface(), nil
}
// 将所有返回值打包成一个映射
resultMap := make(map[string]interface{})
for i, v := range result {
resultMap[fmt.Sprintf("result%d", i)] = v.Interface()
}
return resultMap, nil
}
}
// mapToStruct 将map转换为结构体
func mapToStruct(m map[string]interface{}, structValue reflect.Value) error {
structType := structValue.Type()
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)
fieldValue := structValue.Field(i)
if !fieldValue.CanSet() {
continue
}
// 尝试不同的命名方式
fieldName := field.Name
jsonTag := field.Tag.Get("json")
if jsonTag != "" && jsonTag != "-" {
parts := strings.Split(jsonTag, ",")
fieldName = parts[0]
}
// 检查不同大小写
value, ok := m[fieldName]
if !ok {
value, ok = m[strings.ToLower(fieldName)]
}
if !ok {
continue // 跳过未找到的字段
}
// 转换并设置字段值
convertedValue, err := convertParamValue(value, field.Type)
if err != nil {
return err
}
fieldValue.Set(convertedValue)
}
return nil
}
// convertParamValue 将接口值转换为指定类型
func convertParamValue(value interface{}, targetType reflect.Type) (reflect.Value, error) {
// 处理nil值
if value == nil {
return reflect.Zero(targetType), nil
}
valueType := reflect.TypeOf(value)
// 如果类型已经匹配,直接返回
if valueType.AssignableTo(targetType) {
return reflect.ValueOf(value), nil
}
// 类型转换
switch targetType.Kind() {
case reflect.String:
return reflect.ValueOf(fmt.Sprintf("%v", value)), nil
case reflect.Bool:
switch v := value.(type) {
case bool:
return reflect.ValueOf(v), nil
case string:
b, err := strconv.ParseBool(v)
if err != nil {
return reflect.Value{}, fmt.Errorf("无法将 %v 转换为布尔值", value)
}
return reflect.ValueOf(b), nil
case float64:
return reflect.ValueOf(v != 0), nil
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
var intVal int64
switch v := value.(type) {
case int:
intVal = int64(v)
case int8:
intVal = int64(v)
case int16:
intVal = int64(v)
case int32:
intVal = int64(v)
case int64:
intVal = v
case float32:
intVal = int64(v)
case float64:
intVal = int64(v)
case string:
var err error
intVal, err = strconv.ParseInt(v, 10, 64)
if err != nil {
return reflect.Value{}, fmt.Errorf("无法将 %v 转换为整数", value)
}
default:
return reflect.Value{}, fmt.Errorf("无法将 %v 转换为整数", value)
}
switch targetType.Kind() {
case reflect.Int:
return reflect.ValueOf(int(intVal)), nil
case reflect.Int8:
return reflect.ValueOf(int8(intVal)), nil
case reflect.Int16:
return reflect.ValueOf(int16(intVal)), nil
case reflect.Int32:
return reflect.ValueOf(int32(intVal)), nil
case reflect.Int64:
return reflect.ValueOf(intVal), nil
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
var uintVal uint64
switch v := value.(type) {
case uint:
uintVal = uint64(v)
case uint8:
uintVal = uint64(v)
case uint16:
uintVal = uint64(v)
case uint32:
uintVal = uint64(v)
case uint64:
uintVal = v
case int:
if v < 0 {
return reflect.Value{}, fmt.Errorf("无法将负数 %v 转换为无符号整数", value)
}
uintVal = uint64(v)
case float64:
if v < 0 {
return reflect.Value{}, fmt.Errorf("无法将负数 %v 转换为无符号整数", value)
}
uintVal = uint64(v)
case string:
var err error
uintVal, err = strconv.ParseUint(v, 10, 64)
if err != nil {
return reflect.Value{}, fmt.Errorf("无法将 %v 转换为无符号整数", value)
}
default:
return reflect.Value{}, fmt.Errorf("无法将 %v 转换为无符号整数", value)
}
switch targetType.Kind() {
case reflect.Uint:
return reflect.ValueOf(uint(uintVal)), nil
case reflect.Uint8:
return reflect.ValueOf(uint8(uintVal)), nil
case reflect.Uint16:
return reflect.ValueOf(uint16(uintVal)), nil
case reflect.Uint32:
return reflect.ValueOf(uint32(uintVal)), nil
case reflect.Uint64:
return reflect.ValueOf(uintVal), nil
}
case reflect.Float32, reflect.Float64:
var floatVal float64
switch v := value.(type) {
case float32:
floatVal = float64(v)
case float64:
floatVal = v
case int:
floatVal = float64(v)
case int64:
floatVal = float64(v)
case string:
var err error
floatVal, err = strconv.ParseFloat(v, 64)
if err != nil {
return reflect.Value{}, fmt.Errorf("无法将 %v 转换为浮点数", value)
}
default:
return reflect.Value{}, fmt.Errorf("无法将 %v 转换为浮点数", value)
}
if targetType.Kind() == reflect.Float32 {
return reflect.ValueOf(float32(floatVal)), nil
}
return reflect.ValueOf(floatVal), nil
case reflect.Slice:
// 处理切片类型
srcVal := reflect.ValueOf(value)
if srcVal.Kind() == reflect.Slice {
// 创建目标类型的新切片
elemType := targetType.Elem()
newSlice := reflect.MakeSlice(targetType, srcVal.Len(), srcVal.Cap())
// 转换每个元素
for i := 0; i < srcVal.Len(); i++ {
elemValue, err := convertParamValue(srcVal.Index(i).Interface(), elemType)
if err != nil {
return reflect.Value{}, err
}
newSlice.Index(i).Set(elemValue)
}
return newSlice, nil
}
case reflect.Map:
// 处理映射类型
srcVal := reflect.ValueOf(value)
if srcVal.Kind() == reflect.Map {
keyType := targetType.Key()
elemType := targetType.Elem()
newMap := reflect.MakeMap(targetType)
iter := srcVal.MapRange()
for iter.Next() {
k := iter.Key()
v := iter.Value()
newKey, err := convertParamValue(k.Interface(), keyType)
if err != nil {
return reflect.Value{}, err
}
newValue, err := convertParamValue(v.Interface(), elemType)
if err != nil {
return reflect.Value{}, err
}
newMap.SetMapIndex(newKey, newValue)
}
return newMap, nil
}
case reflect.Ptr:
// 处理指针类型
elemType := targetType.Elem()
elemValue, err := convertParamValue(value, elemType)
if err != nil {
return reflect.Value{}, err
}
ptrValue := reflect.New(elemType)
ptrValue.Elem().Set(elemValue)
return ptrValue, nil
}
return reflect.Value{}, fmt.Errorf("不支持将 %T 类型转换为 %s", value, targetType)
}
// GetParameterInfo 获取操作的参数信息
func (h *PluginHelper) GetParameterInfo(action string) (map[string]interface{}, error) {
action = strings.ToLower(action)
method, exists := h.methods[action]
if !exists {
return nil, fmt.Errorf("未知的操作: %s", action)
}
paramTypes := h.methodParams[action]
returnTypes := h.methodRetValues[action]
result := map[string]interface{}{
"name": action,
"description": fmt.Sprintf("%s 操作", method.Name),
"parameters": make(map[string]interface{}),
"returns": make(map[string]interface{}),
}
// 处理参数信息
paramsInfo := make(map[string]interface{})
// 首先检查是否有context参数
hasContext := false
if len(paramTypes) > 0 && paramTypes[0].String() == "context.Context" {
hasContext = true
result["hasContext"] = true
paramTypes = paramTypes[1:] // 跳过context参数
}
for i, paramType := range paramTypes {
// 如果是结构体参数,展开其字段
if paramType.Kind() == reflect.Struct {
structInfo := getStructInfo(paramType)
structInfo["position"] = i + 1 // 考虑到接收者和可能的context
if hasContext {
structInfo["position"] = i + 2
}
paramsInfo[paramType.Name()] = structInfo
} else {
// 基本类型参数
paramName := fmt.Sprintf("arg%d", i)
typeInfo := getTypeInfo(paramType)
typeInfo["position"] = i + 1 // 考虑到接收者
if hasContext {
typeInfo["position"] = i + 2
}
paramsInfo[paramName] = typeInfo
}
}
result["parameters"] = paramsInfo
// 处理返回值信息
returnsInfo := make(map[string]interface{})
for i, returnType := range returnTypes {
returnName := fmt.Sprintf("return%d", i)
if i == len(returnTypes)-1 && returnType.String() == "error" {
returnName = "error"
} else if i == 0 && len(returnTypes) == 2 && returnTypes[1].String() == "error" {
returnName = "result"
}
returnsInfo[returnName] = getTypeInfo(returnType)
}
result["returns"] = returnsInfo
return result, nil
}
// getStructInfo 获取结构体类型的详细信息
func getStructInfo(t reflect.Type) map[string]interface{} {
info := map[string]interface{}{
"type": "struct",
"name": t.Name(),
"package": t.PkgPath(),
"fields": make(map[string]interface{}),
"fieldCount": t.NumField(),
}
fields := make(map[string]interface{})
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
// 跳过非导出字段
if field.PkgPath != "" {
continue
}
fieldName := field.Name
jsonTag := field.Tag.Get("json")
if jsonTag != "" && jsonTag != "-" {
parts := strings.Split(jsonTag, ",")
if parts[0] != "" {
fieldName = parts[0]
}
}
fieldInfo := getTypeInfo(field.Type)
fieldInfo["name"] = field.Name
fieldInfo["jsonName"] = fieldName
fieldInfo["position"] = i
fieldInfo["tags"] = string(field.Tag)
fields[fieldName] = fieldInfo
}
info["fields"] = fields
return info
}
// getTypeInfo 获取类型的基本信息
func getTypeInfo(t reflect.Type) map[string]interface{} {
info := map[string]interface{}{
"typeName": t.String(),
"kind": t.Kind().String(),
"type": typeKindToString(t.Kind()),
}
// 为不同类型添加特定信息
switch t.Kind() {
case reflect.Slice, reflect.Array:
info["elemType"] = getTypeInfo(t.Elem())
case reflect.Map:
info["keyType"] = getTypeInfo(t.Key())
info["valueType"] = getTypeInfo(t.Elem())
case reflect.Ptr:
info["elemType"] = getTypeInfo(t.Elem())
case reflect.Struct:
// 对于结构体,提供简略信息
info["structName"] = t.Name()
info["package"] = t.PkgPath()
info["fieldCount"] = t.NumField()
}
return info
}
// typeKindToString 将类型Kind转换为字符串表示
func typeKindToString(kind reflect.Kind) string {
switch kind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return "integer"
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return "unsigned integer"
case reflect.Float32, reflect.Float64:
return "float"
case reflect.Bool:
return "boolean"
case reflect.String:
return "string"
case reflect.Slice, reflect.Array:
return "array"
case reflect.Map:
return "map"
case reflect.Struct:
return "object"
case reflect.Ptr:
return "pointer"
case reflect.Interface:
return "interface"
default:
return kind.String()
}
}
// BasePluginImpl 提供插件接口的基本实现用于适配Plugin接口
// 这个结构体包装了BasePlugin以便兼容context参数
type BasePluginImpl struct {
*BasePlugin
helper *PluginHelper // 添加插件辅助器
}
// NewPlugin 创建一个基本插件实现,带有插件类型
func NewPlugin(name, version, description, author string, pluginType PluginType) *BasePluginImpl {
plugin := &BasePluginImpl{
BasePlugin: NewBasePlugin(name, version, description, author, pluginType),
}
plugin.helper = NewPluginHelper(plugin)
return plugin
}
// NewPluginWithDefaultType 创建一个基本插件实现,使用默认的通用插件类型
func NewPluginWithDefaultType(name, version, description, author string) *BasePluginImpl {
plugin := &BasePluginImpl{
BasePlugin: NewBasePluginWithDefaultType(name, version, description, author),
}
plugin.helper = NewPluginHelper(plugin)
return plugin
}
// Init 适配Init方法以支持context参数
func (p *BasePluginImpl) Init(ctx context.Context, config map[string]interface{}) error {
return p.BasePlugin.Init(config)
}
// Start 适配Start方法以支持context参数
func (p *BasePluginImpl) Start(ctx context.Context) error {
return p.BasePlugin.Start()
}
// Stop 适配Stop方法以支持context参数
func (p *BasePluginImpl) Stop(ctx context.Context) error {
return p.BasePlugin.Stop()
}
// Execute 通过辅助器自动执行插件方法
func (p *BasePluginImpl) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
// 首先尝试通过辅助器执行方法
result, err := p.helper.ExecuteAction(ctx, action, params)
if err == nil {
return result, nil
}
// 如果辅助器执行失败,检查错误类型
if strings.Contains(err.Error(), "未知的操作") {
// 回退到基础实现
return p.BasePlugin.Execute(action, params)
}
return nil, err
}
// GetAvailableActions 获取插件支持的所有操作
func (p *BasePluginImpl) GetAvailableActions() []string {
return p.helper.GetAvailableActions()
}
// GetOperationInfo 获取操作的参数信息
func (p *BasePluginImpl) GetOperationInfo(operation string) (map[string]interface{}, error) {
return p.helper.GetParameterInfo(operation)
}
// GetAllOperations 获取所有操作及其参数信息
func (p *BasePluginImpl) GetAllOperations() map[string]map[string]interface{} {
operations := make(map[string]map[string]interface{})
for _, action := range p.helper.GetAvailableActions() {
info, err := p.helper.GetParameterInfo(action)
if err == nil {
operations[action] = info
}
}
return operations
}
// PluginInfo 插件信息
type PluginInfo struct {
Name string `json:"name"`
Version string `json:"version"`
Description string `json:"description"`
Author string `json:"author"`
Type PluginType `json:"type"`
Enabled bool `json:"enabled"`
Config map[string]interface{} `json:"config,omitempty"`
}
// PluginManager 插件管理器
type PluginManager struct {
pluginsDir string
plugins map[string]Plugin
pluginsByType map[PluginType]map[string]Plugin
configs map[string]map[string]interface{}
mu sync.RWMutex
dynamicLoadingSupported bool // 是否支持动态加载插件
}
// NewPluginManager 创建插件管理器
func NewPluginManager(pluginsDir string) *PluginManager {
// 检查当前系统是否支持动态加载插件
dynamicLoadingSupported := runtime.GOOS == "linux" || runtime.GOOS == "darwin"
return &PluginManager{
pluginsDir: pluginsDir,
plugins: make(map[string]Plugin),
pluginsByType: make(map[PluginType]map[string]Plugin),
configs: make(map[string]map[string]interface{}),
dynamicLoadingSupported: dynamicLoadingSupported,
}
}
// IsDynamicLoadingSupported 检查是否支持动态加载插件
func (pm *PluginManager) IsDynamicLoadingSupported() bool {
return pm.dynamicLoadingSupported
}
// LoadPlugins 加载插件
func (pm *PluginManager) LoadPlugins() error {
// 确保插件目录存在
if err := os.MkdirAll(pm.pluginsDir, 0o755); err != nil {
return fmt.Errorf("创建插件目录失败: %v", err)
}
// 加载插件配置
if err := pm.loadPluginConfigs(); err != nil {
return fmt.Errorf("加载插件配置失败: %v", err)
}
// 如果不支持动态加载,则返回
if !pm.dynamicLoadingSupported {
fmt.Printf("警告: 当前系统(%s)不支持动态加载插件,跳过加载\n", runtime.GOOS)
return nil
}
// 遍历插件目录
err := filepath.Walk(pm.pluginsDir, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
// 跳过目录和非.so文件
if info.IsDir() || filepath.Ext(path) != ".so" {
return nil
}
// 加载插件
if err := pm.loadPlugin(path); err != nil {
fmt.Printf("加载插件 %s 失败: %v\n", path, err)
}
return nil
})
return err
}
// loadPluginConfigs 加载插件配置
func (pm *PluginManager) loadPluginConfigs() error {
configPath := filepath.Join(pm.pluginsDir, "plugins.json")
// 如果配置文件不存在,创建一个空的
if _, err := os.Stat(configPath); os.IsNotExist(err) {
file, err := os.Create(configPath)
if err != nil {
return fmt.Errorf("创建插件配置文件失败: %v", err)
}
file.Write([]byte("{}"))
file.Close()
return nil
}
// 读取配置文件
data, err := os.ReadFile(configPath)
if err != nil {
return fmt.Errorf("读取插件配置文件失败: %v", err)
}
// 解析配置
var configs map[string]map[string]interface{}
if err := json.Unmarshal(data, &configs); err != nil {
return fmt.Errorf("解析插件配置文件失败: %v", err)
}
pm.configs = configs
return nil
}
// savePluginConfigs 保存插件配置
func (pm *PluginManager) savePluginConfigs() error {
configPath := filepath.Join(pm.pluginsDir, "plugins.json")
// 创建配置数据
configs := make(map[string]map[string]interface{})
pm.mu.RLock()
for name, plugin := range pm.plugins {
config := pm.configs[name]
if config == nil {
config = make(map[string]interface{})
}
config["enabled"] = plugin.IsEnabled()
config["type"] = string(plugin.Type()) // 保存插件类型
configs[name] = config
}
pm.mu.RUnlock()
// 序列化配置
data, err := json.MarshalIndent(configs, "", " ")
if err != nil {
return fmt.Errorf("序列化插件配置失败: %v", err)
}
// 写入文件
if err := os.WriteFile(configPath, data, 0o644); err != nil {
return fmt.Errorf("写入插件配置文件失败: %v", err)
}
return nil
}
// loadPlugin 加载单个插件
func (pm *PluginManager) loadPlugin(path string) error {
// 打开插件文件
p, err := plugin.Open(path)
if err != nil {
return fmt.Errorf("打开插件失败: %v", err)
}
// 查找Plugin变量
symPlugin, err := p.Lookup("Plugin")
if err != nil {
return fmt.Errorf("查找Plugin变量失败: %v", err)
}
// 使用反射检查插件对象
pluginValue := reflect.ValueOf(symPlugin)
fmt.Printf("加载插件: %s, 类型: %s\n", path, pluginValue.Type())
// 查找基本字段或方法
var pluginName, pluginVersion, pluginAuthor, pluginDesc string
var pluginType PluginType = PluginTypeGeneral
var enabled = true
// 直接检查方法
// 尝试通过方法获取信息
nameFound := false
if nameMethod := pluginValue.MethodByName("Name"); nameMethod.IsValid() {
results := nameMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginName = results[0].String()
nameFound = true
}
}
if versionMethod := pluginValue.MethodByName("Version"); versionMethod.IsValid() {
results := versionMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginVersion = results[0].String()
}
}
if descMethod := pluginValue.MethodByName("Description"); descMethod.IsValid() {
results := descMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginDesc = results[0].String()
}
}
if authorMethod := pluginValue.MethodByName("Author"); authorMethod.IsValid() {
results := authorMethod.Call(nil)
if len(results) > 0 && results[0].Kind() == reflect.String {
pluginAuthor = results[0].String()
}
}
if typeMethod := pluginValue.MethodByName("Type"); typeMethod.IsValid() {
results := typeMethod.Call(nil)
if len(results) > 0 {
// 尝试匹配插件类型
typeStr := fmt.Sprint(results[0].Interface())
switch typeStr {
case "storage":
pluginType = PluginTypeStorage
case "security":
pluginType = PluginTypeSecurity
case "network":
pluginType = PluginTypeNetwork
case "utils":
pluginType = PluginTypeUtils
case "hardware":
pluginType = PluginTypeHardware
case "ui":
pluginType = PluginTypeUI
}
}
}
// 直接检查字段(仅在方法不可用时)
if !nameFound && pluginValue.Kind() == reflect.Ptr && !pluginValue.IsNil() {
elemValue := pluginValue.Elem()
// 检查elemValue是否为结构体
if elemValue.Kind() == reflect.Struct {
// 检查是否有name字段
if nameField := elemValue.FieldByName("name"); nameField.IsValid() && nameField.Kind() == reflect.String {
pluginName = nameField.String()
}
// 检查是否有version字段
if versionField := elemValue.FieldByName("version"); versionField.IsValid() && versionField.Kind() == reflect.String {
pluginVersion = versionField.String()
}
// 检查是否有description字段
if descField := elemValue.FieldByName("description"); descField.IsValid() && descField.Kind() == reflect.String {
pluginDesc = descField.String()
}
// 检查是否有author字段
if authorField := elemValue.FieldByName("author"); authorField.IsValid() && authorField.Kind() == reflect.String {
pluginAuthor = authorField.String()
}
// 检查是否有pluginType字段
if typeField := elemValue.FieldByName("pluginType"); typeField.IsValid() {
// 转换为字符串并尝试匹配已知类型
typeStr := fmt.Sprint(typeField.Interface())
switch typeStr {
case "storage":
pluginType = PluginTypeStorage
case "security":
pluginType = PluginTypeSecurity
case "network":
pluginType = PluginTypeNetwork
case "utils":
pluginType = PluginTypeUtils
case "hardware":
pluginType = PluginTypeHardware
case "ui":
pluginType = PluginTypeUI
}
}
// 检查是否有enabled字段
if enabledField := elemValue.FieldByName("enabled"); enabledField.IsValid() && enabledField.Kind() == reflect.Bool {
enabled = enabledField.Bool()
}
}
}
// 如果名称仍为空,则使用文件名
if pluginName == "" {
// 从路径中提取文件名并去掉扩展名
fileName := filepath.Base(path)
pluginName = strings.TrimSuffix(fileName, filepath.Ext(fileName))
}
fmt.Printf("创建适配器插件: 名称=%s, 版本=%s, 作者=%s, 类型=%s\n",
pluginName, pluginVersion, pluginAuthor, pluginType)
// 创建一个自定义插件结构体
customPlugin := &DynamicPlugin{
original: symPlugin,
name: pluginName,
version: pluginVersion,
description: pluginDesc,
author: pluginAuthor,
pluginType: pluginType,
enabled: enabled,
}
// 检查插件名称是否已存在
pm.mu.Lock()
defer pm.mu.Unlock()
if _, exists := pm.plugins[customPlugin.Name()]; exists {
return fmt.Errorf("插件 %s 已存在", customPlugin.Name())
}
// 设置插件启用状态
if config, exists := pm.configs[customPlugin.Name()]; exists {
if enabled, ok := config["enabled"].(bool); ok {
customPlugin.enabled = enabled
}
}
// 注册插件
pm.registerPlugin(customPlugin)
fmt.Printf("已成功注册插件: %s\n", customPlugin.Name())
return nil
}
// DynamicPlugin 完全动态的插件实现
type DynamicPlugin struct {
original interface{}
name string
version string
description string
author string
pluginType PluginType
enabled bool
}
// Name 返回插件名称
func (p *DynamicPlugin) Name() string {
return p.name
}
// Version 返回插件版本
func (p *DynamicPlugin) Version() string {
return p.version
}
// Description 返回插件描述
func (p *DynamicPlugin) Description() string {
return p.description
}
// Author 返回插件作者
func (p *DynamicPlugin) Author() string {
return p.author
}
// Type 返回插件类型
func (p *DynamicPlugin) Type() PluginType {
return p.pluginType
}
// IsEnabled 返回插件是否启用
func (p *DynamicPlugin) IsEnabled() bool {
return p.enabled
}
// SetEnabled 设置插件启用状态
func (p *DynamicPlugin) SetEnabled(enabled bool) {
p.enabled = enabled
// 尝试调用原始插件的SetEnabled方法
method := reflect.ValueOf(p.original).MethodByName("SetEnabled")
if method.IsValid() {
method.Call([]reflect.Value{reflect.ValueOf(enabled)})
}
}
// Init 初始化插件
func (p *DynamicPlugin) Init(ctx context.Context, config map[string]interface{}) error {
method := reflect.ValueOf(p.original).MethodByName("Init")
if !method.IsValid() {
return nil // 如果方法不存在,就不做任何事情
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 0:
// 无参数
case 1:
// 只有一个参数,可能是配置
args = append(args, reflect.ValueOf(config))
case 2:
// 两个参数,可能是上下文和配置
args = append(args, reflect.ValueOf(ctx), reflect.ValueOf(config))
default:
// 不支持更多参数
return fmt.Errorf("不支持的Init方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
return results[0].Interface().(error)
}
}
return nil
}
// Start 启动插件
func (p *DynamicPlugin) Start(ctx context.Context) error {
method := reflect.ValueOf(p.original).MethodByName("Start")
if !method.IsValid() {
return nil // 如果方法不存在,就不做任何事情
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 0:
// 无参数
case 1:
// 一个参数,可能是上下文
args = append(args, reflect.ValueOf(ctx))
default:
// 不支持更多参数
return fmt.Errorf("不支持的Start方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
return results[0].Interface().(error)
}
}
return nil
}
// Stop 停止插件
func (p *DynamicPlugin) Stop(ctx context.Context) error {
method := reflect.ValueOf(p.original).MethodByName("Stop")
if !method.IsValid() {
return nil // 如果方法不存在,就不做任何事情
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 0:
// 无参数
case 1:
// 一个参数,可能是上下文
args = append(args, reflect.ValueOf(ctx))
default:
// 不支持更多参数
return fmt.Errorf("不支持的Stop方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
return results[0].Interface().(error)
}
}
return nil
}
// Execute 执行插件功能
func (p *DynamicPlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
method := reflect.ValueOf(p.original).MethodByName("Execute")
if !method.IsValid() {
return nil, fmt.Errorf("插件不支持Execute方法")
}
// 确定方法参数数量和类型
methodType := method.Type()
numParams := methodType.NumIn()
// 准备参数
var args []reflect.Value
// 对于不同参数数量的处理
switch numParams {
case 2:
// 两个参数可能是action和params
args = append(args, reflect.ValueOf(action), reflect.ValueOf(params))
case 3:
// 三个参数可能是ctx、action和params
args = append(args, reflect.ValueOf(ctx), reflect.ValueOf(action), reflect.ValueOf(params))
default:
// 不支持其他参数数量
return nil, fmt.Errorf("不支持的Execute方法参数数量: %d", numParams)
}
// 调用方法
results := method.Call(args)
// 处理返回值
var result interface{}
var err error
switch len(results) {
case 1:
// 只有一个返回值,检查是否为错误
if results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[0].IsNil() {
err = results[0].Interface().(error)
}
} else {
result = results[0].Interface()
}
case 2:
// 两个返回值,第一个是结果,第二个是错误
if !results[0].IsNil() {
result = results[0].Interface()
}
if results[1].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[1].IsNil() {
err = results[1].Interface().(error)
}
}
}
return result, err
}
// GetOperationInfo 获取操作的参数信息
func (p *DynamicPlugin) GetOperationInfo(operation string) (map[string]interface{}, error) {
method := reflect.ValueOf(p.original).MethodByName("GetOperationInfo")
if !method.IsValid() {
return map[string]interface{}{}, nil
}
results := method.Call([]reflect.Value{reflect.ValueOf(operation)})
var result map[string]interface{}
var err error
if len(results) > 0 && !results[0].IsNil() {
if m, ok := results[0].Interface().(map[string]interface{}); ok {
result = m
} else {
result = map[string]interface{}{}
}
} else {
result = map[string]interface{}{}
}
if len(results) > 1 && results[1].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) {
if !results[1].IsNil() {
err = results[1].Interface().(error)
}
}
return result, err
}
// GetAllOperations 获取所有操作及其参数信息
func (p *DynamicPlugin) GetAllOperations() map[string]map[string]interface{} {
method := reflect.ValueOf(p.original).MethodByName("GetAllOperations")
if !method.IsValid() {
return map[string]map[string]interface{}{}
}
results := method.Call(nil)
if len(results) > 0 && !results[0].IsNil() {
if m, ok := results[0].Interface().(map[string]map[string]interface{}); ok {
return m
}
}
return map[string]map[string]interface{}{}
}
// registerPlugin 注册插件到插件管理器
func (pm *PluginManager) registerPlugin(plugin Plugin) {
pluginType := plugin.Type()
// 将插件添加到按名称索引的映射
pm.plugins[plugin.Name()] = plugin
// 将插件添加到按类型索引的映射
if pm.pluginsByType[pluginType] == nil {
pm.pluginsByType[pluginType] = make(map[string]Plugin)
}
pm.pluginsByType[pluginType][plugin.Name()] = plugin
}
// RegisterPlugin 注册内置插件
// 用于在不支持动态加载的平台上注册插件
func (pm *PluginManager) RegisterPlugin(plugin Plugin) error {
pm.mu.Lock()
defer pm.mu.Unlock()
if _, exists := pm.plugins[plugin.Name()]; exists {
return fmt.Errorf("插件 %s 已存在", plugin.Name())
}
// 设置插件启用状态
if config, exists := pm.configs[plugin.Name()]; exists {
if enabled, ok := config["enabled"].(bool); ok {
plugin.SetEnabled(enabled)
} else {
plugin.SetEnabled(true) // 默认启用
}
} else {
plugin.SetEnabled(true) // 默认启用
}
// 注册插件
pm.registerPlugin(plugin)
return nil
}
// GetPlugin 获取插件
func (pm *PluginManager) GetPlugin(name string) (Plugin, bool) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
return plugin, exists
}
// GetPluginsByType 按类型获取插件
func (pm *PluginManager) GetPluginsByType(pluginType PluginType) []Plugin {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugins := make([]Plugin, 0)
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for _, plugin := range typePlugins {
if plugin.IsEnabled() {
plugins = append(plugins, plugin)
}
}
}
return plugins
}
// GetAllPluginsByType 获取所有指定类型的插件,无论是否启用
func (pm *PluginManager) GetAllPluginsByType(pluginType PluginType) []Plugin {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugins := make([]Plugin, 0)
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for _, plugin := range typePlugins {
plugins = append(plugins, plugin)
}
}
return plugins
}
// GetAllPlugins 获取所有插件
func (pm *PluginManager) GetAllPlugins() []Plugin {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugins := make([]Plugin, 0, len(pm.plugins))
for _, plugin := range pm.plugins {
plugins = append(plugins, plugin)
}
return plugins
}
// GetPluginInfos 获取所有插件信息
func (pm *PluginManager) GetPluginInfos() []PluginInfo {
pm.mu.RLock()
defer pm.mu.RUnlock()
infos := make([]PluginInfo, 0, len(pm.plugins))
for name, plugin := range pm.plugins {
info := PluginInfo{
Name: plugin.Name(),
Version: plugin.Version(),
Description: plugin.Description(),
Author: plugin.Author(),
Type: plugin.Type(),
Enabled: plugin.IsEnabled(),
Config: pm.configs[name],
}
infos = append(infos, info)
}
return infos
}
// GetPluginInfosByType 按类型获取插件信息
func (pm *PluginManager) GetPluginInfosByType(pluginType PluginType) []PluginInfo {
pm.mu.RLock()
defer pm.mu.RUnlock()
infos := make([]PluginInfo, 0)
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
info := PluginInfo{
Name: plugin.Name(),
Version: plugin.Version(),
Description: plugin.Description(),
Author: plugin.Author(),
Type: plugin.Type(),
Enabled: plugin.IsEnabled(),
Config: pm.configs[name],
}
infos = append(infos, info)
}
}
return infos
}
// EnablePlugin 启用插件
func (pm *PluginManager) EnablePlugin(name string) error {
pm.mu.Lock()
defer pm.mu.Unlock()
plugin, exists := pm.plugins[name]
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
plugin.SetEnabled(true)
// 更新配置
if pm.configs[name] == nil {
pm.configs[name] = make(map[string]interface{})
}
pm.configs[name]["enabled"] = true
// 保存配置
return pm.savePluginConfigs()
}
// DisablePlugin 禁用插件
func (pm *PluginManager) DisablePlugin(name string) error {
pm.mu.Lock()
defer pm.mu.Unlock()
plugin, exists := pm.plugins[name]
if !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
plugin.SetEnabled(false)
// 更新配置
if pm.configs[name] == nil {
pm.configs[name] = make(map[string]interface{})
}
pm.configs[name]["enabled"] = false
// 保存配置
return pm.savePluginConfigs()
}
// InitPlugins 初始化所有插件
func (pm *PluginManager) InitPlugins(ctx context.Context) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
config := pm.configs[name]
if err := plugin.Init(ctx, config); err != nil {
return fmt.Errorf("初始化插件 %s 失败: %v", name, err)
}
}
return nil
}
// InitPluginsByType 初始化指定类型的所有插件
func (pm *PluginManager) InitPluginsByType(ctx context.Context, pluginType PluginType) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
config := pm.configs[name]
if err := plugin.Init(ctx, config); err != nil {
return fmt.Errorf("初始化插件 %s 失败: %v", name, err)
}
}
}
return nil
}
// StartPlugins 启动所有插件
func (pm *PluginManager) StartPlugins(ctx context.Context) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Start(ctx); err != nil {
return fmt.Errorf("启动插件 %s 失败: %v", name, err)
}
}
return nil
}
// StartPluginsByType 启动指定类型的所有插件
func (pm *PluginManager) StartPluginsByType(ctx context.Context, pluginType PluginType) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Start(ctx); err != nil {
return fmt.Errorf("启动插件 %s 失败: %v", name, err)
}
}
}
return nil
}
// StopPlugins 停止所有插件
func (pm *PluginManager) StopPlugins(ctx context.Context) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Stop(ctx); err != nil {
return fmt.Errorf("停止插件 %s 失败: %v", name, err)
}
}
return nil
}
// StopPluginsByType 停止指定类型的所有插件
func (pm *PluginManager) StopPluginsByType(ctx context.Context, pluginType PluginType) error {
pm.mu.RLock()
defer pm.mu.RUnlock()
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
if err := plugin.Stop(ctx); err != nil {
return fmt.Errorf("停止插件 %s 失败: %v", name, err)
}
}
}
return nil
}
// SetPluginConfig 设置插件配置
func (pm *PluginManager) SetPluginConfig(name string, config map[string]interface{}) error {
pm.mu.Lock()
defer pm.mu.Unlock()
if _, exists := pm.plugins[name]; !exists {
return fmt.Errorf("插件 %s 不存在", name)
}
pm.configs[name] = config
return pm.savePluginConfigs()
}
// GetPluginConfig 获取插件配置
func (pm *PluginManager) GetPluginConfig(name string) (map[string]interface{}, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
if _, exists := pm.plugins[name]; !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
config := pm.configs[name]
if config == nil {
config = make(map[string]interface{})
}
return config, nil
}
// ExecutePlugin 执行指定插件的操作
func (pm *PluginManager) ExecutePlugin(ctx context.Context, name string, action string, params map[string]interface{}) (interface{}, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
if !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
if !plugin.IsEnabled() {
return nil, fmt.Errorf("插件 %s 已禁用", name)
}
return plugin.Execute(ctx, action, params)
}
// ExecutePluginsByType 对指定类型的所有插件执行操作
func (pm *PluginManager) ExecutePluginsByType(ctx context.Context, pluginType PluginType, action string, params map[string]interface{}) map[string]interface{} {
pm.mu.RLock()
defer pm.mu.RUnlock()
results := make(map[string]interface{})
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
result, err := plugin.Execute(ctx, action, params)
results[name] = map[string]interface{}{
"result": result,
"error": err,
}
}
}
return results
}
// ExecuteAllPlugins 对所有插件执行操作
func (pm *PluginManager) ExecuteAllPlugins(ctx context.Context, action string, params map[string]interface{}) map[string]interface{} {
pm.mu.RLock()
defer pm.mu.RUnlock()
results := make(map[string]interface{})
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
result, err := plugin.Execute(ctx, action, params)
results[name] = map[string]interface{}{
"result": result,
"error": err,
}
}
return results
}
// GetPluginOperationInfo 获取插件特定操作的参数信息
func (pm *PluginManager) GetPluginOperationInfo(name string, operation string) (map[string]interface{}, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
if !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
if !plugin.IsEnabled() {
return nil, fmt.Errorf("插件 %s 已禁用", name)
}
return plugin.GetOperationInfo(operation)
}
// GetPluginAllOperations 获取插件所有操作及其参数信息
func (pm *PluginManager) GetPluginAllOperations(name string) (map[string]map[string]interface{}, error) {
pm.mu.RLock()
defer pm.mu.RUnlock()
plugin, exists := pm.plugins[name]
if !exists {
return nil, fmt.Errorf("插件 %s 不存在", name)
}
if !plugin.IsEnabled() {
return nil, fmt.Errorf("插件 %s 已禁用", name)
}
return plugin.GetAllOperations(), nil
}
// GetOperationsByType 获取指定类型插件的所有操作信息
func (pm *PluginManager) GetOperationsByType(pluginType PluginType) map[string]map[string]map[string]interface{} {
pm.mu.RLock()
defer pm.mu.RUnlock()
result := make(map[string]map[string]map[string]interface{})
if typePlugins, exists := pm.pluginsByType[pluginType]; exists {
for name, plugin := range typePlugins {
if !plugin.IsEnabled() {
continue
}
result[name] = plugin.GetAllOperations()
}
}
return result
}
// GetAllPluginsOperations 获取所有插件的所有操作信息
func (pm *PluginManager) GetAllPluginsOperations() map[string]map[string]map[string]interface{} {
pm.mu.RLock()
defer pm.mu.RUnlock()
result := make(map[string]map[string]map[string]interface{})
for name, plugin := range pm.plugins {
if !plugin.IsEnabled() {
continue
}
result[name] = plugin.GetAllOperations()
}
return result
}