domain

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2025 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EventTypeParticipantCreated EventType = "participant.created"
	EventTypeParticipantUpdated EventType = "participant.updated"
	EventTypeParticipantDeleted EventType = "participant.deleted"

	ParticipantEnabled  ParticipantStatus = "Enabled"
	ParticipantDisabled ParticipantStatus = "Disabled"
)
View Source
const (
	EventTypeServiceCreated      EventType = "service.created"
	EventTypeServiceUpdated      EventType = "service.updated"
	EventTypeServiceTransitioned EventType = "service.transitioned"
	EventTypeServiceRetried      EventType = "service.retried"

	ServiceCreating     ServiceStatus = "Creating"
	ServiceCreated      ServiceStatus = "Created"
	ServiceStarting     ServiceStatus = "Starting"
	ServiceStarted      ServiceStatus = "Started"
	ServiceStopping     ServiceStatus = "Stopping"
	ServiceStopped      ServiceStatus = "Stopped"
	ServiceHotUpdating  ServiceStatus = "HotUpdating"
	ServiceColdUpdating ServiceStatus = "ColdUpdating"
	ServiceDeleting     ServiceStatus = "Deleting"
	ServiceDeleted      ServiceStatus = "Deleted"
)

Variables

This section is empty.

Functions

func HashTokenValue

func HashTokenValue(value string) string

HashTokenValue creates a secure hash of a token value

func NewAgentCommander

func NewAgentCommander(
	store Store,
) *agentCommander

NewAgentCommander creates a new default AgentCommander

func NewJobCommander

func NewJobCommander(
	store Store,
) *jobCommander

NewJobCommander creates a new command executor

func NewMetricEntryCommander

func NewMetricEntryCommander(
	store Store,
) *metricEntryCommander

NewMetricEntryCommander creates a new MetricEntryCommander

func NewMetricTypeCommander

func NewMetricTypeCommander(
	store Store,
) *metricTypeCommander

NewMetricTypeCommander creates a new MetricTypeService

func NewServiceCommander

func NewServiceCommander(
	store Store,
) *serviceCommander

NewServiceCommander creates a new commander for services

func NewServiceGroupCommander

func NewServiceGroupCommander(
	store Store,
) *serviceGroupCommander

NewServiceGroupCommander creates a new ServiceGroupService

Types

type Agent

type Agent struct {
	BaseEntity

	Name string `json:"name" gorm:"not null"`

	// Status management
	Status           AgentStatus `json:"status" gorm:"not null"`
	LastStatusUpdate time.Time   `json:"lastStatusUpdate" gorm:"index"`

	// Tags representing capabilities or certifications of this agent
	Tags pq.StringArray `json:"tags" gorm:"type:text[]"`

	// Relationships
	AgentTypeID properties.UUID `json:"agentTypeId" gorm:"not null"`
	AgentType   *AgentType      `json:"agentType,omitempty" gorm:"foreignKey:AgentTypeID"`
	ProviderID  properties.UUID `json:"providerId" gorm:"not null"`
	Provider    *Participant    `json:"-" gorm:"foreignKey:ProviderID"`
}

Agent represents a service manager agent

func NewAgent

func NewAgent(name string, providerID properties.UUID, agentTypeID properties.UUID, tags []string) *Agent

NewAgent creates a new agent with proper validation

func (*Agent) RegisterMetadata

func (a *Agent) RegisterMetadata(name *string)

RegisterMetadata updates the agent's metadata properties (name)

func (Agent) TableName

func (Agent) TableName() string

TableName returns the table name for the agent

func (*Agent) Update

func (a *Agent) Update(name *string, tags *[]string) bool

Update updates the agent's fields

func (*Agent) UpdateHeartbeat

func (a *Agent) UpdateHeartbeat()

UpdateHeartbeat updates the last status update timestamp without changing the status

func (*Agent) UpdateStatus

func (a *Agent) UpdateStatus(newStatus AgentStatus)

UpdateStatus updates the agent's status and last update timestamp

func (*Agent) Validate

func (a *Agent) Validate() error

Validate ensures all agent fields are valid

type AgentCommander

type AgentCommander interface {
	// Create creates a new agent
	Create(ctx context.Context, name string, providerID properties.UUID, agentTypeID properties.UUID, tags []string) (*Agent, error)

	// Update updates an agent
	Update(ctx context.Context, id properties.UUID, name *string, status *AgentStatus, tags *[]string) (*Agent, error)

	// Delete removes an agent by ID after checking for dependencies
	Delete(ctx context.Context, id properties.UUID) error

	// UpdateStatus updates the agent status and the related timestamp
	UpdateStatus(ctx context.Context, id properties.UUID, status AgentStatus) (*Agent, error)
}

AgentCommander defines the interface for agent command operations

type AgentQuerier

type AgentQuerier interface {
	BaseEntityQuerier[Agent]

	// CountByProvider returns the number of agents for a specific provider
	CountByProvider(ctx context.Context, providerID properties.UUID) (int64, error)

	// FindByServiceTypeAndTags finds agents that support a service type and have all required tags
	FindByServiceTypeAndTags(ctx context.Context, serviceTypeID properties.UUID, tags []string) ([]*Agent, error)
}

type AgentRepository

type AgentRepository interface {
	AgentQuerier
	BaseEntityRepository[Agent]

	// MarkInactiveAgentsAsDisconnected marks agents that haven't updated their status in the given duration as disconnected
	MarkInactiveAgentsAsDisconnected(ctx context.Context, inactiveDuration time.Duration) (int64, error)
}

type AgentStatus

type AgentStatus string

