* fix(autoscan): bind sources by plugin id * fix(autoscan): skip overlapping source polls
84 lines
3.1 KiB
Go
84 lines
3.1 KiB
Go
package autoscan
|
|
|
|
import (
|
|
"context"
|
|
|
|
pluginv1 "github.com/Silo-Server/silo-plugin-sdk/pkg/pluginproto/silo/plugin/v1"
|
|
)
|
|
|
|
// ScanSourceProvider yields changed paths for one source. The engine calls
|
|
// PollChanges; production wraps the plugins.Service scan_source resolver.
|
|
type ScanSourceProvider interface {
|
|
PollChanges(ctx context.Context, pluginID, capabilityID, marker string, conn ResolvedConnection, sourceConfig map[string]string) (changes []Change, nextMarker string, err error)
|
|
}
|
|
|
|
// PollChangesClient is the slice of *pluginhost.ScanSourceClient used here. It
|
|
// is exported so wiring in the api package can declare an adapter whose
|
|
// ScanSourceClient returns it (Go interface method signatures must match
|
|
// exactly across packages, and the unexported form could not be named there).
|
|
type PollChangesClient interface {
|
|
PollChanges(ctx context.Context, req *pluginv1.PollChangesRequest) (*pluginv1.PollChangesResponse, error)
|
|
}
|
|
|
|
// ScanSourceResolver yields a per-(plugin, capability) scan-source client.
|
|
// Exported for the same cross-package adapter reason as PollChangesClient.
|
|
type ScanSourceResolver interface {
|
|
ScanSourceClient(ctx context.Context, pluginID, capabilityID string) (PollChangesClient, error)
|
|
}
|
|
|
|
type pluginProvider struct{ resolver ScanSourceResolver }
|
|
|
|
// NewPluginProvider builds the production scan-source provider over the plugins
|
|
// resolver.
|
|
func NewPluginProvider(resolver ScanSourceResolver) ScanSourceProvider {
|
|
return &pluginProvider{resolver: resolver}
|
|
}
|
|
|
|
func (p *pluginProvider) PollChanges(ctx context.Context, pluginID, capabilityID, marker string, conn ResolvedConnection, sourceConfig map[string]string) ([]Change, string, error) {
|
|
client, err := p.resolver.ScanSourceClient(ctx, pluginID, capabilityID)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
resp, err := client.PollChanges(ctx, &pluginv1.PollChangesRequest{
|
|
CapabilityId: capabilityID,
|
|
Marker: marker,
|
|
Connection: &pluginv1.ResolvedConnection{BaseUrl: conn.BaseURL, ApiKey: conn.APIKey},
|
|
SourceConfig: sourceConfig,
|
|
})
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
if structured := resp.GetChanges(); len(structured) > 0 {
|
|
changes := make([]Change, 0, len(structured))
|
|
for _, change := range structured {
|
|
if change == nil {
|
|
continue
|
|
}
|
|
changes = append(changes, Change{
|
|
SourcePath: change.GetSourcePath(),
|
|
Scope: scanSourceScope(change.GetScope()),
|
|
})
|
|
}
|
|
return changes, resp.GetNextMarker(), nil
|
|
}
|
|
|
|
// Legacy plugins return only source_paths. Treat them as auto/file-like
|
|
// paths so the existing parent-directory collapse behavior is preserved.
|
|
changes := make([]Change, 0, len(resp.GetSourcePaths()))
|
|
for _, path := range resp.GetSourcePaths() {
|
|
changes = append(changes, Change{SourcePath: path, Scope: ChangeScopeAuto})
|
|
}
|
|
return changes, resp.GetNextMarker(), nil
|
|
}
|
|
|
|
func scanSourceScope(scope pluginv1.ScanSourceChangeScope) ChangeScope {
|
|
switch scope {
|
|
case pluginv1.ScanSourceChangeScope_SCAN_SOURCE_CHANGE_SCOPE_FILE:
|
|
return ChangeScopeFile
|
|
case pluginv1.ScanSourceChangeScope_SCAN_SOURCE_CHANGE_SCOPE_SUBTREE:
|
|
return ChangeScopeSubtree
|
|
default:
|
|
return ChangeScopeAuto
|
|
}
|
|
}
|