mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-11 17:39:46 +08:00
✨ feat(jvm): 打通 JVM 只读资源浏览链路
- 后端新增 JVMListResources 与 JVMGetValue 接口并补齐回归测试 - Sidebar 基于能力探测展示 JVM 模式节点并懒加载资源节点 - TabManager 接入 JVMOverview、JVMResourceBrowser 与模式徽标展示 - 补齐 JVM Tab 元数据与连接持久化 sanitize 逻辑 - 更新需求追踪文档并记录 Task 4 验证结果与残余风险
This commit is contained in:
@@ -7,13 +7,22 @@ import (
|
||||
|
||||
var newJVMProvider = jvm.NewProvider
|
||||
|
||||
func (a *App) TestJVMConnection(cfg connection.ConnectionConfig) connection.QueryResult {
|
||||
func resolveJVMProvider(cfg connection.ConnectionConfig) (connection.ConnectionConfig, jvm.Provider, error) {
|
||||
normalized, err := jvm.NormalizeConnectionConfig(cfg)
|
||||
if err != nil {
|
||||
return connection.QueryResult{Success: false, Message: err.Error()}
|
||||
return connection.ConnectionConfig{}, nil, err
|
||||
}
|
||||
|
||||
provider, err := newJVMProvider(normalized.JVM.PreferredMode)
|
||||
if err != nil {
|
||||
return connection.ConnectionConfig{}, nil, err
|
||||
}
|
||||
|
||||
return normalized, provider, nil
|
||||
}
|
||||
|
||||
func (a *App) TestJVMConnection(cfg connection.ConnectionConfig) connection.QueryResult {
|
||||
normalized, provider, err := resolveJVMProvider(cfg)
|
||||
if err != nil {
|
||||
return connection.QueryResult{Success: false, Message: err.Error()}
|
||||
}
|
||||
@@ -25,6 +34,34 @@ func (a *App) TestJVMConnection(cfg connection.ConnectionConfig) connection.Quer
|
||||
return connection.QueryResult{Success: true, Message: "JVM 连接成功"}
|
||||
}
|
||||
|
||||
func (a *App) JVMListResources(cfg connection.ConnectionConfig, parentPath string) connection.QueryResult {
|
||||
normalized, provider, err := resolveJVMProvider(cfg)
|
||||
if err != nil {
|
||||
return connection.QueryResult{Success: false, Message: err.Error()}
|
||||
}
|
||||
|
||||
items, err := provider.ListResources(a.ctx, normalized, parentPath)
|
||||
if err != nil {
|
||||
return connection.QueryResult{Success: false, Message: err.Error()}
|
||||
}
|
||||
|
||||
return connection.QueryResult{Success: true, Data: items}
|
||||
}
|
||||
|
||||
func (a *App) JVMGetValue(cfg connection.ConnectionConfig, resourcePath string) connection.QueryResult {
|
||||
normalized, provider, err := resolveJVMProvider(cfg)
|
||||
if err != nil {
|
||||
return connection.QueryResult{Success: false, Message: err.Error()}
|
||||
}
|
||||
|
||||
value, err := provider.GetValue(a.ctx, normalized, resourcePath)
|
||||
if err != nil {
|
||||
return connection.QueryResult{Success: false, Message: err.Error()}
|
||||
}
|
||||
|
||||
return connection.QueryResult{Success: true, Data: value}
|
||||
}
|
||||
|
||||
func (a *App) JVMProbeCapabilities(cfg connection.ConnectionConfig) connection.QueryResult {
|
||||
normalized, err := jvm.NormalizeConnectionConfig(cfg)
|
||||
if err != nil {
|
||||
|
||||
@@ -15,7 +15,9 @@ type fakeJVMProvider struct {
|
||||
probe []jvm.Capability
|
||||
probeErr error
|
||||
list []jvm.ResourceSummary
|
||||
listErr error
|
||||
value jvm.ValueSnapshot
|
||||
valueErr error
|
||||
apply jvm.ApplyResult
|
||||
}
|
||||
|
||||
@@ -27,10 +29,10 @@ func (f fakeJVMProvider) ProbeCapabilities(context.Context, connection.Connectio
|
||||
return f.probe, f.probeErr
|
||||
}
|
||||
func (f fakeJVMProvider) ListResources(context.Context, connection.ConnectionConfig, string) ([]jvm.ResourceSummary, error) {
|
||||
return f.list, nil
|
||||
return f.list, f.listErr
|
||||
}
|
||||
func (f fakeJVMProvider) GetValue(context.Context, connection.ConnectionConfig, string) (jvm.ValueSnapshot, error) {
|
||||
return f.value, nil
|
||||
return f.value, f.valueErr
|
||||
}
|
||||
func (f fakeJVMProvider) PreviewChange(context.Context, connection.ConnectionConfig, jvm.ChangeRequest) (jvm.ChangePreview, error) {
|
||||
return jvm.ChangePreview{Allowed: true, Summary: "preview"}, nil
|
||||
@@ -238,3 +240,84 @@ func TestJVMProbeCapabilitiesUsesReadableLabelForUnsupportedMode(t *testing.T) {
|
||||
t.Fatalf("expected unsupported mode error, got %#v", items[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestJVMListResourcesReturnsProviderPayload(t *testing.T) {
|
||||
app := NewAppWithSecretStore(nil)
|
||||
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
|
||||
return fakeJVMProvider{
|
||||
list: []jvm.ResourceSummary{
|
||||
{
|
||||
ID: "memory.heap",
|
||||
Kind: "folder",
|
||||
Name: "Heap",
|
||||
Path: "/memory/heap",
|
||||
ProviderMode: jvm.ModeJMX,
|
||||
CanRead: true,
|
||||
HasChildren: true,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
defer restore()
|
||||
|
||||
res := app.JVMListResources(connection.ConnectionConfig{
|
||||
Type: "jvm",
|
||||
Host: "orders.internal",
|
||||
JVM: connection.JVMConfig{
|
||||
PreferredMode: "jmx",
|
||||
AllowedModes: []string{"jmx"},
|
||||
},
|
||||
}, "/memory")
|
||||
|
||||
if !res.Success {
|
||||
t.Fatalf("expected success, got %+v", res)
|
||||
}
|
||||
items, ok := res.Data.([]jvm.ResourceSummary)
|
||||
if !ok || len(items) != 1 {
|
||||
t.Fatalf("expected one resource summary, got %#v", res.Data)
|
||||
}
|
||||
if items[0].Path != "/memory/heap" {
|
||||
t.Fatalf("expected resource path %q, got %#v", "/memory/heap", items[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestJVMGetValueReturnsProviderPayload(t *testing.T) {
|
||||
app := NewAppWithSecretStore(nil)
|
||||
restore := swapJVMProviderFactory(func(mode string) (jvm.Provider, error) {
|
||||
return fakeJVMProvider{
|
||||
value: jvm.ValueSnapshot{
|
||||
ResourceID: "memory.heap.used",
|
||||
Kind: "metric",
|
||||
Format: "number",
|
||||
Value: 128,
|
||||
Metadata: map[string]any{
|
||||
"unit": "MiB",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
defer restore()
|
||||
|
||||
res := app.JVMGetValue(connection.ConnectionConfig{
|
||||
Type: "jvm",
|
||||
Host: "orders.internal",
|
||||
JVM: connection.JVMConfig{
|
||||
PreferredMode: "jmx",
|
||||
AllowedModes: []string{"jmx"},
|
||||
},
|
||||
}, "/memory/heap/used")
|
||||
|
||||
if !res.Success {
|
||||
t.Fatalf("expected success, got %+v", res)
|
||||
}
|
||||
snapshot, ok := res.Data.(jvm.ValueSnapshot)
|
||||
if !ok {
|
||||
t.Fatalf("expected value snapshot, got %#v", res.Data)
|
||||
}
|
||||
if snapshot.ResourceID != "memory.heap.used" {
|
||||
t.Fatalf("expected resource id %q, got %#v", "memory.heap.used", snapshot)
|
||||
}
|
||||
if snapshot.Metadata["unit"] != "MiB" {
|
||||
t.Fatalf("expected unit metadata %q, got %#v", "MiB", snapshot.Metadata)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user