AgentStatus represents the possible statuss of an Agent

const (
	AgentNew          AgentStatus = "New"
	AgentConnected    AgentStatus = "Connected"
	AgentDisconnected AgentStatus = "Disconnected"
	AgentError        AgentStatus = "Error"
	AgentDisabled     AgentStatus = "Disabled"
)

func ParseAgentStatus

func ParseAgentStatus(value string) (AgentStatus, error)

func (AgentStatus) Validate

func (s AgentStatus) Validate() error

Validate checks if the agent status is valid

type AgentType

type AgentType struct {
	BaseEntity
	Name         string        `json:"name" gorm:"not null;unique"`
	ServiceTypes []ServiceType `json:"-" gorm:"many2many:agent_type_service_types;"`
}

AgentType represents a type of service manager agent

func (AgentType) TableName

func (AgentType) TableName() string

TableName returns the table name for the agent type

type AgentTypeQuerier

type AgentTypeQuerier interface {
	BaseEntityQuerier[AgentType]
}

AgentTypeQuerier defines the interface for the AgentType read-only queries

type AgentTypeRepository

type AgentTypeRepository interface {
	AgentTypeQuerier
	BaseEntityRepository[AgentType]
}

AgentTypeRepository defines the interface for the AgentType repository

type AggregateType

type AggregateType string

AggregateType defines the type of aggregation to perform on metric entries

const (
	// AggregateMax returns the maximum value
	AggregateMax AggregateType = "max"
	// AggregateSum returns the sum of values
	AggregateSum AggregateType = "sum"
	// AggregateDiffMaxMin returns the difference between maximum and minimum values (for always increasing metrics)
	AggregateDiffMaxMin AggregateType = "diff"
	// AggregateAvg returns the average value
	AggregateAvg AggregateType = "avg"
)

type BaseEntity

