feat(sdk): ✨ Complete Phase 2 - AppInstance, Cloudlet APIs & CLI integration
Implemented comprehensive EdgeXR SDK with full API coverage and CLI integration:
## New API Coverage:
- **AppInstance Management**: Create, Show, List, Refresh, Delete instances
- **Cloudlet Management**: Create, Show, List, Delete cloudlets
- **Cloudlet Operations**: GetManifest, GetResourceUsage for monitoring
- **Streaming JSON**: Support for EdgeXR's multi-line JSON response format
## API Implementations:
### AppInstance APIs:
- CreateAppInstance → POST /auth/ctrl/CreateAppInst
- ShowAppInstance → POST /auth/ctrl/ShowAppInst
- ShowAppInstances → POST /auth/ctrl/ShowAppInst (multi-result)
- RefreshAppInstance → POST /auth/ctrl/RefreshAppInst
- DeleteAppInstance → POST /auth/ctrl/DeleteAppInst
### Cloudlet APIs:
- CreateCloudlet → POST /auth/ctrl/CreateCloudlet
- ShowCloudlet → POST /auth/ctrl/ShowCloudlet
- ShowCloudlets → POST /auth/ctrl/ShowCloudlet (multi-result)
- DeleteCloudlet → POST /auth/ctrl/DeleteCloudlet
- GetCloudletManifest → POST /auth/ctrl/GetCloudletManifest
- GetCloudletResourceUsage → POST /auth/ctrl/GetCloudletResourceUsage
## CLI Integration:
- **Backward Compatible**: Existing CLI commands work unchanged
- **Enhanced Reliability**: Now uses SDK with retry logic and caching
- **Same Interface**: All flags, config, and behavior preserved
- **Better Errors**: Structured error handling with meaningful messages
## Testing & Examples:
- **Comprehensive Test Suite**: 100+ test cases covering all APIs
- **Mock Servers**: httptest-based integration testing
- **Error Scenarios**: Network failures, auth errors, 404 handling
- **Real Workflow**: Complete app deployment example with cleanup
## Documentation:
- **SDK README**: Complete API reference and usage examples
- **Migration Guide**: Easy transition from existing client
- **Configuration**: All authentication and retry options documented
- **Performance**: Token caching, connection pooling benchmarks
## Quality Features:
- **Type Safety**: No more interface{} - full type definitions
- **Context Support**: Proper timeout/cancellation throughout
- **Error Handling**: Structured APIError with status codes
- **Resilience**: Automatic retry with exponential backoff
- **Observability**: Request logging and metrics hooks
The SDK is now production-ready with comprehensive API coverage,
robust error handling, and seamless CLI integration while maintaining
full backward compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:53:43 +02:00
|
|
|
// ABOUTME: Cloudlet management APIs for EdgeXR Master Controller
|
|
|
|
|
// ABOUTME: Provides typed methods for creating, querying, and managing edge cloudlets
|
|
|
|
|
|
2025-09-29 09:41:44 +02:00
|
|
|
package edgeconnect
|
feat(sdk): ✨ Complete Phase 2 - AppInstance, Cloudlet APIs & CLI integration
Implemented comprehensive EdgeXR SDK with full API coverage and CLI integration:
## New API Coverage:
- **AppInstance Management**: Create, Show, List, Refresh, Delete instances
- **Cloudlet Management**: Create, Show, List, Delete cloudlets
- **Cloudlet Operations**: GetManifest, GetResourceUsage for monitoring
- **Streaming JSON**: Support for EdgeXR's multi-line JSON response format
## API Implementations:
### AppInstance APIs:
- CreateAppInstance → POST /auth/ctrl/CreateAppInst
- ShowAppInstance → POST /auth/ctrl/ShowAppInst
- ShowAppInstances → POST /auth/ctrl/ShowAppInst (multi-result)
- RefreshAppInstance → POST /auth/ctrl/RefreshAppInst
- DeleteAppInstance → POST /auth/ctrl/DeleteAppInst
### Cloudlet APIs:
- CreateCloudlet → POST /auth/ctrl/CreateCloudlet
- ShowCloudlet → POST /auth/ctrl/ShowCloudlet
- ShowCloudlets → POST /auth/ctrl/ShowCloudlet (multi-result)
- DeleteCloudlet → POST /auth/ctrl/DeleteCloudlet
- GetCloudletManifest → POST /auth/ctrl/GetCloudletManifest
- GetCloudletResourceUsage → POST /auth/ctrl/GetCloudletResourceUsage
## CLI Integration:
- **Backward Compatible**: Existing CLI commands work unchanged
- **Enhanced Reliability**: Now uses SDK with retry logic and caching
- **Same Interface**: All flags, config, and behavior preserved
- **Better Errors**: Structured error handling with meaningful messages
## Testing & Examples:
- **Comprehensive Test Suite**: 100+ test cases covering all APIs
- **Mock Servers**: httptest-based integration testing
- **Error Scenarios**: Network failures, auth errors, 404 handling
- **Real Workflow**: Complete app deployment example with cleanup
## Documentation:
- **SDK README**: Complete API reference and usage examples
- **Migration Guide**: Easy transition from existing client
- **Configuration**: All authentication and retry options documented
- **Performance**: Token caching, connection pooling benchmarks
## Quality Features:
- **Type Safety**: No more interface{} - full type definitions
- **Context Support**: Proper timeout/cancellation throughout
- **Error Handling**: Structured APIError with status codes
- **Resilience**: Automatic retry with exponential backoff
- **Observability**: Request logging and metrics hooks
The SDK is now production-ready with comprehensive API coverage,
robust error handling, and seamless CLI integration while maintaining
full backward compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:53:43 +02:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
|
|
sdkhttp "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/internal/http"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// CreateCloudlet creates a new cloudlet in the specified region
|
|
|
|
|
// Maps to POST /auth/ctrl/CreateCloudlet
|
|
|
|
|
func (c *Client) CreateCloudlet(ctx context.Context, input *NewCloudletInput) error {
|
|
|
|
|
transport := c.getTransport()
|
|
|
|
|
url := c.BaseURL + "/api/v1/auth/ctrl/CreateCloudlet"
|
|
|
|
|
|
|
|
|
|
resp, err := transport.Call(ctx, "POST", url, input)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("CreateCloudlet failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode >= 400 {
|
|
|
|
|
return c.handleErrorResponse(resp, "CreateCloudlet")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.logf("CreateCloudlet: %s/%s created successfully",
|
|
|
|
|
input.Cloudlet.Key.Organization, input.Cloudlet.Key.Name)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ShowCloudlet retrieves a single cloudlet by key and region
|
|
|
|
|
// Maps to POST /auth/ctrl/ShowCloudlet
|
|
|
|
|
func (c *Client) ShowCloudlet(ctx context.Context, cloudletKey CloudletKey, region string) (Cloudlet, error) {
|
|
|
|
|
transport := c.getTransport()
|
|
|
|
|
url := c.BaseURL + "/api/v1/auth/ctrl/ShowCloudlet"
|
|
|
|
|
|
|
|
|
|
filter := CloudletFilter{
|
2025-09-25 17:08:08 +02:00
|
|
|
Cloudlet: Cloudlet{Key: cloudletKey},
|
|
|
|
|
Region: region,
|
feat(sdk): ✨ Complete Phase 2 - AppInstance, Cloudlet APIs & CLI integration
Implemented comprehensive EdgeXR SDK with full API coverage and CLI integration:
## New API Coverage:
- **AppInstance Management**: Create, Show, List, Refresh, Delete instances
- **Cloudlet Management**: Create, Show, List, Delete cloudlets
- **Cloudlet Operations**: GetManifest, GetResourceUsage for monitoring
- **Streaming JSON**: Support for EdgeXR's multi-line JSON response format
## API Implementations:
### AppInstance APIs:
- CreateAppInstance → POST /auth/ctrl/CreateAppInst
- ShowAppInstance → POST /auth/ctrl/ShowAppInst
- ShowAppInstances → POST /auth/ctrl/ShowAppInst (multi-result)
- RefreshAppInstance → POST /auth/ctrl/RefreshAppInst
- DeleteAppInstance → POST /auth/ctrl/DeleteAppInst
### Cloudlet APIs:
- CreateCloudlet → POST /auth/ctrl/CreateCloudlet
- ShowCloudlet → POST /auth/ctrl/ShowCloudlet
- ShowCloudlets → POST /auth/ctrl/ShowCloudlet (multi-result)
- DeleteCloudlet → POST /auth/ctrl/DeleteCloudlet
- GetCloudletManifest → POST /auth/ctrl/GetCloudletManifest
- GetCloudletResourceUsage → POST /auth/ctrl/GetCloudletResourceUsage
## CLI Integration:
- **Backward Compatible**: Existing CLI commands work unchanged
- **Enhanced Reliability**: Now uses SDK with retry logic and caching
- **Same Interface**: All flags, config, and behavior preserved
- **Better Errors**: Structured error handling with meaningful messages
## Testing & Examples:
- **Comprehensive Test Suite**: 100+ test cases covering all APIs
- **Mock Servers**: httptest-based integration testing
- **Error Scenarios**: Network failures, auth errors, 404 handling
- **Real Workflow**: Complete app deployment example with cleanup
## Documentation:
- **SDK README**: Complete API reference and usage examples
- **Migration Guide**: Easy transition from existing client
- **Configuration**: All authentication and retry options documented
- **Performance**: Token caching, connection pooling benchmarks
## Quality Features:
- **Type Safety**: No more interface{} - full type definitions
- **Context Support**: Proper timeout/cancellation throughout
- **Error Handling**: Structured APIError with status codes
- **Resilience**: Automatic retry with exponential backoff
- **Observability**: Request logging and metrics hooks
The SDK is now production-ready with comprehensive API coverage,
robust error handling, and seamless CLI integration while maintaining
full backward compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := transport.Call(ctx, "POST", url, filter)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return Cloudlet{}, fmt.Errorf("ShowCloudlet failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusNotFound {
|
|
|
|
|
return Cloudlet{}, fmt.Errorf("cloudlet %s/%s in region %s: %w",
|
|
|
|
|
cloudletKey.Organization, cloudletKey.Name, region, ErrResourceNotFound)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode >= 400 {
|
|
|
|
|
return Cloudlet{}, c.handleErrorResponse(resp, "ShowCloudlet")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse streaming JSON response
|
|
|
|
|
var cloudlets []Cloudlet
|
|
|
|
|
if err := c.parseStreamingCloudletResponse(resp, &cloudlets); err != nil {
|
|
|
|
|
return Cloudlet{}, fmt.Errorf("ShowCloudlet failed to parse response: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(cloudlets) == 0 {
|
|
|
|
|
return Cloudlet{}, fmt.Errorf("cloudlet %s/%s in region %s: %w",
|
|
|
|
|
cloudletKey.Organization, cloudletKey.Name, region, ErrResourceNotFound)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cloudlets[0], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ShowCloudlets retrieves all cloudlets matching the filter criteria
|
|
|
|
|
// Maps to POST /auth/ctrl/ShowCloudlet
|
|
|
|
|
func (c *Client) ShowCloudlets(ctx context.Context, cloudletKey CloudletKey, region string) ([]Cloudlet, error) {
|
|
|
|
|
transport := c.getTransport()
|
|
|
|
|
url := c.BaseURL + "/api/v1/auth/ctrl/ShowCloudlet"
|
|
|
|
|
|
|
|
|
|
filter := CloudletFilter{
|
2025-09-25 17:08:08 +02:00
|
|
|
Cloudlet: Cloudlet{Key: cloudletKey},
|
|
|
|
|
Region: region,
|
feat(sdk): ✨ Complete Phase 2 - AppInstance, Cloudlet APIs & CLI integration
Implemented comprehensive EdgeXR SDK with full API coverage and CLI integration:
## New API Coverage:
- **AppInstance Management**: Create, Show, List, Refresh, Delete instances
- **Cloudlet Management**: Create, Show, List, Delete cloudlets
- **Cloudlet Operations**: GetManifest, GetResourceUsage for monitoring
- **Streaming JSON**: Support for EdgeXR's multi-line JSON response format
## API Implementations:
### AppInstance APIs:
- CreateAppInstance → POST /auth/ctrl/CreateAppInst
- ShowAppInstance → POST /auth/ctrl/ShowAppInst
- ShowAppInstances → POST /auth/ctrl/ShowAppInst (multi-result)
- RefreshAppInstance → POST /auth/ctrl/RefreshAppInst
- DeleteAppInstance → POST /auth/ctrl/DeleteAppInst
### Cloudlet APIs:
- CreateCloudlet → POST /auth/ctrl/CreateCloudlet
- ShowCloudlet → POST /auth/ctrl/ShowCloudlet
- ShowCloudlets → POST /auth/ctrl/ShowCloudlet (multi-result)
- DeleteCloudlet → POST /auth/ctrl/DeleteCloudlet
- GetCloudletManifest → POST /auth/ctrl/GetCloudletManifest
- GetCloudletResourceUsage → POST /auth/ctrl/GetCloudletResourceUsage
## CLI Integration:
- **Backward Compatible**: Existing CLI commands work unchanged
- **Enhanced Reliability**: Now uses SDK with retry logic and caching
- **Same Interface**: All flags, config, and behavior preserved
- **Better Errors**: Structured error handling with meaningful messages
## Testing & Examples:
- **Comprehensive Test Suite**: 100+ test cases covering all APIs
- **Mock Servers**: httptest-based integration testing
- **Error Scenarios**: Network failures, auth errors, 404 handling
- **Real Workflow**: Complete app deployment example with cleanup
## Documentation:
- **SDK README**: Complete API reference and usage examples
- **Migration Guide**: Easy transition from existing client
- **Configuration**: All authentication and retry options documented
- **Performance**: Token caching, connection pooling benchmarks
## Quality Features:
- **Type Safety**: No more interface{} - full type definitions
- **Context Support**: Proper timeout/cancellation throughout
- **Error Handling**: Structured APIError with status codes
- **Resilience**: Automatic retry with exponential backoff
- **Observability**: Request logging and metrics hooks
The SDK is now production-ready with comprehensive API coverage,
robust error handling, and seamless CLI integration while maintaining
full backward compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := transport.Call(ctx, "POST", url, filter)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("ShowCloudlets failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode >= 400 && resp.StatusCode != http.StatusNotFound {
|
|
|
|
|
return nil, c.handleErrorResponse(resp, "ShowCloudlets")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var cloudlets []Cloudlet
|
|
|
|
|
if resp.StatusCode == http.StatusNotFound {
|
|
|
|
|
return cloudlets, nil // Return empty slice for not found
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := c.parseStreamingCloudletResponse(resp, &cloudlets); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("ShowCloudlets failed to parse response: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.logf("ShowCloudlets: found %d cloudlets matching criteria", len(cloudlets))
|
|
|
|
|
return cloudlets, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteCloudlet removes a cloudlet from the specified region
|
|
|
|
|
// Maps to POST /auth/ctrl/DeleteCloudlet
|
|
|
|
|
func (c *Client) DeleteCloudlet(ctx context.Context, cloudletKey CloudletKey, region string) error {
|
|
|
|
|
transport := c.getTransport()
|
|
|
|
|
url := c.BaseURL + "/api/v1/auth/ctrl/DeleteCloudlet"
|
|
|
|
|
|
|
|
|
|
filter := CloudletFilter{
|
2025-09-25 17:08:08 +02:00
|
|
|
Cloudlet: Cloudlet{Key: cloudletKey},
|
|
|
|
|
Region: region,
|
feat(sdk): ✨ Complete Phase 2 - AppInstance, Cloudlet APIs & CLI integration
Implemented comprehensive EdgeXR SDK with full API coverage and CLI integration:
## New API Coverage:
- **AppInstance Management**: Create, Show, List, Refresh, Delete instances
- **Cloudlet Management**: Create, Show, List, Delete cloudlets
- **Cloudlet Operations**: GetManifest, GetResourceUsage for monitoring
- **Streaming JSON**: Support for EdgeXR's multi-line JSON response format
## API Implementations:
### AppInstance APIs:
- CreateAppInstance → POST /auth/ctrl/CreateAppInst
- ShowAppInstance → POST /auth/ctrl/ShowAppInst
- ShowAppInstances → POST /auth/ctrl/ShowAppInst (multi-result)
- RefreshAppInstance → POST /auth/ctrl/RefreshAppInst
- DeleteAppInstance → POST /auth/ctrl/DeleteAppInst
### Cloudlet APIs:
- CreateCloudlet → POST /auth/ctrl/CreateCloudlet
- ShowCloudlet → POST /auth/ctrl/ShowCloudlet
- ShowCloudlets → POST /auth/ctrl/ShowCloudlet (multi-result)
- DeleteCloudlet → POST /auth/ctrl/DeleteCloudlet
- GetCloudletManifest → POST /auth/ctrl/GetCloudletManifest
- GetCloudletResourceUsage → POST /auth/ctrl/GetCloudletResourceUsage
## CLI Integration:
- **Backward Compatible**: Existing CLI commands work unchanged
- **Enhanced Reliability**: Now uses SDK with retry logic and caching
- **Same Interface**: All flags, config, and behavior preserved
- **Better Errors**: Structured error handling with meaningful messages
## Testing & Examples:
- **Comprehensive Test Suite**: 100+ test cases covering all APIs
- **Mock Servers**: httptest-based integration testing
- **Error Scenarios**: Network failures, auth errors, 404 handling
- **Real Workflow**: Complete app deployment example with cleanup
## Documentation:
- **SDK README**: Complete API reference and usage examples
- **Migration Guide**: Easy transition from existing client
- **Configuration**: All authentication and retry options documented
- **Performance**: Token caching, connection pooling benchmarks
## Quality Features:
- **Type Safety**: No more interface{} - full type definitions
- **Context Support**: Proper timeout/cancellation throughout
- **Error Handling**: Structured APIError with status codes
- **Resilience**: Automatic retry with exponential backoff
- **Observability**: Request logging and metrics hooks
The SDK is now production-ready with comprehensive API coverage,
robust error handling, and seamless CLI integration while maintaining
full backward compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := transport.Call(ctx, "POST", url, filter)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("DeleteCloudlet failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
// 404 is acceptable for delete operations (already deleted)
|
|
|
|
|
if resp.StatusCode >= 400 && resp.StatusCode != http.StatusNotFound {
|
|
|
|
|
return c.handleErrorResponse(resp, "DeleteCloudlet")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.logf("DeleteCloudlet: %s/%s deleted successfully",
|
|
|
|
|
cloudletKey.Organization, cloudletKey.Name)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetCloudletManifest retrieves the deployment manifest for a cloudlet
|
|
|
|
|
// Maps to POST /auth/ctrl/GetCloudletManifest
|
|
|
|
|
func (c *Client) GetCloudletManifest(ctx context.Context, cloudletKey CloudletKey, region string) (*CloudletManifest, error) {
|
|
|
|
|
transport := c.getTransport()
|
|
|
|
|
url := c.BaseURL + "/api/v1/auth/ctrl/GetCloudletManifest"
|
|
|
|
|
|
|
|
|
|
filter := CloudletFilter{
|
2025-09-25 17:08:08 +02:00
|
|
|
Cloudlet: Cloudlet{Key: cloudletKey},
|
|
|
|
|
Region: region,
|
feat(sdk): ✨ Complete Phase 2 - AppInstance, Cloudlet APIs & CLI integration
Implemented comprehensive EdgeXR SDK with full API coverage and CLI integration:
## New API Coverage:
- **AppInstance Management**: Create, Show, List, Refresh, Delete instances
- **Cloudlet Management**: Create, Show, List, Delete cloudlets
- **Cloudlet Operations**: GetManifest, GetResourceUsage for monitoring
- **Streaming JSON**: Support for EdgeXR's multi-line JSON response format
## API Implementations:
### AppInstance APIs:
- CreateAppInstance → POST /auth/ctrl/CreateAppInst
- ShowAppInstance → POST /auth/ctrl/ShowAppInst
- ShowAppInstances → POST /auth/ctrl/ShowAppInst (multi-result)
- RefreshAppInstance → POST /auth/ctrl/RefreshAppInst
- DeleteAppInstance → POST /auth/ctrl/DeleteAppInst
### Cloudlet APIs:
- CreateCloudlet → POST /auth/ctrl/CreateCloudlet
- ShowCloudlet → POST /auth/ctrl/ShowCloudlet
- ShowCloudlets → POST /auth/ctrl/ShowCloudlet (multi-result)
- DeleteCloudlet → POST /auth/ctrl/DeleteCloudlet
- GetCloudletManifest → POST /auth/ctrl/GetCloudletManifest
- GetCloudletResourceUsage → POST /auth/ctrl/GetCloudletResourceUsage
## CLI Integration:
- **Backward Compatible**: Existing CLI commands work unchanged
- **Enhanced Reliability**: Now uses SDK with retry logic and caching
- **Same Interface**: All flags, config, and behavior preserved
- **Better Errors**: Structured error handling with meaningful messages
## Testing & Examples:
- **Comprehensive Test Suite**: 100+ test cases covering all APIs
- **Mock Servers**: httptest-based integration testing
- **Error Scenarios**: Network failures, auth errors, 404 handling
- **Real Workflow**: Complete app deployment example with cleanup
## Documentation:
- **SDK README**: Complete API reference and usage examples
- **Migration Guide**: Easy transition from existing client
- **Configuration**: All authentication and retry options documented
- **Performance**: Token caching, connection pooling benchmarks
## Quality Features:
- **Type Safety**: No more interface{} - full type definitions
- **Context Support**: Proper timeout/cancellation throughout
- **Error Handling**: Structured APIError with status codes
- **Resilience**: Automatic retry with exponential backoff
- **Observability**: Request logging and metrics hooks
The SDK is now production-ready with comprehensive API coverage,
robust error handling, and seamless CLI integration while maintaining
full backward compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := transport.Call(ctx, "POST", url, filter)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("GetCloudletManifest failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusNotFound {
|
|
|
|
|
return nil, fmt.Errorf("cloudlet manifest %s/%s in region %s: %w",
|
|
|
|
|
cloudletKey.Organization, cloudletKey.Name, region, ErrResourceNotFound)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode >= 400 {
|
|
|
|
|
return nil, c.handleErrorResponse(resp, "GetCloudletManifest")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse the response as CloudletManifest
|
|
|
|
|
var manifest CloudletManifest
|
|
|
|
|
if err := c.parseDirectJSONResponse(resp, &manifest); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("GetCloudletManifest failed to parse response: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.logf("GetCloudletManifest: retrieved manifest for %s/%s",
|
|
|
|
|
cloudletKey.Organization, cloudletKey.Name)
|
|
|
|
|
|
|
|
|
|
return &manifest, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetCloudletResourceUsage retrieves resource usage information for a cloudlet
|
|
|
|
|
// Maps to POST /auth/ctrl/GetCloudletResourceUsage
|
|
|
|
|
func (c *Client) GetCloudletResourceUsage(ctx context.Context, cloudletKey CloudletKey, region string) (*CloudletResourceUsage, error) {
|
|
|
|
|
transport := c.getTransport()
|
|
|
|
|
url := c.BaseURL + "/api/v1/auth/ctrl/GetCloudletResourceUsage"
|
|
|
|
|
|
|
|
|
|
filter := CloudletFilter{
|
2025-09-25 17:08:08 +02:00
|
|
|
Cloudlet: Cloudlet{Key: cloudletKey},
|
|
|
|
|
Region: region,
|
feat(sdk): ✨ Complete Phase 2 - AppInstance, Cloudlet APIs & CLI integration
Implemented comprehensive EdgeXR SDK with full API coverage and CLI integration:
## New API Coverage:
- **AppInstance Management**: Create, Show, List, Refresh, Delete instances
- **Cloudlet Management**: Create, Show, List, Delete cloudlets
- **Cloudlet Operations**: GetManifest, GetResourceUsage for monitoring
- **Streaming JSON**: Support for EdgeXR's multi-line JSON response format
## API Implementations:
### AppInstance APIs:
- CreateAppInstance → POST /auth/ctrl/CreateAppInst
- ShowAppInstance → POST /auth/ctrl/ShowAppInst
- ShowAppInstances → POST /auth/ctrl/ShowAppInst (multi-result)
- RefreshAppInstance → POST /auth/ctrl/RefreshAppInst
- DeleteAppInstance → POST /auth/ctrl/DeleteAppInst
### Cloudlet APIs:
- CreateCloudlet → POST /auth/ctrl/CreateCloudlet
- ShowCloudlet → POST /auth/ctrl/ShowCloudlet
- ShowCloudlets → POST /auth/ctrl/ShowCloudlet (multi-result)
- DeleteCloudlet → POST /auth/ctrl/DeleteCloudlet
- GetCloudletManifest → POST /auth/ctrl/GetCloudletManifest
- GetCloudletResourceUsage → POST /auth/ctrl/GetCloudletResourceUsage
## CLI Integration:
- **Backward Compatible**: Existing CLI commands work unchanged
- **Enhanced Reliability**: Now uses SDK with retry logic and caching
- **Same Interface**: All flags, config, and behavior preserved
- **Better Errors**: Structured error handling with meaningful messages
## Testing & Examples:
- **Comprehensive Test Suite**: 100+ test cases covering all APIs
- **Mock Servers**: httptest-based integration testing
- **Error Scenarios**: Network failures, auth errors, 404 handling
- **Real Workflow**: Complete app deployment example with cleanup
## Documentation:
- **SDK README**: Complete API reference and usage examples
- **Migration Guide**: Easy transition from existing client
- **Configuration**: All authentication and retry options documented
- **Performance**: Token caching, connection pooling benchmarks
## Quality Features:
- **Type Safety**: No more interface{} - full type definitions
- **Context Support**: Proper timeout/cancellation throughout
- **Error Handling**: Structured APIError with status codes
- **Resilience**: Automatic retry with exponential backoff
- **Observability**: Request logging and metrics hooks
The SDK is now production-ready with comprehensive API coverage,
robust error handling, and seamless CLI integration while maintaining
full backward compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-25 14:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := transport.Call(ctx, "POST", url, filter)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("GetCloudletResourceUsage failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusNotFound {
|
|
|
|
|
return nil, fmt.Errorf("cloudlet resource usage %s/%s in region %s: %w",
|
|
|
|
|
cloudletKey.Organization, cloudletKey.Name, region, ErrResourceNotFound)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode >= 400 {
|
|
|
|
|
return nil, c.handleErrorResponse(resp, "GetCloudletResourceUsage")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Parse the response as CloudletResourceUsage
|
|
|
|
|
var usage CloudletResourceUsage
|
|
|
|
|
if err := c.parseDirectJSONResponse(resp, &usage); err != nil {
|
|
|
|
|
return nil, fmt.Errorf("GetCloudletResourceUsage failed to parse response: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.logf("GetCloudletResourceUsage: retrieved usage for %s/%s",
|
|
|
|
|
cloudletKey.Organization, cloudletKey.Name)
|
|
|
|
|
|
|
|
|
|
return &usage, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// parseStreamingCloudletResponse parses the EdgeXR streaming JSON response format for cloudlets
|
|
|
|
|
func (c *Client) parseStreamingCloudletResponse(resp *http.Response, result interface{}) error {
|
|
|
|
|
var responses []Response[Cloudlet]
|
|
|
|
|
|
|
|
|
|
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error {
|
|
|
|
|
var response Response[Cloudlet]
|
|
|
|
|
if err := json.Unmarshal(line, &response); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
responses = append(responses, response)
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if parseErr != nil {
|
|
|
|
|
return parseErr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Extract data from responses
|
|
|
|
|
var cloudlets []Cloudlet
|
|
|
|
|
var messages []string
|
|
|
|
|
|
|
|
|
|
for _, response := range responses {
|
|
|
|
|
if response.HasData() {
|
|
|
|
|
cloudlets = append(cloudlets, response.Data)
|
|
|
|
|
}
|
|
|
|
|
if response.IsMessage() {
|
|
|
|
|
messages = append(messages, response.Data.GetMessage())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we have error messages, return them
|
|
|
|
|
if len(messages) > 0 {
|
|
|
|
|
return &APIError{
|
|
|
|
|
StatusCode: resp.StatusCode,
|
|
|
|
|
Messages: messages,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set result based on type
|
|
|
|
|
switch v := result.(type) {
|
|
|
|
|
case *[]Cloudlet:
|
|
|
|
|
*v = cloudlets
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("unsupported result type: %T", result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// parseDirectJSONResponse parses a direct JSON response (not streaming)
|
|
|
|
|
func (c *Client) parseDirectJSONResponse(resp *http.Response, result interface{}) error {
|
|
|
|
|
decoder := json.NewDecoder(resp.Body)
|
|
|
|
|
if err := decoder.Decode(result); err != nil {
|
|
|
|
|
return fmt.Errorf("failed to decode JSON response: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2025-09-25 17:08:08 +02:00
|
|
|
}
|