From dd931d8ecc834e34b9778de8de16d1390f6ca33e Mon Sep 17 00:00:00 2001 From: Jan Obernberger Date: Mon, 18 May 2026 09:51:47 +0200 Subject: [PATCH 1/7] feat(mongodbflex): refactored and tested mongodbflex wait handler to use wait helper. TODO: test acceptance tests when API Issue is fixed --- services/mongodbflex/v2api/wait/wait.go | 114 +++++++++++------------- 1 file changed, 54 insertions(+), 60 deletions(-) diff --git a/services/mongodbflex/v2api/wait/wait.go b/services/mongodbflex/v2api/wait/wait.go index 932de4fd4..5bd37d7f0 100644 --- a/services/mongodbflex/v2api/wait/wait.go +++ b/services/mongodbflex/v2api/wait/wait.go @@ -2,12 +2,11 @@ package wait import ( "context" + "errors" "fmt" - "net/http" "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" ) @@ -27,29 +26,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, region, instanceId).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 @@ -106,29 +91,15 @@ func RestoreInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, p // 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, region, instanceId).Execute, + GetState: getStateInstance, + ActiveState: []string{INSTANCESTATUS_READY}, + ErrorState: []string{INSTANCESTATUS_FAILED}, + } + + handler := wait.New(waitConfig.Wait()) + handler.SetTimeout(45 * time.Minute) return handler } @@ -140,20 +111,43 @@ 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") + w := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{ + FetchInstance: a.GetInstance(ctx, projectId, region, instanceId).Execute, + GetState: getStateInstance, + ActiveState: []string{}, + ErrorState: []string{}, + } + + // adapter for adhering to the wait helper type schema + genericCheck := w.Wait() + adaptedCheck := func() (waitFinished bool, response *struct{}, err error) { + finished, _, err := genericCheck() + if err != nil { + return finished, nil, err } - if oapiErr.StatusCode != http.StatusNotFound { - return false, nil, err + if finished { + return true, nil, nil } - return true, nil, nil - }) + return false, nil, nil + } + + 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("emtpy items") + } + if response.Item.Id == nil { + return "", errors.New("emtpy item id") + } + if response.Item.Status == nil { + return "", errors.New("emtpy item status") + } + return *response.Item.Status, nil +} From 4976198a2bd5e39770cf17bed6185328c42fa96b Mon Sep 17 00:00:00 2001 From: Jan Obernberger Date: Mon, 18 May 2026 10:20:57 +0200 Subject: [PATCH 2/7] feat(mongodbflex): flatted adapter function --- services/mongodbflex/v2api/wait/wait.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/services/mongodbflex/v2api/wait/wait.go b/services/mongodbflex/v2api/wait/wait.go index 5bd37d7f0..de052f2e6 100644 --- a/services/mongodbflex/v2api/wait/wait.go +++ b/services/mongodbflex/v2api/wait/wait.go @@ -122,13 +122,7 @@ func DeleteInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, pr genericCheck := w.Wait() adaptedCheck := func() (waitFinished bool, response *struct{}, err error) { finished, _, err := genericCheck() - if err != nil { - return finished, nil, err - } - if finished { - return true, nil, nil - } - return false, nil, nil + return finished, nil, err } handler := wait.New(adaptedCheck) From 2263b85d7ac942b86c3d17918fe680c656281cd3 Mon Sep 17 00:00:00 2001 From: Jan Obernberger Date: Mon, 18 May 2026 11:43:38 +0200 Subject: [PATCH 3/7] fix(mongodbflex): ordered parameters for fetch function correctly --- services/mongodbflex/v2api/wait/wait.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/mongodbflex/v2api/wait/wait.go b/services/mongodbflex/v2api/wait/wait.go index de052f2e6..a5656500a 100644 --- a/services/mongodbflex/v2api/wait/wait.go +++ b/services/mongodbflex/v2api/wait/wait.go @@ -27,7 +27,7 @@ const ( // CreateInstanceWaitHandler will wait for instance creation func CreateInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[mongodbflex.InstanceResponse] { waitConfig := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{ - FetchInstance: a.GetInstance(ctx, projectId, region, instanceId).Execute, + FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute, GetState: getStateInstance, ActiveState: []string{INSTANCESTATUS_READY}, ErrorState: []string{INSTANCESTATUS_FAILED}, @@ -92,7 +92,7 @@ func RestoreInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, p // UpdateInstanceWaitHandler will wait for instance update func UpdateInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, projectId, instanceId, region string) *wait.AsyncActionHandler[mongodbflex.InstanceResponse] { waitConfig := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{ - FetchInstance: a.GetInstance(ctx, projectId, region, instanceId).Execute, + FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute, GetState: getStateInstance, ActiveState: []string{INSTANCESTATUS_READY}, ErrorState: []string{INSTANCESTATUS_FAILED}, @@ -112,7 +112,7 @@ 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{}] { w := wait.WaiterHelper[mongodbflex.InstanceResponse, string]{ - FetchInstance: a.GetInstance(ctx, projectId, region, instanceId).Execute, + FetchInstance: a.GetInstance(ctx, projectId, instanceId, region).Execute, GetState: getStateInstance, ActiveState: []string{}, ErrorState: []string{}, From aa70238473b9b4fd5f2ac1df9f4110f6f650ccea Mon Sep 17 00:00:00 2001 From: Jan Obernberger Date: Mon, 18 May 2026 12:26:43 +0200 Subject: [PATCH 4/7] feature(mongodbflex): adapted wait restore handler to use new wait helper --- services/mongodbflex/v2api/wait/wait.go | 66 +++++++++++-------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/services/mongodbflex/v2api/wait/wait.go b/services/mongodbflex/v2api/wait/wait.go index a5656500a..3ff908fcd 100644 --- a/services/mongodbflex/v2api/wait/wait.go +++ b/services/mongodbflex/v2api/wait/wait.go @@ -3,7 +3,6 @@ package wait import ( "context" "errors" - "fmt" "sort" "time" @@ -46,44 +45,35 @@ 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 + }, + } + + handler := wait.New(waitConfig.Wait()) + handler.SetTimeout(45 * time.Minute) handler.SetSleepBeforeWait(5 * time.Second) return handler From 1e2fe0c2fa9d3bd2061348609de333754134a755 Mon Sep 17 00:00:00 2001 From: Jan Obernberger Date: Mon, 18 May 2026 13:39:47 +0200 Subject: [PATCH 5/7] feature(mongodbflex): added missing states in RestoreInstanceWaitHandler --- services/mongodbflex/v2api/wait/wait.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/mongodbflex/v2api/wait/wait.go b/services/mongodbflex/v2api/wait/wait.go index 3ff908fcd..7e11fc20e 100644 --- a/services/mongodbflex/v2api/wait/wait.go +++ b/services/mongodbflex/v2api/wait/wait.go @@ -70,6 +70,8 @@ func RestoreInstanceWaitHandler(ctx context.Context, a mongodbflex.DefaultAPI, p } return status, nil }, + ActiveState: []string{RestoreJobFinished}, + ErrorState: []string{RestoreJobKilled, RestoreJobBroken}, } handler := wait.New(waitConfig.Wait()) From 5cccde1be9e7942042704d3b3a13599b2faff9cd Mon Sep 17 00:00:00 2001 From: Jan Obernberger Date: Mon, 18 May 2026 13:49:12 +0200 Subject: [PATCH 6/7] fix(mongodbflex): fixed linter issues and wrote CHANGELOG.md --- CHANGELOG.md | 2 ++ services/mongodbflex/CHANGELOG.md | 3 +++ services/mongodbflex/VERSION | 2 +- services/mongodbflex/v2api/wait/wait.go | 6 +++--- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5558bbc75..07406a594 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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#v183) + - **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` diff --git a/services/mongodbflex/CHANGELOG.md b/services/mongodbflex/CHANGELOG.md index 0842a68b1..2f537c208 100644 --- a/services/mongodbflex/CHANGELOG.md +++ b/services/mongodbflex/CHANGELOG.md @@ -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` diff --git a/services/mongodbflex/VERSION b/services/mongodbflex/VERSION index 25b56915a..e2f650c40 100644 --- a/services/mongodbflex/VERSION +++ b/services/mongodbflex/VERSION @@ -1 +1 @@ -v1.8.3 \ No newline at end of file +v1.9.0 \ No newline at end of file diff --git a/services/mongodbflex/v2api/wait/wait.go b/services/mongodbflex/v2api/wait/wait.go index 7e11fc20e..81a70b099 100644 --- a/services/mongodbflex/v2api/wait/wait.go +++ b/services/mongodbflex/v2api/wait/wait.go @@ -127,13 +127,13 @@ func getStateInstance(response *mongodbflex.InstanceResponse) (string, error) { return "", errors.New("empty response") } if response.Item == nil { - return "", errors.New("emtpy items") + return "", errors.New("empty items") } if response.Item.Id == nil { - return "", errors.New("emtpy item id") + return "", errors.New("empty item id") } if response.Item.Status == nil { - return "", errors.New("emtpy item status") + return "", errors.New("empty item status") } return *response.Item.Status, nil } From 5fffa98d685f6484946acd1f0e445b14d41aef9f Mon Sep 17 00:00:00 2001 From: Jan Obernberger Date: Mon, 18 May 2026 14:04:00 +0200 Subject: [PATCH 7/7] fix(mongodbflex): fixed link in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07406a594..8b01be99a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -230,7 +230,7 @@ - **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#v183) + - [v1.9.0](services/mongodbflex/CHANGELOG.md#v190) - **Improvement:** Use new WaiterHelper for mongodbflex - `objectstorage`: - [v1.7.2](services/objectstorage/CHANGELOG.md#v172)