Skip to content

Commit 0c1002f

Browse files
implement action sdk
1 parent 2ebc651 commit 0c1002f

File tree

29 files changed

+3652
-103
lines changed

29 files changed

+3652
-103
lines changed

sdk/action/.gitkeep

Whitespace-only changes.

sdk/action/client.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package action
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"action/config"
8+
"action/event"
9+
"action/task"
10+
11+
"github.com/LumeraProtocol/supernode/pkg/lumera"
12+
)
13+
14+
type ActionClient interface {
15+
StartSense(ctx context.Context, fileHash string, actionID string, filePath string) (string, error)
16+
17+
StartCascade(ctx context.Context, fileHash string, actionID string, filePath string, signedData string) (string, error)
18+
19+
GetTask(ctx context.Context, taskID string) (*task.TaskEntry, bool)
20+
21+
SubscribeToEvents(eventType event.EventType, handler event.Handler)
22+
23+
SubscribeToAllEvents(handler event.Handler)
24+
}
25+
26+
type ActionClientImpl struct {
27+
lumeraClient lumera.Client
28+
config config.Config
29+
taskManager task.Manager
30+
}
31+
32+
func NewActionClient(lumeraClient lumera.Client, config config.Config) (ActionClient, error) {
33+
taskManager, err := task.NewManager(lumeraClient, config)
34+
if err != nil {
35+
return nil, fmt.Errorf("failed to create task manager: %w", err)
36+
}
37+
38+
return &ActionClientImpl{
39+
lumeraClient: lumeraClient,
40+
config: config,
41+
taskManager: taskManager,
42+
}, nil
43+
}
44+
45+
func (ac *ActionClientImpl) StartSense(
46+
ctx context.Context,
47+
fileHash string,
48+
actionID string,
49+
filePath string,
50+
) (string, error) {
51+
ac.config.Logger.Debug(ctx, "Starting sense operation",
52+
"fileHash", fileHash,
53+
"actionID", actionID,
54+
"filePath", filePath)
55+
56+
if fileHash == "" {
57+
ac.config.Logger.Error(ctx, "Empty file hash provided")
58+
return "", ErrEmptyFileHash
59+
}
60+
if actionID == "" {
61+
ac.config.Logger.Error(ctx, "Empty action ID provided")
62+
return "", ErrEmptyActionID
63+
}
64+
if filePath == "" {
65+
ac.config.Logger.Error(ctx, "Empty file path provided")
66+
return "", ErrEmptyFilePath
67+
}
68+
69+
taskID, err := ac.taskManager.CreateSenseTask(ctx, fileHash, actionID, filePath)
70+
if err != nil {
71+
ac.config.Logger.Error(ctx, "Failed to create sense task", "error", err)
72+
return "", fmt.Errorf("failed to create sense task: %w", err)
73+
}
74+
75+
ac.config.Logger.Info(ctx, "Sense task created successfully", "taskID", taskID)
76+
return taskID, nil
77+
}
78+
79+
func (ac *ActionClientImpl) StartCascade(
80+
ctx context.Context,
81+
fileHash string,
82+
actionID string,
83+
filePath string,
84+
signedData string,
85+
) (string, error) {
86+
ac.config.Logger.Debug(ctx, "Starting cascade operation",
87+
"fileHash", fileHash,
88+
"actionID", actionID,
89+
"filePath", filePath)
90+
91+
if fileHash == "" {
92+
ac.config.Logger.Error(ctx, "Empty file hash provided")
93+
return "", ErrEmptyFileHash
94+
}
95+
if actionID == "" {
96+
ac.config.Logger.Error(ctx, "Empty action ID provided")
97+
return "", ErrEmptyActionID
98+
}
99+
if filePath == "" {
100+
ac.config.Logger.Error(ctx, "Empty file path provided")
101+
return "", ErrEmptyFilePath
102+
}
103+
104+
taskID, err := ac.taskManager.CreateCascadeTask(ctx, fileHash, actionID, filePath, signedData)
105+
if err != nil {
106+
ac.config.Logger.Error(ctx, "Failed to create cascade task", "error", err)
107+
return "", fmt.Errorf("failed to create cascade task: %w", err)
108+
}
109+
110+
ac.config.Logger.Info(ctx, "Cascade task created successfully", "taskID", taskID)
111+
return taskID, nil
112+
}
113+
114+
func (ac *ActionClientImpl) GetTask(ctx context.Context, taskID string) (*task.TaskEntry, bool) {
115+
ac.config.Logger.Debug(ctx, "Getting task", "taskID", taskID)
116+
task, found := ac.taskManager.GetTask(ctx, taskID)
117+
if !found {
118+
ac.config.Logger.Debug(ctx, "Task not found", "taskID", taskID)
119+
} else {
120+
ac.config.Logger.Debug(ctx, "Task found", "taskID", taskID, "status", task.Status)
121+
}
122+
return task, found
123+
}
124+
125+
// SubscribeToEvents registers a handler for specific event types
126+
func (ac *ActionClientImpl) SubscribeToEvents(eventType event.EventType, handler event.Handler) {
127+
ac.config.Logger.Debug(context.Background(), "Subscribing to events", "eventType", eventType)
128+
if ac.config.EventBus != nil {
129+
ac.config.EventBus.Subscribe(eventType, handler)
130+
} else {
131+
ac.config.Logger.Warn(context.Background(), "EventBus is nil, cannot subscribe to events")
132+
}
133+
}
134+
135+
// SubscribeToAllEvents registers a handler for all events
136+
func (ac *ActionClientImpl) SubscribeToAllEvents(handler event.Handler) {
137+
ac.config.Logger.Debug(context.Background(), "Subscribing to all events")
138+
if ac.config.EventBus != nil {
139+
ac.config.EventBus.SubscribeAll(handler)
140+
} else {
141+
ac.config.Logger.Warn(context.Background(), "EventBus is nil, cannot subscribe to events")
142+
}
143+
}

