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

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

367 lines
9.8 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 main
import (
"context"
"fmt"
"runtime"
"strings"
"github.com/darkit/goproxy/examples/plugin"
)
// 这是内置插件的示例实现
// LogPlugin 日志插件
type LogPlugin struct {
name string
version string
description string
author string
pluginType plugin.PluginType
enabled bool
level string
}
// 创建内置日志插件 - 示例1明确指定插件类型
func NewLogPlugin() *LogPlugin {
return &LogPlugin{
name: "InternalLogPlugin",
version: "1.0.0",
description: "内置日志插件,在不支持动态加载插件的平台上使用",
author: "开发者",
pluginType: plugin.PluginTypeUtils, // 明确指定为工具类插件
enabled: true,
level: "info",
}
}
// 创建内置日志插件 - 示例2使用默认插件类型通用插件
func NewDefaultLogPlugin() *LogPlugin {
return &LogPlugin{
name: "DefaultLogPlugin",
version: "1.0.0",
description: "使用默认类型的内置日志插件示例",
author: "开发者",
pluginType: plugin.PluginTypeGeneral, // 自动设置为通用插件类型
enabled: true,
level: "info",
}
}
// 实现Plugin接口
func (p *LogPlugin) Name() string {
return p.name
}
func (p *LogPlugin) Version() string {
return p.version
}
func (p *LogPlugin) Description() string {
return p.description
}
func (p *LogPlugin) Author() string {
return p.author
}
// Type 实现插件类型方法
func (p *LogPlugin) Type() plugin.PluginType {
return p.pluginType
}
func (p *LogPlugin) IsEnabled() bool {
return p.enabled
}
func (p *LogPlugin) SetEnabled(enabled bool) {
p.enabled = enabled
}
// GetOperationInfo 获取操作的参数信息
func (p *LogPlugin) GetOperationInfo(operation string) (map[string]interface{}, error) {
// 转换为小写以便不区分大小写匹配
operation = strings.ToLower(operation)
switch operation {
case "log":
return map[string]interface{}{
"name": "log",
"description": "记录日志消息",
"parameters": map[string]interface{}{
"message": map[string]interface{}{
"type": "string",
"description": "要记录的日志消息",
"required": true,
},
},
"returns": map[string]interface{}{
"result": map[string]interface{}{
"type": "boolean",
"description": "操作是否成功",
},
},
}, nil
case "setlevel":
return map[string]interface{}{
"name": "setLevel",
"description": "设置日志级别",
"parameters": map[string]interface{}{
"level": map[string]interface{}{
"type": "string",
"description": "日志级别info、debug、warn、error",
"required": true,
},
},
"returns": map[string]interface{}{
"result": map[string]interface{}{
"type": "boolean",
"description": "操作是否成功",
},
},
}, nil
case "getlevel":
return map[string]interface{}{
"name": "getLevel",
"description": "获取当前日志级别",
"parameters": map[string]interface{}{},
"returns": map[string]interface{}{
"result": map[string]interface{}{
"type": "string",
"description": "当前日志级别",
},
},
}, nil
case "getstatus":
return map[string]interface{}{
"name": "getStatus",
"description": "获取插件状态信息",
"parameters": map[string]interface{}{},
"returns": map[string]interface{}{
"result": map[string]interface{}{
"type": "object",
"description": "包含插件状态的对象",
"properties": map[string]interface{}{
"name": map[string]interface{}{"type": "string"},
"version": map[string]interface{}{"type": "string"},
"level": map[string]interface{}{"type": "string"},
"enabled": map[string]interface{}{"type": "boolean"},
"type": map[string]interface{}{"type": "string"},
},
},
},
}, nil
default:
return nil, fmt.Errorf("未知的操作: %s", operation)
}
}
// GetAllOperations 获取所有操作及其参数信息
func (p *LogPlugin) GetAllOperations() map[string]map[string]interface{} {
operations := make(map[string]map[string]interface{})
// 获取所有操作的信息
for _, op := range []string{"log", "setlevel", "getlevel", "getstatus"} {
info, err := p.GetOperationInfo(op)
if err == nil {
operations[op] = info
}
}
return operations
}
func (p *LogPlugin) Init(ctx context.Context, config map[string]interface{}) error {
if level, ok := config["level"].(string); ok {
p.level = level
}
fmt.Printf("内置日志插件[%s]已初始化,日志级别: %s, 插件类型: %s\n", p.name, p.level, p.Type())
return nil
}
func (p *LogPlugin) Start(ctx context.Context) error {
fmt.Printf("内置日志插件[%s]已启动\n", p.name)
return nil
}
func (p *LogPlugin) Stop(ctx context.Context) error {
fmt.Printf("内置日志插件[%s]已停止\n", p.name)
return nil
}
// Execute 实现Execute方法以满足Plugin接口
func (p *LogPlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) {
switch action {
case "log":
// 需要参数: message
message, ok := params["message"].(string)
if !ok {
return nil, fmt.Errorf("缺少必需参数: message")
}
p.Log(message)
return true, nil
case "setLevel":
// 需要参数: level
level, ok := params["level"].(string)
if !ok {
return nil, fmt.Errorf("缺少必需参数: level")
}
p.level = level
return true, nil
case "getLevel":
// 不需要参数,返回当前日志级别
return p.level, nil
case "getStatus":
// 返回插件状态信息
status := map[string]interface{}{
"name": p.name,
"version": p.version,
"level": p.level,
"enabled": p.enabled,
"type": p.Type(),
}
return status, nil
default:
return nil, fmt.Errorf("未知的操作: %s", action)
}
}
// Log 记录日志
func (p *LogPlugin) Log(message string) {
fmt.Printf("[%s][%s] %s\n", p.name, p.level, message)
}
func main() {
// 创建插件管理器
pluginsDir := "../admin/plugins"
pm := plugin.NewPluginManager(pluginsDir)
// 检查当前系统是否支持动态加载插件
if pm.IsDynamicLoadingSupported() {
fmt.Printf("当前系统(%s)支持动态加载插件\n", runtime.GOOS)
} else {
fmt.Printf("当前系统(%s)不支持动态加载插件\n", runtime.GOOS)
// 在不支持动态加载的系统上注册内置插件
// 示例1注册明确指定类型的插件
logPlugin := NewLogPlugin()
pm.RegisterPlugin(logPlugin)
// 示例2注册使用默认类型的插件
defaultLogPlugin := NewDefaultLogPlugin()
pm.RegisterPlugin(defaultLogPlugin)
fmt.Println("已注册两个内置插件以展示不同的插件类型设置方式")
}
// 加载插件
fmt.Println("正在加载插件...")
if err := pm.LoadPlugins(); err != nil {
fmt.Printf("加载插件失败: %v\n", err)
}
// 配置插件
logPluginConfig := map[string]interface{}{
"level": "debug",
}
if err := pm.SetPluginConfig("InternalLogPlugin", logPluginConfig); err != nil {
fmt.Printf("配置插件失败: %v\n", err)
}
// 初始化插件
ctx := context.Background()
fmt.Println("正在初始化插件...")
if err := pm.InitPlugins(ctx); err != nil {
fmt.Printf("初始化插件失败: %v\n", err)
}
// 启动插件
fmt.Println("正在启动插件...")
if err := pm.StartPlugins(ctx); err != nil {
fmt.Printf("启动插件失败: %v\n", err)
}
// 获取并打印所有插件信息
fmt.Println("\n已加载的插件列表:")
plugins := pm.GetPluginInfos()
for i, info := range plugins {
status := "启用"
if !info.Enabled {
status = "禁用"
}
fmt.Printf("[%d] %s (v%s) - %s [%s]\n作者: %s\n类型: %s\n",
i, info.Name, info.Version, info.Description, status, info.Author, info.Type)
// 打印插件配置
if len(info.Config) > 0 {
fmt.Println("配置:")
for k, v := range info.Config {
fmt.Printf(" %s: %v\n", k, v)
}
}
fmt.Println()
}
// 使用第一个启用的插件(这里只是示例)
if len(plugins) > 0 {
for _, info := range plugins {
if info.Enabled {
fmt.Printf("正在使用插件: %s (类型: %s)\n", info.Name, info.Type)
if p, ok := pm.GetPlugin(info.Name); ok {
// 这里可以根据插件类型执行特定操作
if logPlugin, ok := p.(*LogPlugin); ok {
logPlugin.Log("这是一条测试日志消息")
// 改用Execute方法调用
logPlugin.Execute(ctx, "log", map[string]interface{}{
"message": "这是一条测试日志消息",
})
}
}
break
}
}
}
// 按类型获取和使用插件
fmt.Println("\n按类型获取插件:")
// 获取工具类插件
utilsPlugins := pm.GetPluginsByType(plugin.PluginTypeUtils)
fmt.Printf("找到 %d 个工具类插件\n", len(utilsPlugins))
for _, p := range utilsPlugins {
fmt.Printf("工具类插件: %s\n", p.Name())
if logPlugin, ok := p.(*LogPlugin); ok {
logPlugin.Log("通过类型获取到的日志插件记录消息")
// 改用Execute方法调用
logPlugin.Execute(ctx, "log", map[string]interface{}{
"message": "通过类型获取到的日志插件记录消息",
})
}
}
// 获取通用类型插件
generalPlugins := pm.GetPluginsByType(plugin.PluginTypeGeneral)
fmt.Printf("找到 %d 个通用类型插件\n", len(generalPlugins))
for _, p := range generalPlugins {
fmt.Printf("通用类型插件: %s\n", p.Name())
if logPlugin, ok := p.(*LogPlugin); ok {
logPlugin.Log("通过类型获取到的通用类型插件记录消息")
// 改用Execute方法调用
logPlugin.Execute(ctx, "log", map[string]interface{}{
"message": "通过类型获取到的通用类型插件记录消息",
})
}
}
// 停止插件
fmt.Println("\n正在停止插件...")
if err := pm.StopPlugins(ctx); err != nil {
fmt.Printf("停止插件失败: %v\n", err)
}
fmt.Println("示例结束")
}