Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@
- **Bugfix**: **Dependencies:** Bump STACKIT SDK core module from `v0.24.1` to `v0.25.0`
- [v1.8.3](services/mongodbflex/CHANGELOG.md#v183)
- **Dependencies:** Bump STACKIT SDK core module from `v0.25.0` to `v0.26.0`
- [v1.9.0](services/mongodbflex/CHANGELOG.md#v190)
- **Improvement:** Use new WaiterHelper for mongodbflex
- `objectstorage`:
- [v1.7.2](services/objectstorage/CHANGELOG.md#v172)
- **Dependencies:** Bump STACKIT SDK core module from `v0.24.0` to `v0.24.1`
Expand Down
3 changes: 3 additions & 0 deletions services/mongodbflex/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## v1.9.0
- **Improvement:** Use new WaiterHelper for mongodbflex

## v1.8.3
- **Dependencies:** Bump STACKIT SDK core module from `v0.25.0` to `v0.26.0`

Expand Down
2 changes: 1 addition & 1 deletion services/mongodbflex/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.8.3
v1.9.0
180 changes: 80 additions & 100 deletions services/mongodbflex/v2api/wait/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package wait

import (
"context"
"fmt"
"net/http"
"errors"
"sort"
"time"

"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
"github.com/stackitcloud/stackit-sdk-go/core/wait"
mongodbflex "github.com/stackitcloud/stackit-sdk-go/services/mongodbflex/v2api"
)
Expand All @@ -27,29 +25,15 @@ const (

// CreateInstanceWaitHandler will wait for instance creation
func CreateInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[mongodbflex.InstanceResponse] {
handler := wait.New(func() (waitFinished bool, response *mongodbflex.InstanceResponse, err error) {
s, err := a.GetInstance(ctx, projectId, instanceId, region).Execute()
if err != nil {
return false, nil, err
}
if s == nil || s.Item == nil || s.Item.Id == nil || *s.Item.Id != instanceId || s.Item.Status == nil {
return false, nil, nil
}
switch *s.Item.Status {
default:
return true, s, fmt.Errorf("instance with id %s has unexpected status %s", instanceId, *s.Item.Status)
case "":
return false, nil, nil
case INSTANCESTATUS_PROCESSING:
return false, nil, nil
case INSTANCESTATUS_UNKNOWN:
return false, nil, nil
case INSTANCESTATUS_READY:
return true, s, nil
case INSTANCESTATUS_FAILED:
return true, s, fmt.Errorf("create failed for instance with id %s", instanceId)
}
})
waitConfig := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{
FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute,
GetState: getStateInstance,
ActiveState: []string{INSTANCESTATUS_READY},
ErrorState: []string{INSTANCESTATUS_FAILED},
}

handler := wait.New(waitConfig.Wait())

handler.SetTimeout(45 * time.Minute)
handler.SetSleepBeforeWait(5 * time.Second)
return handler
Expand All @@ -61,74 +45,53 @@ func CloneInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, pro
}

func RestoreInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, backupId, region string) *wait.AsyncActionHandler[mongodbflex.ListRestoreJobsResponse] {
handler := wait.New(func() (waitFinished bool, response *mongodbflex.ListRestoreJobsResponse, err error) {
s, err := a.ListRestoreJobs(ctx, projectId, instanceId, region).Execute()
if err != nil {
return false, nil, err
}
if s == nil || s.Items == nil {
return false, nil, nil
}

restoreJobsSlice := s.Items

// sort array by descending date
sort.Slice(restoreJobsSlice, func(i, j int) bool {
// swap elements to sort by descending order
return *restoreJobsSlice[i].Date > *restoreJobsSlice[j].Date
})

var status string
for _, restoreJob := range restoreJobsSlice {
if *restoreJob.BackupID == backupId {
status = *restoreJob.Status
break
waitConfig := wait.WaiterHelper[mongodbflex.ListRestoreJobsResponse, string]{
FetchInstance: a.ListRestoreJobs(ctx, projectId, instanceId, region).Execute,
GetState: func(response *mongodbflex.ListRestoreJobsResponse) (string, error) {
if response == nil {
return "", errors.New("response is nil")
}
}

switch status {
default:
return true, s, fmt.Errorf("restore job for backup with id %s has unexpected status %s", backupId, status)
case RestoreJobProcessing:
return false, nil, nil
case RestoreJobFinished:
return true, s, nil
case RestoreJobBroken:
return true, s, fmt.Errorf("restore job for backup with id %s is broken", backupId)
case RestoreJobKilled:
return true, s, fmt.Errorf("restore job for backup with id %s was killed", backupId)
}
})
if len(response.Items) == 0 {
return "", errors.New("response items is empty")
}
restoreJobsSlice := response.Items
// sort array by descending date
sort.Slice(restoreJobsSlice, func(i, j int) bool {
// swap elements to sort by descending order
return *restoreJobsSlice[i].Date > *restoreJobsSlice[j].Date
})

var status string
for _, restoreJob := range restoreJobsSlice {
if *restoreJob.BackupID == backupId {
status = *restoreJob.Status
break
}
}
return status, nil
},
ActiveState: []string{RestoreJobFinished},
ErrorState: []string{RestoreJobKilled, RestoreJobBroken},
}

handler := wait.New(waitConfig.Wait())

handler.SetTimeout(45 * time.Minute)
handler.SetSleepBeforeWait(5 * time.Second)
return handler
}

// UpdateInstanceWaitHandler will wait for instance update
func UpdateInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[mongodbflex.InstanceResponse] {
handler := wait.New(func() (waitFinished bool, response *mongodbflex.InstanceResponse, err error) {
s, err := a.GetInstance(ctx, projectId, instanceId, region).Execute()
if err != nil {
return false, nil, err
}
if s == nil || s.Item == nil || s.Item.Id == nil || *s.Item.Id != instanceId || s.Item.Status == nil {
return false, nil, nil
}
switch *s.Item.Status {
default:
return true, s, fmt.Errorf("instance with id %s has unexpected status %s", instanceId, *s.Item.Status)
case "":
return false, nil, nil
case INSTANCESTATUS_PROCESSING:
return false, nil, nil
case INSTANCESTATUS_UNKNOWN:
return false, nil, nil
case INSTANCESTATUS_READY:
return true, s, nil
case INSTANCESTATUS_FAILED:
return true, s, fmt.Errorf("update failed for instance with id %s", instanceId)
}
})
waitConfig := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{
FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute,
GetState: getStateInstance,
ActiveState: []string{INSTANCESTATUS_READY},
ErrorState: []string{INSTANCESTATUS_FAILED},
}

handler := wait.New(waitConfig.Wait())

handler.SetTimeout(45 * time.Minute)
return handler
}
Expand All @@ -140,20 +103,37 @@ func PartialUpdateInstanceWaitHandler(ctx context.Context, a mongodbflex.Default

// DeleteInstanceWaitHandler will wait for instance deletion
func DeleteInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[struct{}] {
handler := wait.New(func() (waitFinished bool, response *struct{}, err error) {
_, err = a.GetInstance(ctx, projectId, instanceId, region).Execute()
if err == nil {
return false, nil, nil
}
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
if !ok {
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
}
if oapiErr.StatusCode != http.StatusNotFound {
return false, nil, err
}
return true, nil, nil
})
w := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{
FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute,
GetState: getStateInstance,
ActiveState: []string{},
ErrorState: []string{INSTANCESTATUS_FAILED},
}

// adapter for adhering to the wait helper type schema
genericCheck := w.Wait()
adaptedCheck := func() (waitFinished bool, response *struct{}, err error) {
finished, _, err := genericCheck()
return finished, nil, err
}

handler := wait.New(adaptedCheck)
handler.SetTimeout(15 * time.Minute)
return handler
}

func getStateInstance(response *mongodbflex.InstanceResponse) (string, error) {
if response == nil {
return "", errors.New("empty response")
}
if response.Item == nil {
return "", errors.New("empty items")
}
if response.Item.Id == nil {
return "", errors.New("empty item id")
}
if response.Item.Status == nil {
return "", errors.New("empty item status")
}
return *response.Item.Status, nil
}
Loading