sdk/action/client/check_health.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

sdk/action/client/client.go

Lines changed: 0 additions & 35 deletions
This file was deleted.

sdk/action/client/options.go

Lines changed: 0 additions & 28 deletions
This file was deleted.

sdk/action/errors.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package action
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
)
7+
8+
var (
9+
ErrEmptyFileHash = errors.New("file hash cannot be empty")
10+
ErrEmptyActionID = errors.New("action ID cannot be empty")
11+
ErrEmptyFilePath = errors.New("file path cannot be empty")
12+
ErrNoValidAction = errors.New("no action found with the specified ID")
13+
ErrInvalidAction = errors.New("action is not in a valid state")
14+
ErrNoSupernodes = errors.New("no valid supernodes available")
15+
ErrTaskCreation = errors.New("failed to create task")
16+
ErrCommunication = errors.New("communication with supernode failed")
17+
)
18+
19+
// SupernodeError represents an error related to supernode operations
20+
type SupernodeError struct {
21+
NodeID string
22+
Message string
23+
Err error
24+
}
25+
26+
// Error returns the error message
27+
func (e *SupernodeError) Error() string {
28+
return fmt.Sprintf("supernode error (ID: %s): %s: %v", e.NodeID, e.Message, e.Err)
29+
}
30+
31+
// Unwrap returns the underlying error
32+
func (e *SupernodeError) Unwrap() error {
33+
return e.Err
34+
}
35+
36+
// ActionError represents an error related to action operations
37+
type ActionError struct {
38+
ActionID string
39+
Message string
40+
Err error
41+
}
42+
43+
// Error returns the error message
44+
func (e *ActionError) Error() string {
45+
return fmt.Sprintf("action error (ID: %s): %s: %v", e.ActionID, e.Message, e.Err)
46+
}
47+
48+
// Unwrap returns the underlying error
49+
func (e *ActionError) Unwrap() error {
50+
return e.Err
51+
}

sdk/action/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package action
2+
3+
type TaskType string
4+
5+
const (
6+
TaskTypeSense TaskType = "SENSE"
7+
TaskTypeCascade TaskType = "CASCADE"
8+
)

0 commit comments

Comments
 (0)