- Add provider catalog and device status management for edge nodes - Update edge config and model queue services - Add status provider tests - Update proto definitions for runtime - Add agent-task for m-provider-catalog-device-status
115 lines
2.6 KiB
Go
115 lines
2.6 KiB
Go
package node
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/google/uuid"
|
|
"iop/packages/go/config"
|
|
)
|
|
|
|
// NodeRecord is the pre-registered node definition stored in edge.
|
|
type NodeRecord struct {
|
|
ID string
|
|
Alias string
|
|
Token string
|
|
AgentKind string
|
|
Index int
|
|
Adapters config.AdaptersConf
|
|
Providers []config.NodeProviderConf
|
|
Runtime config.RuntimeConf
|
|
}
|
|
|
|
// NodeStore holds pre-registered node definitions, keyed by token.
|
|
type NodeStore struct {
|
|
mu sync.RWMutex
|
|
byToken map[string]*NodeRecord
|
|
byID map[string]*NodeRecord
|
|
}
|
|
|
|
func NewNodeStore() *NodeStore {
|
|
return &NodeStore{
|
|
byToken: make(map[string]*NodeRecord),
|
|
byID: make(map[string]*NodeRecord),
|
|
}
|
|
}
|
|
|
|
func (s *NodeStore) Add(rec *NodeRecord) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.byToken[rec.Token] = rec
|
|
s.byID[rec.ID] = rec
|
|
}
|
|
|
|
func (s *NodeStore) FindByToken(token string) (*NodeRecord, bool) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
r, ok := s.byToken[token]
|
|
return r, ok
|
|
}
|
|
|
|
func (s *NodeStore) FindByID(id string) (*NodeRecord, bool) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
r, ok := s.byID[id]
|
|
return r, ok
|
|
}
|
|
|
|
func (s *NodeStore) All() []*NodeRecord {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
out := make([]*NodeRecord, 0, len(s.byID))
|
|
for _, r := range s.byID {
|
|
out = append(out, r)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// LoadFromConfig seeds the store from EdgeConfig.Nodes.
|
|
func LoadFromConfig(defs []config.NodeDefinition) (*NodeStore, error) {
|
|
s := NewNodeStore()
|
|
seenToken := make(map[string]bool)
|
|
seenAlias := make(map[string]bool)
|
|
seenID := make(map[string]bool)
|
|
for i, d := range defs {
|
|
if d.Token == "" {
|
|
return nil, fmt.Errorf("node[%d] alias=%q: token must not be empty", i, d.Alias)
|
|
}
|
|
if seenToken[d.Token] {
|
|
return nil, fmt.Errorf("node[%d] alias=%q: duplicate token", i, d.Alias)
|
|
}
|
|
if seenAlias[d.Alias] {
|
|
return nil, fmt.Errorf("node[%d] alias=%q: duplicate alias", i, d.Alias)
|
|
}
|
|
if d.ID != "" && seenID[d.ID] {
|
|
return nil, fmt.Errorf("node[%d] alias=%q: duplicate id %q", i, d.Alias, d.ID)
|
|
}
|
|
seenToken[d.Token] = true
|
|
seenAlias[d.Alias] = true
|
|
nodeID := d.ID
|
|
if nodeID == "" {
|
|
nodeID = uuid.NewString()
|
|
} else {
|
|
seenID[d.ID] = true
|
|
}
|
|
agentKind := d.AgentKind
|
|
if agentKind == "" {
|
|
agentKind = config.AgentKindGenericNode
|
|
}
|
|
adapters := d.Adapters
|
|
if err := config.NormalizeAdapters(&adapters); err != nil {
|
|
return nil, fmt.Errorf("node[%d] alias=%q: adapters: %w", i, d.Alias, err)
|
|
}
|
|
s.Add(&NodeRecord{
|
|
ID: nodeID,
|
|
Alias: d.Alias,
|
|
Token: d.Token,
|
|
AgentKind: agentKind,
|
|
Index: i,
|
|
Adapters: adapters,
|
|
Providers: d.Providers,
|
|
Runtime: d.Runtime,
|
|
})
|
|
}
|
|
return s, nil
|
|
}
|