✨ Features: - Simple dependency inversion following SOLID principles - Clean constructor injection without complex DI containers - Proper hexagonal architecture with driving/driven separation - Presentation layer moved to cmd/cli for correct application structure 🏗️ Architecture Changes: - Driving Adapters (Inbound): internal/adapters/driving/cli/ - Driven Adapters (Outbound): internal/adapters/driven/edgeconnect/ - Core Services: Dependency-injected via interface parameters - main.go relocated from root to cmd/cli/main.go 📦 Application Flow: 1. cmd/cli/main.go - Entry point and dependency wiring └── Creates EdgeConnect client based on environment └── Instantiates services with injected repositories └── Executes CLI with properly wired dependencies 2. internal/adapters/driving/cli/ - User interface layer └── Receives user commands and input validation └── Delegates to core services via driving ports └── Handles presentation logic and output formatting 3. internal/core/services/ - Business logic layer └── NewAppService(appRepo, instanceRepo) - Constructor injection └── NewAppInstanceService(instanceRepo) - Interface dependencies └── NewCloudletService(cloudletRepo) - Clean separation 4. internal/adapters/driven/edgeconnect/ - Infrastructure layer └── Implements repository interfaces for external API └── Handles HTTP communication and data persistence └── Provides concrete implementations of driven ports 🔧 Build & Deployment: - CLI Binary: make build → bin/edge-connect-cli - Usage: ./bin/edge-connect-cli --help - Tests: make test (all passing) - Clean: make clean (updated paths) 💡 Benefits: - Simple and maintainable dependency management - Testable architecture with clear boundaries - SOLID principles compliance without overengineering - Proper separation of concerns in hexagonal structure |
||
|---|---|---|
| .. | ||
| examples | ||
| README.md | ||
EdgeXR Master Controller Go SDK
A comprehensive Go SDK for the EdgeXR Master Controller API, providing typed interfaces for edge application lifecycle management, cloudlet orchestration, and instance deployment workflows.
Features
- 🔐 Dual Authentication: Static Bearer tokens and username/password with token caching
- 📡 Resilient HTTP: Built-in retry logic, exponential backoff, and context support
- ⚡ Type Safety: Full type definitions based on EdgeXR API specifications
- 🧪 Comprehensive Testing: Unit tests with mock servers and error condition coverage
- 📊 Streaming Responses: Support for EdgeXR's streaming JSON response format
- 🔧 CLI Integration: Drop-in replacement for existing edge-connect CLI
Quick Start
Installation
import "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/edgeconnect"
Authentication
// Username/password (recommended)
client := client.NewClientWithCredentials(baseURL, username, password)
// Static Bearer token
client := client.NewClient(baseURL,
client.WithAuthProvider(client.NewStaticTokenProvider(token)))
Basic Usage
ctx := context.Background()
// Create an application
app := &client.NewAppInput{
Region: "us-west",
App: client.App{
Key: client.AppKey{
Organization: "myorg",
Name: "my-app",
Version: "1.0.0",
},
Deployment: "kubernetes",
ImagePath: "nginx:latest",
},
}
if err := client.CreateApp(ctx, app); err != nil {
log.Fatal(err)
}
// Deploy an application instance
instance := &client.NewAppInstanceInput{
Region: "us-west",
AppInst: client.AppInstance{
Key: client.AppInstanceKey{
Organization: "myorg",
Name: "my-instance",
CloudletKey: client.CloudletKey{
Organization: "cloudlet-provider",
Name: "edge-cloudlet",
},
},
AppKey: app.App.Key,
Flavor: client.Flavor{Name: "m4.small"},
},
}
if err := client.CreateAppInstance(ctx, instance); err != nil {
log.Fatal(err)
}
API Coverage
Application Management
CreateApp()→POST /auth/ctrl/CreateAppShowApp()→POST /auth/ctrl/ShowAppShowApps()→POST /auth/ctrl/ShowApp(multi-result)DeleteApp()→POST /auth/ctrl/DeleteApp
Application Instance Management
CreateAppInstance()→POST /auth/ctrl/CreateAppInstShowAppInstance()→POST /auth/ctrl/ShowAppInstShowAppInstances()→POST /auth/ctrl/ShowAppInst(multi-result)RefreshAppInstance()→POST /auth/ctrl/RefreshAppInstDeleteAppInstance()→POST /auth/ctrl/DeleteAppInst
Cloudlet Management
CreateCloudlet()→POST /auth/ctrl/CreateCloudletShowCloudlet()→POST /auth/ctrl/ShowCloudletShowCloudlets()→POST /auth/ctrl/ShowCloudlet(multi-result)DeleteCloudlet()→POST /auth/ctrl/DeleteCloudletGetCloudletManifest()→POST /auth/ctrl/GetCloudletManifestGetCloudletResourceUsage()→POST /auth/ctrl/GetCloudletResourceUsage
Configuration Options
client := client.NewClient(baseURL,
// Custom HTTP client with timeout
client.WithHTTPClient(&http.Client{Timeout: 30 * time.Second}),
// Authentication provider
client.WithAuthProvider(client.NewStaticTokenProvider(token)),
// Retry configuration
client.WithRetryOptions(client.RetryOptions{
MaxRetries: 5,
InitialDelay: 1 * time.Second,
MaxDelay: 30 * time.Second,
}),
// Request logging
client.WithLogger(log.Default()),
)
Examples
Simple App Deployment
# Run basic example
EDGEXR_USERNAME=user EDGEXR_PASSWORD=pass go run sdk/examples/deploy_app.go
Comprehensive Workflow
# Run full workflow demonstration
cd sdk/examples/comprehensive
EDGEXR_USERNAME=user EDGEXR_PASSWORD=pass go run main.go
Authentication Methods
Username/Password (Recommended)
Uses the existing /api/v1/login endpoint with automatic token caching:
client := client.NewClientWithCredentials(baseURL, username, password)
Features:
- Automatic token refresh on expiry
- Thread-safe token caching
- 1-hour default cache duration
- Matches existing client authentication exactly
Static Bearer Token
For pre-obtained tokens:
client := client.NewClient(baseURL,
client.WithAuthProvider(client.NewStaticTokenProvider(token)))
Error Handling
app, err := client.ShowApp(ctx, appKey, region)
if err != nil {
// Check for specific error types
if errors.Is(err, client.ErrResourceNotFound) {
fmt.Println("App not found")
return
}
// Check for API errors
var apiErr *client.APIError
if errors.As(err, &apiErr) {
fmt.Printf("API Error %d: %s\n", apiErr.StatusCode, apiErr.Messages[0])
return
}
// Network or other errors
fmt.Printf("Request failed: %v\n", err)
}
Testing
# Run all SDK tests
go test ./sdk/client/ -v
# Run with coverage
go test ./sdk/client/ -v -coverprofile=coverage.out
go tool cover -html=coverage.out
# Run specific test suites
go test ./sdk/client/ -v -run TestApp
go test ./sdk/client/ -v -run TestAuth
go test ./sdk/client/ -v -run TestCloudlet
CLI Integration
The existing edge-connect CLI has been updated to use the SDK internally while maintaining full backward compatibility:
# Same commands, enhanced reliability
edge-connect app create --org myorg --name myapp --version 1.0.0 --region us-west
edge-connect instance create --org myorg --name myinst --app myapp --version 1.0.0
Migration from Existing Client
The SDK provides a drop-in replacement with enhanced features:
// Old approach
oldClient := &client.EdgeConnect{
BaseURL: baseURL,
Credentials: client.Credentials{Username: user, Password: pass},
}
// New SDK approach
newClient := client.NewClientWithCredentials(baseURL, user, pass)
// Same method calls, enhanced reliability
err := newClient.CreateApp(ctx, input)
Performance
- Token Caching: Reduces login API calls by >90%
- Connection Pooling: Reuses HTTP connections efficiently
- Context Support: Proper timeout and cancellation handling
- Retry Logic: Automatic recovery from transient failures
Contributing
Project Structure
sdk/
├── client/ # Public SDK interfaces
├── internal/http/ # HTTP transport layer
├── examples/ # Usage demonstrations
└── README.md # This file
Development
# Install dependencies
go mod tidy
# Generate types (if swagger changes)
make generate
# Run tests
make test
# Build everything
make build
License
This SDK follows the same license as the parent edge-connect-client project.