feat(swagger_v2): added support for the orca staging environment

This commit is contained in:
Richard Robert Reitz 2025-10-20 13:05:36 +02:00
parent 0f71239db6
commit 1413836b68
9 changed files with 186 additions and 39 deletions

View file

@ -4,9 +4,11 @@
package edgeconnect
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
sdkhttp "edp.buildth.ing/DevFW-CICD/edge-connect-client/sdk/internal/http"
@ -164,18 +166,17 @@ func (c *Client) RefreshAppInstance(ctx context.Context, appInstKey AppInstanceK
return nil
}
// DeleteAppInstance removes an application instance from the specified region
// DeleteAppInstance removes an application instance
// Maps to POST /auth/ctrl/DeleteAppInst
func (c *Client) DeleteAppInstance(ctx context.Context, appInstKey AppInstanceKey, region string) error {
transport := c.getTransport()
url := c.BaseURL + "/api/v1/auth/ctrl/DeleteAppInst"
filter := AppInstanceFilter{
AppInstance: AppInstance{Key: appInstKey},
Region: region,
input := DeleteAppInstanceInput{
Key: appInstKey,
}
resp, err := transport.Call(ctx, "POST", url, filter)
resp, err := transport.Call(ctx, "POST", url, input)
if err != nil {
return fmt.Errorf("DeleteAppInstance failed: %w", err)
}
@ -194,13 +195,29 @@ func (c *Client) DeleteAppInstance(ctx context.Context, appInstKey AppInstanceKe
// parseStreamingAppInstanceResponse parses the EdgeXR streaming JSON response format for app instances
func (c *Client) parseStreamingAppInstanceResponse(resp *http.Response, result interface{}) error {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %w", err)
}
// Try parsing as a direct JSON array first (v2 API format)
switch v := result.(type) {
case *[]AppInstance:
var appInstances []AppInstance
if err := json.Unmarshal(bodyBytes, &appInstances); err == nil {
*v = appInstances
return nil
}
}
// Fall back to streaming format (v1 API format)
var appInstances []AppInstance
var messages []string
var hasError bool
var errorCode int
var errorMessage string
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error {
parseErr := sdkhttp.ParseJSONLines(io.NopCloser(bytes.NewReader(bodyBytes)), func(line []byte) error {
// Try parsing as ResultResponse first (error format)
var resultResp ResultResponse
if err := json.Unmarshal(line, &resultResp); err == nil && resultResp.Result.Message != "" {

View file

@ -4,6 +4,7 @@
package edgeconnect
import (
"bytes"
"context"
"encoding/json"
"fmt"
@ -142,12 +143,12 @@ func (c *Client) DeleteApp(ctx context.Context, appKey AppKey, region string) er
transport := c.getTransport()
url := c.BaseURL + "/api/v1/auth/ctrl/DeleteApp"
filter := AppFilter{
App: App{Key: appKey},
input := DeleteAppInput{
Key: appKey,
Region: region,
}
resp, err := transport.Call(ctx, "POST", url, filter)
resp, err := transport.Call(ctx, "POST", url, input)
if err != nil {
return fmt.Errorf("DeleteApp failed: %w", err)
}
@ -166,9 +167,27 @@ func (c *Client) DeleteApp(ctx context.Context, appKey AppKey, region string) er
// parseStreamingResponse parses the EdgeXR streaming JSON response format
func (c *Client) parseStreamingResponse(resp *http.Response, result interface{}) error {
var responses []Response[App]
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %w", err)
}
parseErr := sdkhttp.ParseJSONLines(resp.Body, func(line []byte) error {
// Try parsing as a direct JSON array first (v2 API format)
switch v := result.(type) {
case *[]App:
var apps []App
if err := json.Unmarshal(bodyBytes, &apps); err == nil {
*v = apps
return nil
}
}
// Fall back to streaming format (v1 API format)
var responses []Response[App]
var apps []App
var messages []string
parseErr := sdkhttp.ParseJSONLines(io.NopCloser(bytes.NewReader(bodyBytes)), func(line []byte) error {
var response Response[App]
if err := json.Unmarshal(line, &response); err != nil {
return err
@ -182,9 +201,6 @@ func (c *Client) parseStreamingResponse(resp *http.Response, result interface{})
}
// Extract data from responses
var apps []App
var messages []string
for _, response := range responses {
if response.HasData() {
apps = append(apps, response.Data)

View file

@ -184,24 +184,33 @@ type App struct {
Deployment string `json:"deployment,omitempty"`
ImageType string `json:"image_type,omitempty"`
ImagePath string `json:"image_path,omitempty"`
AccessPorts string `json:"access_ports,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"`
GlobalID string `json:"global_id,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
Fields []string `json:"fields,omitempty"`
}
// 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"`
Fields []string `json:"fields,omitempty"`
msg `json:",inline"`
Key AppInstanceKey `json:"key"`
AppKey AppKey `json:"app_key,omitempty"`
CloudletLoc CloudletLoc `json:"cloudlet_loc,omitempty"`
Flavor Flavor `json:"flavor,omitempty"`
State string `json:"state,omitempty"`
IngressURL string `json:"ingress_url,omitempty"`
UniqueID string `json:"unique_id,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
PowerState string `json:"power_state,omitempty"`
Fields []string `json:"fields,omitempty"`
}
// Cloudlet represents edge infrastructure
@ -224,6 +233,12 @@ type Location struct {
Longitude float64 `json:"longitude"`
}
// CloudletLoc represents geographical coordinates for cloudlets
type CloudletLoc struct {
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
// Input types for API operations
// NewAppInput represents input for creating an application
@ -256,6 +271,17 @@ type UpdateAppInstanceInput struct {
AppInst AppInstance `json:"appinst"`
}
// DeleteAppInput represents input for deleting an application
type DeleteAppInput struct {
Key AppKey `json:"key"`
Region string `json:"region"`
}
// DeleteAppInstanceInput represents input for deleting an app instance
type DeleteAppInstanceInput struct {
Key AppInstanceKey `json:"key"`
}
// Response wrapper types
// Response wraps a single API response

View file

@ -3,8 +3,8 @@
kind: edgeconnect-deployment
metadata:
name: "edge-app-demo" # name could be used for appName
appVersion: "1.0.0"
organization: "edp2"
appVersion: "1"
organization: "edp2-orca"
spec:
# dockerApp: # Docker is OBSOLETE
# appVersion: "1.0.0"
@ -13,10 +13,10 @@ spec:
k8sApp:
manifestFile: "./k8s-deployment.yaml"
infraTemplate:
- region: "EU"
cloudletOrg: "TelekomOP"
cloudletName: "Munich"
flavorName: "EU.small"
- region: "US"
cloudletOrg: "TelekomOp"
cloudletName: "gardener-shepherd-test"
flavorName: "defualt"
network:
outboundConnections:
- protocol: "tcp"

View file

@ -32,7 +32,7 @@ spec:
volumes:
containers:
- name: edgeconnect-coder
image: nginx:latest
image: edp.buildth.ing/devfw-cicd/fibonacci_pipeline:edge_platform_demo
imagePullPolicy: Always
ports:
- containerPort: 80

View file

@ -98,10 +98,12 @@ func NewTransport(opts RetryOptions, auth AuthProvider, logger Logger) *Transpor
// Call executes an HTTP request with retry logic and returns typed response
func (t *Transport) Call(ctx context.Context, method, url string, body interface{}) (*http.Response, error) {
var reqBody io.Reader
var jsonData []byte
// Marshal request body if provided
if body != nil {
jsonData, err := json.Marshal(body)
var err error
jsonData, err = json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("failed to marshal request body: %w", err)
}
@ -127,8 +129,16 @@ func (t *Transport) Call(ctx context.Context, method, url string, body interface
// Log request
if t.logger != nil {
t.logger.Printf("HTTP %s %s", method, url)
t.logger.Printf("BODY %s", reqBody)
t.logger.Printf("=== HTTP REQUEST ===")
t.logger.Printf("%s %s", method, url)
if len(jsonData) > 0 {
var prettyJSON bytes.Buffer
if err := json.Indent(&prettyJSON, jsonData, "", " "); err == nil {
t.logger.Printf("Request Body:\n%s", prettyJSON.String())
} else {
t.logger.Printf("Request Body: %s", string(jsonData))
}
}
}
// Execute request
@ -139,7 +149,8 @@ func (t *Transport) Call(ctx context.Context, method, url string, body interface
// Log response
if t.logger != nil {
t.logger.Printf("HTTP %s %s -> %d", method, url, resp.StatusCode)
t.logger.Printf("=== HTTP RESPONSE ===")
t.logger.Printf("%s %s -> %d", method, url, resp.StatusCode)
}
return resp, nil