type BaseEntity struct {
	ID        properties.UUID `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	CreatedAt time.Time       `json:"-" gorm:"not null;default:CURRENT_TIMESTAMP"`
	UpdatedAt time.Time       `json:"-" gorm:"not null;default:CURRENT_TIMESTAMP"`
}

BaseEntity provides common fields for all entities

func (BaseEntity) GetID

func (b BaseEntity) GetID() properties.UUID

GetID returns the entity's ID

type BaseEntityQuerier

type BaseEntityQuerier[T Entity] interface {

	// Get retrieves an entity by ID
	Get(ctx context.Context, id properties.UUID) (*T, error)

	// Exists checks if an entity with the given ID exists
	Exists(ctx context.Context, id properties.UUID) (bool, error)

	// List retrieves a list of entities based on the provided filters
	List(ctx context.Context, scope *auth.IdentityScope, req *PageReq) (*PageRes[T], error)

	// Count returns the number of entities
	Count(ctx context.Context) (int64, error)

	// AuthScope returns the authorization scope for the entity
	AuthScope(ctx context.Context, id properties.UUID) (auth.ObjectScope, error)
}

BaseEntityQuerier defines the interface for the BaseEntity read-only queries

type BaseEntityRepository

type BaseEntityRepository[T Entity] interface {
	BaseEntityQuerier[T]

	// Create creates a new entity
	Create(ctx context.Context, entity *T) error

	// Save updates an existing entity
	Save(ctx context.Context, entity *T) error

	// Delete removes an entity by ID
	Delete(ctx context.Context, id properties.UUID) error
}

BaseEntityRepository defines the interface for the BaseEntity repository

type Entity

type Entity interface {
	GetID() properties.UUID
}

Entity defines the interface that all domain entities must implement

type Event

type Event struct {
	BaseEntity

	// For strict ordering of events
	SequenceNumber int64 `json:"sequenceNumber" gorm:"autoIncrement;uniqueIndex;not null"`

	InitiatorType InitiatorType `gorm:"not null"`
	InitiatorID   string        `gorm:"not null"`

	Type    EventType       `gorm:"not null"`
	Payload properties.JSON `gorm:"type:jsonb"`

	// Target entity ID for the event
	EntityID *properties.UUID `gorm:"index"`

	// Optional IDs for related entities and filtering
	ParticipantID *properties.UUID `gorm:"type:uuid"`
	ProviderID    *properties.UUID `gorm:"type:uuid"`
	AgentID       *properties.UUID `gorm:"type:uuid"`
	ConsumerID    *properties.UUID `gorm:"type:uuid"`
}

Event represents an event in the system

func NewEvent

func NewEvent(
	eventType EventType,
	opts ...EventOption,
) (*Event, error)

NewEvent creates a new event

func (Event) TableName

func (Event) TableName() string

TableName returns the table name for the event

func (*Event) Validate

func (p *Event) Validate() error

Validate ensures all Event fields are valid

type EventOption

type EventOption func(*Event) error

EventOption defines a function that configures an EventEntry

func WithAgent

func WithAgent(t *Agent) EventOption

WithAgent sets the entity ID for the event

func WithDiff

func WithDiff(beforeEntity, afterEntity any) EventOption

WithDiff

func WithInitiatorCtx

func WithInitiatorCtx(ctx context.Context) EventOption

WithInitiatorCtx sets the event from a context

func WithJob

func WithJob(t *Job) EventOption

WithJob sets the entity ID for the event

func WithMetricType

func WithMetricType(t *MetricType) EventOption

WithMetricType sets the entity ID for the event

func WithParticipant

func WithParticipant(t *Participant) EventOption

WithParticipant sets the entity ID for the event

func WithService

func WithService(t *Service) EventOption

WithService sets the entity ID for the event

func WithServiceGroup

func WithServiceGroup(t *ServiceGroup) EventOption

WithServiceGroup sets the entity ID for the event

func WithToken

func WithToken(t *Token) EventOption

WithToken sets the entity ID for the event

type EventQuerier

type EventQuerier interface {
	BaseEntityQuerier[Event]

	// ListFromSequence retrieves events starting from a specific sequence number
	ListFromSequence(ctx context.Context, fromSequenceNumber int64, limit int) ([]*Event, error)

	// ServiceUptime returns the uptime and downtime in seconds of a service in a time range
	ServiceUptime(ctx context.Context, serviceID properties.UUID, start time.Time, end time.Time) (uptimeSeconds uint64, downtimeSeconds uint64, err error)
}

type EventRepository

type EventRepository interface {
	BaseEntityRepository[Event]
	EventQuerier

	// Create stores a new event
	Create(ctx context.Context, entry *Event) error
}

type EventSubscription

type EventSubscription struct {
	BaseEntity

	SubscriberID               string     `json:"subscriber_id" gorm:"not null;uniqueIndex"`
	LastEventSequenceProcessed int64      `json:"last_event_sequence_processed" gorm:"not null;default:0"`
	LeaseOwnerInstanceID       *string    `json:"lease_owner_instance_id,omitempty" gorm:"index"`
	LeaseAcquiredAt            *time.Time `json:"lease_acquired_at,omitempty"`
	LeaseExpiresAt             *time.Time `json:"lease_expires_at,omitempty" gorm:"index"`
	IsActive                   bool       `json:"is_active" gorm:"not null;default:true"`
}

EventSubscription represents a subscription for external systems to consume events

func NewEventSubscription

func NewEventSubscription(subscriberID string) *EventSubscription

NewEventSubscription creates a new EventSubscription without validation

func (*EventSubscription) AcquireLease

func (es *EventSubscription) AcquireLease(instanceID string, duration time.Duration)

AcquireLease sets the lease fields for the subscription

func (*EventSubscription) HasActiveLease

func (es *EventSubscription) HasActiveLease() bool

HasActiveLease checks if the subscription has an active (non-expired) lease

func (*EventSubscription) IsLeaseExpired

func (es *EventSubscription) IsLeaseExpired() bool

IsLeaseExpired checks if the current lease has expired

func (*EventSubscription) ReleaseLease

func (es *EventSubscription) ReleaseLease()

ReleaseLease clears the lease fields for the subscription

func (EventSubscription) TableName

func (EventSubscription) TableName() string

TableName returns the table name for the event subscription

func (*EventSubscription) Update

func (es *EventSubscription) Update(
	lastEventSequenceProcessed *int64,
	leaseOwnerInstanceID *string,
	leaseAcquiredAt *time.Time,
	leaseExpiresAt *time.Time,
	isActive *bool,
)

Update updates the event subscription fields if the pointers are non-nil

func (*EventSubscription) Validate

func (es *EventSubscription) Validate() error

Validate ensures all EventSubscription fields are valid

type EventSubscriptionCommander

type EventSubscriptionCommander interface {
	// UpdateProgress updates the last event sequence processed
	UpdateProgress(ctx context.Context, subscriberID string, lastEventSequenceProcessed int64) (*EventSubscription, error)

	// AcquireLease attempts to acquire a lease for processing events
	AcquireLease(ctx context.Context, subscriberID string, instanceID string, duration time.Duration) (*EventSubscription, error)

	// RenewLease renews an existing lease
	RenewLease(ctx context.Context, subscriberID string, instanceID string, duration time.Duration) (*EventSubscription, error)

	// ReleaseLease releases the lease for the subscription
	ReleaseLease(ctx context.Context, subscriberID string, instanceID string) (*EventSubscription, error)

	// AcknowledgeEvents acknowledges processed events by updating progress, but only if the instance holds a valid lease
	AcknowledgeEvents(ctx context.Context, subscriberID string, instanceID string, lastEventSequenceProcessed int64) (*EventSubscription, error)

	// SetActive sets the active status of the subscription
	SetActive(ctx context.Context, subscriberID string, isActive bool) (*EventSubscription, error)

	// Delete removes an event subscription
	Delete(ctx context.Context, subscriberID string) error
}

EventSubscriptionCommander defines the interface for event subscription command operations

func NewEventSubscriptionCommander

func NewEventSubscriptionCommander(store Store) EventSubscriptionCommander

NewEventSubscriptionCommander creates a new default EventSubscriptionCommander

type EventSubscriptionQuerier

type EventSubscriptionQuerier interface {
	BaseEntityRepository[EventSubscription]

	// FindBySubscriberID retrieves an entity by subscriber ID
	FindBySubscriberID(ctx context.Context, subscriberID string) (*EventSubscription, error)

	// ExistsBySubscriberID checks if an entity with the given subscriber ID exists
	ExistsBySubscriberID(ctx context.Context, subscriberID string) (bool, error)

	// ListExpiredLeases retrieves subscriptions with expired leases
	ListExpiredLeases(ctx context.Context) ([]*EventSubscription, error)
}

EventSubscriptionQuerier defines the interface for event subscription query operations

type EventSubscriptionRepository

type EventSubscriptionRepository interface {
	EventSubscriptionQuerier
	BaseEntityRepository[EventSubscription]

	// DeleteBySubscriberID removes an entity by subscriber ID
	DeleteBySubscriberID(ctx context.Context, subscriberID string) error
}

EventSubscriptionRepository defines the interface for event subscription data operations

type EventType

type EventType string

EventType defines the type of event

const (
	EventTypeAgentCreated EventType = "agent.created"
	EventTypeAgentUpdated EventType = "agent.updated"
	EventTypeAgentDeleted EventType = "agent.deleted"
)
const (
	EventTypeMetricTypeUpdated EventType = "metric_type.updated"
	EventTypeMetricTypeCreated EventType = "metric_type.created"
	EventTypeMetricTypeDeleted EventType = "metric_type.deleted"
)
const (
	EventTypeServiceGroupCreated EventType = "service_group.created"
	EventTypeServiceGroupUpdated EventType = "service_group.updated"
	EventTypeServiceGroupDeleted EventType = "service_group.deleted"
)
const (
	EventTypeTokenCreated     EventType = "token.created"
	EventTypeTokenUpdated     EventType = "token.updated"
	EventTypeTokenDeleted     EventType = "token.deleted"
	EventTypeTokenRegenerated EventType = "token.regenerate"
)

type InitiatorType

type InitiatorType string

InitiatorType defines the type of actor that initiated the event

const (
	InitiatorTypeSystem InitiatorType = "system"
	InitiatorTypeUser   InitiatorType = "user"
)

Predefined initiator types

type InvalidInputError

type InvalidInputError struct {
	Err error
}

func NewInvalidInputErrorf

func NewInvalidInputErrorf(format string, a ...any) InvalidInputError

func (InvalidInputError) Error

func (e InvalidInputError) Error() string

func (InvalidInputError) Unwrap

func (e InvalidInputError) Unwrap() error

type Job

type Job struct {
	BaseEntity

	Action   ServiceAction `gorm:"type:varchar(50);not null"`
	Priority int           `gorm:"not null;default:1"`

	// Status management
	Status       JobStatus  `gorm:"type:varchar(20);not null"`
	ErrorMessage string     `gorm:"type:text"`
	ClaimedAt    *time.Time `gorm:""`
	CompletedAt  *time.Time `gorm:""`

	// Relationships
	AgentID    properties.UUID `gorm:"not null"`
	Agent      *Agent          `gorm:"foreignKey:AgentID"`
	ServiceID  properties.UUID `gorm:"not null"`
	Service    *Service        `gorm:"foreignKey:ServiceID"`
	ProviderID properties.UUID `gorm:"not null"`
	Provider   *Participant    `gorm:"foreignKey:ProviderID"`
	ConsumerID properties.UUID `gorm:"not null"`
	Consumer   *Participant    `gorm:"foreignKey:ConsumerID"`
}

Job represents a task to be executed by an agent

func NewJob

func NewJob(svc *Service, action ServiceAction, priority int) *Job

NewJob creates a new job instance with the provided parameters

func (*Job) Claim

func (j *Job) Claim() error

Claim marks a job as claimed by an agent

func (*Job) Complete

func (j *Job) Complete() error

Complete marks a job as successfully completed

func (*Job) Fail

func (j *Job) Fail(errorMessage string) error

Fail records job failure with error details

func (*Job) Retry

func (j *Job) Retry() error

Retry increments retry count and updates status

func (Job) TableName

func (Job) TableName() string

TableName returns the table name for the job

func (*Job) Validate

func (j *Job) Validate() error

Validate ensures all Job fields are valid

type JobCommander

type JobCommander interface {
	// Claim claims a job for an agent
	Claim(ctx context.Context, jobID properties.UUID) error

	// Complete marks a job as completed
	Complete(ctx context.Context, jobID properties.UUID, resources *properties.JSON, externalID *string) error

	// Fail marks a job as failed
	Fail(ctx context.Context, jobID properties.UUID, errorMessage string) error
}

JobCommander defines the interface for job command operations

type JobQuerier

type JobQuerier interface {
	BaseEntityQuerier[Job]

	// GetPendingJobsForAgent retrieves pending jobs targeted for a specific agent
	GetPendingJobsForAgent(ctx context.Context, agentID properties.UUID, limit int) ([]*Job, error)

	// GetTimeOutJobs retrieves jobs that have been processing for too long and returns them
	GetTimeOutJobs(ctx context.Context, olderThan time.Duration) ([]*Job, error)
}

type JobRepository

type JobRepository interface {
	JobQuerier
	BaseEntityRepository[Job]

	// DeleteOldCompletedJobs removes completed or failed jobs older than the specified interval
	DeleteOldCompletedJobs(ctx context.Context, olderThan time.Duration) (int, error)
}

type JobStatus

type JobStatus string

JobStatus represents the current status of a job

const (
	JobPending    JobStatus = "Pending"
	JobProcessing JobStatus = "Processing"
	JobCompleted  JobStatus = "Completed"
	JobFailed     JobStatus = "Failed"
)

func ParseJobStatus

func ParseJobStatus(s string) (JobStatus, error)

ParseJobStatus parses a string into a JobStatus

func (JobStatus) Validate

func (s JobStatus) Validate() error

Validate checks if the service status is valid

type MetricEntityType

type MetricEntityType string

MetricEntityType represents the possible types of entities that can be measured

const (
	MetricEntityTypeAgent    MetricEntityType = "Agent"
	MetricEntityTypeService  MetricEntityType = "Service"
	MetricEntityTypeResource MetricEntityType = "Resource"
)

func (MetricEntityType) Validate

func (t MetricEntityType) Validate() error

Validate ensures the MetricEntityType is one of the allowed values

type MetricEntry

type MetricEntry struct {
	// Base entity fields
	ID        properties.UUID `json:"id" gorm:"type:uuid;primary_key"`
	CreatedAt time.Time       `json:"-" gorm:"not null;default:CURRENT_TIMESTAMP;index:idx_metric_aggregate,priority:3"`
	UpdatedAt time.Time       `json:"-" gorm:"not null;default:CURRENT_TIMESTAMP"`

	ResourceID string  `gorm:"not null"`
	Value      float64 `gorm:"not null"`

	// Relationships
	TypeID     properties.UUID `gorm:"not null;index:idx_metric_aggregate,priority:2"`
	Type       *MetricType     `gorm:"foreignKey:TypeID"`
	AgentID    properties.UUID `gorm:"not null"`
	Agent      *Agent          `gorm:"foreignKey:AgentID"`
	ServiceID  properties.UUID `gorm:"not null;index:idx_metric_aggregate,priority:1"`
	Service    *Service        `gorm:"foreignKey:ServiceID"`
	ProviderID properties.UUID `gorm:"not null"`
	Provider   *Participant    `gorm:"foreignKey:ProviderID"`
	ConsumerID properties.UUID `gorm:"not null"`
	Consumer   *Participant    `gorm:"foreignKey:ConsumerID"`
}

MetricEntry represents a metric measurement for a specific resource Does not extend BaseEntity because it has a custom index on created_at

func NewMetricEntry

func NewMetricEntry(
	consumerID properties.UUID,
	providerID properties.UUID,
	agentID properties.UUID,
	serviceID properties.UUID,
	resourceID string,
	typeID properties.UUID,
	value float64,
) *MetricEntry

NewMetricEntry creates a new metric entry

func (*MetricEntry) BeforeCreate

func (m *MetricEntry) BeforeCreate(tx *gorm.DB) error

BeforeCreate ensures properties.UUID is set before creating a record

func (MetricEntry) GetID

func (m MetricEntry) GetID() properties.UUID

GetID returns the entity's ID (implements Entity interface)

func (MetricEntry) TableName

func (MetricEntry) TableName() string

TableName returns the table name for the metric entry

func (*MetricEntry) Validate

func (p *MetricEntry) Validate() error

Validate ensures all MetricEntry fields are valid

type MetricEntryCommander

type MetricEntryCommander interface {
	// Create creates a new metric entry
	Create(ctx context.Context, typeName string, agentID properties.UUID, serviceID properties.UUID, resourceID string, value float64) (*MetricEntry, error)

	// CreateWithExternalID creates a new metric entry using service's external ID
	CreateWithExternalID(ctx context.Context, typeName string, agentID properties.UUID, externalID string, resourceID string, value float64) (*MetricEntry, error)
}

MetricEntryCommander defines the interface for metric entry command operations

type MetricEntryQuerier

type MetricEntryQuerier interface {
	BaseEntityQuerier[MetricEntry]

	// CountByMetricType counts the number of entries for a specific metric type
	CountByMetricType(ctx context.Context, typeID properties.UUID) (int64, error)

	// Aggregate performs aggregation operations on metric entries for a specific metric type and service within a time range
	Aggregate(ctx context.Context, aggregateType AggregateType, serviceID properties.UUID, typeID properties.UUID, start time.Time, end time.Time) (float64, error)
}

type MetricEntryRepository

type MetricEntryRepository interface {
	MetricEntryQuerier
	BaseEntityRepository[MetricEntry]
}

type MetricType

type MetricType struct {
	BaseEntity
	Name       string           `json:"name" gorm:"not null;unique"`
	EntityType MetricEntityType `json:"entityType" gorm:"not null"`
}

MetricType represents a type of metric that can be collected

func NewMetricType

func NewMetricType(name string, entityType MetricEntityType) *MetricType

NewMetricType creates a new metric type without validation

func (MetricType) TableName

func (MetricType) TableName() string

TableName returns the table name for the metric type

func (*MetricType) Update

func (m *MetricType) Update(name *string)

Update updates the metric type

func (*MetricType) Validate

func (m *MetricType) Validate() error

Validate ensures all MetricType fields are valid

type MetricTypeCommander

type MetricTypeCommander interface {
	// Create creates a new metric-type
	Create(ctx context.Context, name string, kind MetricEntityType) (*MetricType, error)

	// Update updates a metric-type
	Update(ctx context.Context, id properties.UUID, name *string) (*MetricType, error)

	// Delete removes a metric-type by ID after checking for dependencies
	Delete(ctx context.Context, id properties.UUID) error
}

MetricTypeCommander defines the interface for metric type command operations

type MetricTypeQuerier

type MetricTypeQuerier interface {
	BaseEntityQuerier[MetricType]

	// FindByName retrieves a metric type by name
	FindByName(ctx context.Context, name string) (*MetricType, error)
}

type MetricTypeRepository

type MetricTypeRepository interface {
	MetricTypeQuerier
	BaseEntityRepository[MetricType]
}

type NotFoundError

type NotFoundError struct {
	Err error
}

func NewNotFoundErrorf

func NewNotFoundErrorf(format string, a ...any) NotFoundError

func (NotFoundError) Error

func (e NotFoundError) Error() string

func (NotFoundError) Unwrap

func (e NotFoundError) Unwrap() error

type PageReq

type PageReq struct {
	Filters  map[string][]string // Filters to be applied
	Sort     bool                // Should sort
	SortBy   string              // Field to sort by
	SortAsc  bool                // Sort dir
	Page     int                 // Current page number
	PageSize int                 // Number of items per page
}

type PageRes

type PageRes[T any] struct {
	Items       []T
	TotalItems  int64
	TotalPages  int
	CurrentPage int
	HasNext     bool
	HasPrev     bool
}

func NewPaginatedResult

func NewPaginatedResult[T any](items []T, totalItems int64, page *PageReq) *PageRes[T]

NewPaginatedResult creates a new PaginatedResult with calculated pagination fields

type Participant

type Participant struct {
	BaseEntity

	Name   string            `json:"name" gorm:"not null"`
	Status ParticipantStatus `json:"status" gorm:"not null"`

	// Relationships
	Agents []Agent `json:"agents,omitempty" gorm:"foreignKey:ProviderID"` // Agent struct will be updated later
}

Participant represents a unified entity for providers and consumers

func NewParticipant

func NewParticipant(name string, status ParticipantStatus) *Participant

NewParticipant creates a new Participant without validation

func (Participant) TableName

func (Participant) TableName() string

TableName returns the table name for the participant

func (*Participant) Update

func (p *Participant) Update(name *string, status *ParticipantStatus)

Update updates the participant fields if the pointers are non-nil

func (*Participant) Validate

func (p *Participant) Validate() error

Validate ensures all Participant fields are valid

type ParticipantCommander

type ParticipantCommander interface {
	// Create creates a new participant
	Create(ctx context.Context, name string, status ParticipantStatus) (*Participant, error)

	// Update updates a participant
	Update(ctx context.Context, id properties.UUID, name *string, status *ParticipantStatus) (*Participant, error)

	// Delete removes a participant by ID after checking for dependencies
	Delete(ctx context.Context, id properties.UUID) error
}

ParticipantCommander defines the interface for participant command operations

func NewParticipantCommander

func NewParticipantCommander(
	store Store,
) ParticipantCommander

NewParticipantCommander creates a new default ParticipantCommander

type ParticipantQuerier

type ParticipantQuerier interface {
	BaseEntityQuerier[Participant]
}

ParticipantQuerier defines the interface for participant query operations

type ParticipantRepository

type ParticipantRepository interface {
	ParticipantQuerier
	BaseEntityRepository[Participant]
}

ParticipantRepository defines the interface for participant data operations

type ParticipantStatus

type ParticipantStatus string

ParticipantStatus represents the possible statuss of a Participant

func ParseParticipantStatus

func ParseParticipantStatus(value string) (ParticipantStatus, error)

ParseParticipantStatus parses a string into a ParticipantStatus

func (ParticipantStatus) Validate

func (s ParticipantStatus) Validate() error

Validate checks if the participant status is valid

type Service

type Service struct {
	BaseEntity

	Name string `json:"name" gorm:"not null"`

	// Status management
	CurrentStatus     ServiceStatus    `json:"currentStatus" gorm:"not null"`
	TargetStatus      *ServiceStatus   `json:"targetStatus,omitempty"`
	ErrorMessage      *string          `json:"errorMessage,omitempty"`
	FailedAction      *ServiceAction   `json:"failedAction,omitempty"`
	RetryCount        int              `json:"retryCount"`
	CurrentProperties *properties.JSON `json:"currentProperties,omitempty" gorm:"type:jsonb"`
	TargetProperties  *properties.JSON `json:"targetProperties,omitempty" gorm:"type:jsonb"`

	// To store an external ID for the agent's use to facilitate metric reporting
	ExternalID *string `json:"externalId,omitempty" gorm:"uniqueIndex:service_external_id_uniq"`
	// Safe place for the Agent for store data
	Resources *properties.JSON `json:"resources,omitempty" gorm:"type:jsonb"`

	// Relationships
	ProviderID    properties.UUID `json:"providerId" gorm:"not null"`
	Provider      *Participant    `json:"-" gorm:"foreignKey:ProviderID"`
	ConsumerID    properties.UUID `json:"consumerId" gorm:"not null"`
	Consumer      *Participant    `json:"-" gorm:"foreignKey:ConsumerID"`
	GroupID       properties.UUID `gorm:"not null" json:"groupId"`
	Group         *ServiceGroup   `json:"-" gorm:"foreignKey:GroupID"`
	AgentID       properties.UUID `json:"agentId" gorm:"not null"`
	Agent         *Agent          `json:"-" gorm:"foreignKey:AgentID"`
	ServiceTypeID properties.UUID `json:"serviceTypeId" gorm:"not null"`
	ServiceType   *ServiceType    `json:"-" gorm:"foreignKey:ServiceTypeID"`
}

Service represents a service instance managed by an agent

func CreateServiceWithAgent

func CreateServiceWithAgent(
	ctx context.Context,
	store Store,
	agent *Agent,
	serviceTypeID properties.UUID,
	groupID properties.UUID,
	name string,
	properties properties.JSON,
) (*Service, error)

func CreateServiceWithTags

func CreateServiceWithTags(
	ctx context.Context,
	store Store,
	serviceTypeID properties.UUID,
	groupID properties.UUID,
	name string,
	properties properties.JSON,
	serviceTags []string,
) (*Service, error)

func NewService

func NewService(
	consumerID properties.UUID,
	groupID properties.UUID,
	providerID properties.UUID,
	agentID properties.UUID,
	serviceTypeID properties.UUID,
	name string,
	properties *properties.JSON,
) *Service

NewService creates a new Service without validation

func RetryService

func RetryService(ctx context.Context, store Store, id properties.UUID) (*Service, error)

func TransitionService

func TransitionService(ctx context.Context, store Store, id properties.UUID, target ServiceStatus) (*Service, error)

func UpdateService

func UpdateService(ctx context.Context, store Store, id properties.UUID, name *string, props *properties.JSON) (*Service, error)

func (*Service) HandleJobComplete

func (s *Service) HandleJobComplete(resources *properties.JSON, externalID *string) error

HandleJobComplete updates the service status when a job completes successfully

func (*Service) HandleJobFailure

func (s *Service) HandleJobFailure(errorMessage string, action ServiceAction)

HandleJobFailure updates the service status when a job fails

func (*Service) RetryFailedAction

func (s *Service) RetryFailedAction() *ServiceAction

RetryFailedAction prepares a service for retry and returns a job for the failed action

func (Service) TableName

func (Service) TableName() string

TableName returns the table name for the service

func (*Service) Transition

func (s *Service) Transition(targetStatus ServiceStatus) (*ServiceAction, error)

Transition sets the service statuss for a transition

func (*Service) Update

func (s *Service) Update(name *string, props *properties.JSON) (bool, *ServiceAction, error)

Update updates the service

func (Service) Validate

func (s Service) Validate() error

Validate a service

type ServiceAction

type ServiceAction string

ServiceAction represents the type of operation a job performs

const (
	ServiceActionCreate     ServiceAction = "ServiceCreate"
	ServiceActionStart      ServiceAction = "ServiceStart"
	ServiceActionStop       ServiceAction = "ServiceStop"
	ServiceActionHotUpdate  ServiceAction = "ServiceHotUpdate"
	ServiceActionColdUpdate ServiceAction = "ServiceColdUpdate"
	ServiceActionDelete     ServiceAction = "ServiceDelete"
)

func ParseServiceAction

func ParseServiceAction(s string) (ServiceAction, error)

ParseServiceAction parses a string into a JobType

func (ServiceAction) Validate

func (t ServiceAction) Validate() error

Validate checks if the job type is valid

type ServiceCommander

type ServiceCommander interface {
	// Create handles service creation and creates a job for the agent
	Create(ctx context.Context, agentID properties.UUID, serviceTypeID properties.UUID, groupID properties.UUID, name string, properties properties.JSON) (*Service, error)

	// CreateWithTags handles service creation using agent discovery by tags
	CreateWithTags(ctx context.Context, serviceTypeID properties.UUID, groupID properties.UUID, name string, properties properties.JSON, serviceTags []string) (*Service, error)

	// Update handles service updates and creates a job for the agent
	Update(ctx context.Context, id properties.UUID, name *string, props *properties.JSON) (*Service, error)

	// Transition transitions a service to a new status
	Transition(ctx context.Context, id properties.UUID, target ServiceStatus) (*Service, error)

	// Retry retries a failed service operation
	Retry(ctx context.Context, id properties.UUID) (*Service, error)

	// FailTimeoutServicesAndJobs fails services and jobs that have timed out
	FailTimeoutServicesAndJobs(ctx context.Context, timeout time.Duration) (int, error)
}

ServiceCommander defines the interface for service command operations

type ServiceGroup

type ServiceGroup struct {
	BaseEntity

	Name string `json:"name" gorm:"not null"`

	// Relationships
	Services    []Service       `json:"-" gorm:"foreignKey:GroupID"`
	ConsumerID  properties.UUID `json:"consumerId" gorm:"not null"`
	Participant *Participant    `json:"-" gorm:"foreignKey:ConsumerID"`
}

ServiceGroup represents a group of related services

func NewServiceGroup

func NewServiceGroup(name string, consumerID properties.UUID) *ServiceGroup

NewServiceGroup creates a new service group with validation

func (ServiceGroup) TableName

func (ServiceGroup) TableName() string

TableName returns the table name for the service

func (*ServiceGroup) Update

func (sg *ServiceGroup) Update(name *string) error

Update updates the service group properties and performs validation

func (*ServiceGroup) Validate

func (sg *ServiceGroup) Validate() error

Validate checks if the service group is valid

type ServiceGroupCommander

type ServiceGroupCommander interface {
	// Create creates a new service group
	Create(ctx context.Context, name string, consumerID properties.UUID) (*ServiceGroup, error)

	// Update updates an existing service group
	Update(ctx context.Context, id properties.UUID, name *string) (*ServiceGroup, error)

	// Delete removes a service group by ID after checking for dependencies
	Delete(ctx context.Context, id properties.UUID) error
}

ServiceGroupCommander defines the interface for service group command operations

type ServiceGroupQuerier

type ServiceGroupQuerier interface {
	BaseEntityQuerier[ServiceGroup]
}

ServiceGroupRepository defines the interface for the ServiceGroup read-only queries

type ServiceGroupRepository

type ServiceGroupRepository interface {
	ServiceGroupQuerier
	BaseEntityRepository[ServiceGroup]
}

ServiceGroupRepository defines the interface for the ServiceGroup repository

type ServiceQuerier

type ServiceQuerier interface {
	BaseEntityQuerier[Service]

	// FindByExternalID retrieves a service by its external ID and agent ID
	FindByExternalID(ctx context.Context, agentID properties.UUID, externalID string) (*Service, error)

	// CountByGroup returns the number of services in a specific group
	CountByGroup(ctx context.Context, groupID properties.UUID) (int64, error)

	// CountByAgent returns the number of services handled by a specific agent
	CountByAgent(ctx context.Context, agentID properties.UUID) (int64, error)
}

ServiceQuerier defines the interface for the Service read-only queries

type ServiceRepository

type ServiceRepository interface {
	ServiceQuerier
	BaseEntityRepository[Service]
}

ServiceRepository defines the interface for the Service repository

type ServiceStatus

type ServiceStatus string

ServiceStatus represents the possible statuss of a service

func ParseServiceStatus

func ParseServiceStatus(s string) (ServiceStatus, error)

ParseServiceStatus parses a string into a ServiceStatus

func (ServiceStatus) Validate

func (s ServiceStatus) Validate() error

Validate checks if the service status is valid

type ServiceType

type ServiceType struct {
	BaseEntity
	Name           string               `json:"name" gorm:"not null;unique"`
	PropertySchema *schema.CustomSchema `json:"propertySchema,omitempty" gorm:"type:jsonb"`
}

ServiceType represents a type of service that can be provided

func (ServiceType) TableName

func (ServiceType) TableName() string

TableName returns the table name for the service type

type ServiceTypeQuerier

type ServiceTypeQuerier interface {
	BaseEntityQuerier[ServiceType]
}

ServiceTypeQuerier defines the interface for the ServiceType read-only queries

type ServiceTypeRepository

type ServiceTypeRepository interface {
	ServiceTypeQuerier
	BaseEntityRepository[ServiceType]
}

ServiceTypeRepository defines the interface for the ServiceType repository

type Store

type Store interface {
	// Atomic executes function in a transaction
	Atomic(context.Context, func(Store) error) error

	// Repositories
	AgentTypeRepo() AgentTypeRepository
	AgentRepo() AgentRepository
	TokenRepo() TokenRepository
	ServiceTypeRepo() ServiceTypeRepository
	ServiceGroupRepo() ServiceGroupRepository
	ServiceRepo() ServiceRepository
	JobRepo() JobRepository
	EventRepo() EventRepository
	EventSubscriptionRepo() EventSubscriptionRepository
	MetricTypeRepo() MetricTypeRepository
	MetricEntryRepo() MetricEntryRepository
	ParticipantRepo() ParticipantRepository
}

Store provides data access to all repositories and supports transactions.

type Token

type Token struct {
	BaseEntity

	Name        string    `json:"name" gorm:"not null"`
	Role        auth.Role `json:"role" gorm:"not null"`
	PlainValue  string    `json:"-" gorm:"-"`
	HashedValue string    `json:"-" gorm:"not null"`
	ExpireAt    time.Time `json:"expireAt" gorm:"not null"`

	// Relationships
	ParticipantID *properties.UUID `json:"participantId,omitempty"`           // New field
	Participant   *Participant     `json:"-" gorm:"foreignKey:ParticipantID"` // New field
	AgentID       *properties.UUID `json:"agentId,omitempty"`
	Agent         *Agent           `json:"-" gorm:"foreignKey:AgentID"`
}

Token represents an authentication token

func NewToken

func NewToken(
	ctx context.Context,
	store Store,
	name string,
	role auth.Role,
	expireAt *time.Time,
	scopeID *properties.UUID,
) (*Token, error)

NewToken is an helper method to create a token with appropriate scope settings

func (*Token) GenerateTokenValue

func (t *Token) GenerateTokenValue() error

GenerateTokenValue creates a secure random token and sets the HashedValue field The plain text value is only returned and never stored in the entity

func (*Token) IsExpired

func (t *Token) IsExpired() bool

IsExpired checks if the token is expired

func (Token) TableName

func (Token) TableName() string

TableName returns the table name for the token

func (*Token) Update

func (t *Token) Update(name *string, expireAt *time.Time) error

Update updates the token properties

func (*Token) Validate

func (t *Token) Validate() error

Validate ensures all Token fields are valid

func (*Token) VerifyTokenValue

func (t *Token) VerifyTokenValue(value string) bool

VerifyTokenValue checks if a token matches the stored hash

type TokenCommander

type TokenCommander interface {
	// Create creates a new token
	Create(ctx context.Context, name string, role auth.Role, expireAt *time.Time, scopeID *properties.UUID) (*Token, error)

	// Update updates a token
	Update(ctx context.Context, id properties.UUID, name *string, expireAt *time.Time) (*Token, error)

	// Delete removes a token by ID
	Delete(ctx context.Context, id properties.UUID) error

	// Regenerate regenerates the token value
	Regenerate(ctx context.Context, id properties.UUID) (*Token, error)
}

TokenCommander defines the interface for token command operations

func NewTokenCommander

func NewTokenCommander(
	store Store,
) TokenCommander

NewTokenCommander creates a new TokenCommander

type TokenQuerier

type TokenQuerier interface {
	BaseEntityQuerier[Token]

	// FindByHashedValue finds a token by its hashed value
	FindByHashedValue(ctx context.Context, hashedValue string) (*Token, error)
}

type TokenRepository

type TokenRepository interface {
	TokenQuerier
	BaseEntityRepository[Token]

	// DeleteByParticipantID removes all tokens associated with a participant ID
	DeleteByParticipantID(ctx context.Context, participantID properties.UUID) error

	// DeleteByAgentID removes all tokens associated with an agent ID
	DeleteByAgentID(ctx context.Context, agentID properties.UUID) error
}

type UnauthorizedError

type UnauthorizedError struct {
	Err error
}

func NewUnauthorizedErrorf

func NewUnauthorizedErrorf(format string, a ...any) UnauthorizedError

func (UnauthorizedError) Error

func (e UnauthorizedError) Error() string

func (UnauthorizedError) Unwrap

func (e UnauthorizedError) Unwrap() error

type ValidationError

type ValidationError struct {
	Errors []ValidationErrorDetail `json:"errors"`
}

func NewValidationError

func NewValidationError(errors []ValidationErrorDetail) ValidationError

func (ValidationError) Error

func (e ValidationError) Error() string

type ValidationErrorDetail

type ValidationErrorDetail struct {
	Path    string `json:"path"`
	Message string `json:"message"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL