edge-connect-client/sdk/client/types.go

226 lines
6.3 KiB
Go

// ABOUTME: Core type definitions for EdgeXR Master Controller SDK
// ABOUTME: These types are based on the swagger API specification and existing client patterns
package client
import (
"encoding/json"
"fmt"
"time"
)
// Message interface for types that can provide error messages
type Message interface {
GetMessage() string
}
// Base message type for API responses
type msg struct {
Message string `json:"message,omitempty"`
}
func (m msg) GetMessage() string {
return m.Message
}
// AppKey uniquely identifies an application
type AppKey struct {
Organization string `json:"organization"`
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
}
// CloudletKey uniquely identifies a cloudlet
type CloudletKey struct {
Organization string `json:"organization"`
Name string `json:"name"`
}
// AppInstanceKey uniquely identifies an application instance
type AppInstanceKey struct {
Organization string `json:"organization"`
Name string `json:"name"`
CloudletKey CloudletKey `json:"cloudlet_key"`
}
// Flavor defines resource allocation for instances
type Flavor struct {
Name string `json:"name"`
}
// SecurityRule defines network access rules
type SecurityRule struct {
PortRangeMax int `json:"port_range_max"`
PortRangeMin int `json:"port_range_min"`
Protocol string `json:"protocol"`
RemoteCIDR string `json:"remote_cidr"`
}
// App represents an application definition
type App struct {
msg `json:",inline"`
Key AppKey `json:"key"`
Deployment string `json:"deployment,omitempty"`
ImageType string `json:"image_type,omitempty"`
ImagePath string `json:"image_path,omitempty"`
AllowServerless bool `json:"allow_serverless,omitempty"`
DefaultFlavor Flavor `json:"defaultFlavor,omitempty"`
ServerlessConfig interface{} `json:"serverless_config,omitempty"`
DeploymentGenerator string `json:"deployment_generator,omitempty"`
DeploymentManifest string `json:"deployment_manifest,omitempty"`
RequiredOutboundConnections []SecurityRule `json:"required_outbound_connections"`
}
// AppInstance represents a deployed application instance
type AppInstance struct {
msg `json:",inline"`
Key AppInstanceKey `json:"key"`
AppKey AppKey `json:"app_key,omitempty"`
Flavor Flavor `json:"flavor,omitempty"`
State string `json:"state,omitempty"`
PowerState string `json:"power_state,omitempty"`
}
// Cloudlet represents edge infrastructure
type Cloudlet struct {
msg `json:",inline"`
Key CloudletKey `json:"key"`
Location Location `json:"location"`
IpSupport string `json:"ip_support,omitempty"`
NumDynamicIps int32 `json:"num_dynamic_ips,omitempty"`
State string `json:"state,omitempty"`
Flavor Flavor `json:"flavor,omitempty"`
PhysicalName string `json:"physical_name,omitempty"`
Region string `json:"region,omitempty"`
NotifySrvAddr string `json:"notify_srv_addr,omitempty"`
}
// Location represents geographical coordinates
type Location struct {
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
// Input types for API operations
// NewAppInput represents input for creating an application
type NewAppInput struct {
Region string `json:"region"`
App App `json:"app"`
}
// NewAppInstanceInput represents input for creating an app instance
type NewAppInstanceInput struct {
Region string `json:"region"`
AppInst AppInstance `json:"appinst"`
}
// NewCloudletInput represents input for creating a cloudlet
type NewCloudletInput struct {
Region string `json:"region"`
Cloudlet Cloudlet `json:"cloudlet"`
}
// Response wrapper types
// Response wraps a single API response
type Response[T Message] struct {
Data T `json:"data"`
}
func (res *Response[T]) HasData() bool {
return !res.IsMessage()
}
func (res *Response[T]) IsMessage() bool {
return res.Data.GetMessage() != ""
}
// Responses wraps multiple API responses with metadata
type Responses[T Message] struct {
Responses []Response[T] `json:"responses,omitempty"`
StatusCode int `json:"-"`
}
func (r *Responses[T]) GetData() []T {
var data []T
for _, v := range r.Responses {
if v.HasData() {
data = append(data, v.Data)
}
}
return data
}
func (r *Responses[T]) GetMessages() []string {
var messages []string
for _, v := range r.Responses {
if v.IsMessage() {
messages = append(messages, v.Data.GetMessage())
}
}
return messages
}
func (r *Responses[T]) IsSuccessful() bool {
return r.StatusCode >= 200 && r.StatusCode < 400
}
func (r *Responses[T]) Error() error {
if r.IsSuccessful() {
return nil
}
return &APIError{
StatusCode: r.StatusCode,
Messages: r.GetMessages(),
}
}
// APIError represents an API error with details
type APIError struct {
StatusCode int `json:"status_code"`
Code string `json:"code,omitempty"`
Messages []string `json:"messages,omitempty"`
Body []byte `json:"-"`
}
func (e *APIError) Error() string {
jsonErr, err := json.Marshal(e)
if err != nil {
return fmt.Sprintf("API error: %v", err)
}
return fmt.Sprintf("API error: %s", jsonErr)
}
// Filter types for querying
// AppFilter represents filters for app queries
type AppFilter struct {
AppKey AppKey `json:"app"`
Region string `json:"region"`
}
// AppInstanceFilter represents filters for app instance queries
type AppInstanceFilter struct {
AppInstanceKey AppInstanceKey `json:"appinst"`
Region string `json:"region"`
}
// CloudletFilter represents filters for cloudlet queries
type CloudletFilter struct {
CloudletKey CloudletKey `json:"cloudlet"`
Region string `json:"region"`
}
// CloudletManifest represents cloudlet deployment manifest
type CloudletManifest struct {
Manifest string `json:"manifest"`
LastModified time.Time `json:"last_modified,omitempty"`
}
// CloudletResourceUsage represents cloudlet resource utilization
type CloudletResourceUsage struct {
CloudletKey CloudletKey `json:"cloudlet_key"`
Region string `json:"region"`
Usage map[string]interface{} `json:"usage"`
}