Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed sdk/action/.gitkeep
Empty file.
144 changes: 144 additions & 0 deletions sdk/action/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package action

import (
"context"
"fmt"

"action/config"
"action/event"
"action/log"
"action/task"

"github.com/cosmos/cosmos-sdk/crypto/keyring"
)

// Client defines the interface for action operations
type Client interface {
StartCascade(ctx context.Context, fileHash string, actionID string, filePath string, signedData string) (string, error)
DeleteTask(ctx context.Context, taskID string) error
GetTask(ctx context.Context, taskID string) (*task.TaskEntry, bool)
SubscribeToEvents(ctx context.Context, eventType event.EventType, handler event.Handler)
SubscribeToAllEvents(ctx context.Context, handler event.Handler)
}

// ClientImpl implements the Client interface
type ClientImpl struct {
config config.Config
taskManager task.Manager
logger log.Logger
keyring keyring.Keyring
}

// Verify interface compliance at compile time
var _ Client = (*ClientImpl)(nil)

// NewClient creates a new action client
func NewClient(
ctx context.Context,
config config.Config,
logger log.Logger,
keyring keyring.Keyring,
) (Client, error) {
if logger == nil {
logger = log.NewNoopLogger()
}

taskManager, err := task.NewManager(ctx, config, logger, keyring)
if err != nil {
return nil, fmt.Errorf("failed to create task manager: %w", err)
}

return &ClientImpl{
config: config,
taskManager: taskManager,
logger: logger,
keyring: keyring,
}, nil
}

// StartCascade initiates a cascade operation
func (c *ClientImpl) StartCascade(
ctx context.Context,
fileHash string, // Hash of the file to process
actionID string, // ID of the action to perform
filePath string, // Path to the file on disk
signedData string, // Optional signed authorization data
) (string, error) {
c.logger.Debug(ctx, "Starting cascade operation",
"fileHash", fileHash,
"actionID", actionID,
"filePath", filePath,
)

if fileHash == "" {
c.logger.Error(ctx, "Empty file hash provided")
return "", ErrEmptyFileHash
}
if actionID == "" {
c.logger.Error(ctx, "Empty action ID provided")
return "", ErrEmptyActionID
}
if filePath == "" {
c.logger.Error(ctx, "Empty file path provided")
return "", ErrEmptyFilePath
}

taskID, err := c.taskManager.CreateCascadeTask(ctx, fileHash, actionID, filePath, signedData)
if err != nil {
c.logger.Error(ctx, "Failed to create cascade task", "error", err)
return "", fmt.Errorf("failed to create cascade task: %w", err)
}

c.logger.Info(ctx, "Cascade task created successfully", "taskID", taskID)
return taskID, nil
}

// GetTask retrieves a task by its ID
func (c *ClientImpl) GetTask(ctx context.Context, taskID string) (*task.TaskEntry, bool) {
c.logger.Debug(ctx, "Getting task", "taskID", taskID)
task, found := c.taskManager.GetTask(ctx, taskID)
if !found {
c.logger.Debug(ctx, "Task not found", "taskID", taskID)
} else {
c.logger.Debug(ctx, "Task found", "taskID", taskID, "status", task.Status)
}
return task, found
}

// DeleteTask removes a task by its ID
func (c *ClientImpl) DeleteTask(ctx context.Context, taskID string) error {
c.logger.Debug(ctx, "Deleting task", "taskID", taskID)
if taskID == "" {
c.logger.Error(ctx, "Empty task ID provided")
return fmt.Errorf("task ID cannot be empty")
}

err := c.taskManager.DeleteTask(ctx, taskID)
if err != nil {
c.logger.Error(ctx, "Failed to delete task", "taskID", taskID, "error", err)
return fmt.Errorf("failed to delete task: %w", err)
}

c.logger.Info(ctx, "Task deleted successfully", "taskID", taskID)
return nil
}

// SubscribeToEvents registers a handler for specific event types
func (c *ClientImpl) SubscribeToEvents(ctx context.Context, eventType event.EventType, handler event.Handler) {
c.logger.Debug(ctx, "Subscribing to events via task manager", "eventType", eventType)
if c.taskManager != nil {
c.taskManager.SubscribeToEvents(ctx, eventType, handler)
} else {
c.logger.Warn(ctx, "TaskManager is nil, cannot subscribe to events")
}
}

// SubscribeToAllEvents registers a handler for all events
func (c *ClientImpl) SubscribeToAllEvents(ctx context.Context, handler event.Handler) {
c.logger.Debug(ctx, "Subscribing to all events via task manager")
if c.taskManager != nil {
c.taskManager.SubscribeToAllEvents(ctx, handler)
} else {
c.logger.Warn(ctx, "TaskManager is nil, cannot subscribe to all events")
}
}
40 changes: 0 additions & 40 deletions sdk/action/client/check_health.go

This file was deleted.

35 changes: 0 additions & 35 deletions sdk/action/client/client.go

This file was deleted.

28 changes: 0 additions & 28 deletions sdk/action/client/options.go

This file was deleted.

51 changes: 51 additions & 0 deletions sdk/action/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package action

import (
"errors"
"fmt"
)

var (
ErrEmptyFileHash = errors.New("file hash cannot be empty")
ErrEmptyActionID = errors.New("action ID cannot be empty")
ErrEmptyFilePath = errors.New("file path cannot be empty")
ErrNoValidAction = errors.New("no action found with the specified ID")
ErrInvalidAction = errors.New("action is not in a valid state")
ErrNoSupernodes = errors.New("no valid supernodes available")
ErrTaskCreation = errors.New("failed to create task")
ErrCommunication = errors.New("communication with supernode failed")
)

// SupernodeError represents an error related to supernode operations
type SupernodeError struct {
NodeID string
Message string
Err error
}

// Error returns the error message
func (e *SupernodeError) Error() string {
return fmt.Sprintf("supernode error (ID: %s): %s: %v", e.NodeID, e.Message, e.Err)
}

// Unwrap returns the underlying error
func (e *SupernodeError) Unwrap() error {
return e.Err
}

// ActionError represents an error related to action operations
type ActionError struct {
ActionID string
Message string
Err error
}

// Error returns the error message
func (e *ActionError) Error() string {
return fmt.Sprintf("action error (ID: %s): %s: %v", e.ActionID, e.Message, e.Err)
}

// Unwrap returns the underlying error
func (e *ActionError) Unwrap() error {
return e.Err
}
8 changes: 8 additions & 0 deletions sdk/action/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package action

type TaskType string

const (
TaskTypeSense TaskType = "SENSE"
TaskTypeCascade TaskType = "CASCADE"
)
Loading