From a8cfe26e91bab83f7400c098e9bb10a8dbf9307c Mon Sep 17 00:00:00 2001 From: Antony Natale Date: Thu, 23 May 2024 19:07:29 +0000 Subject: [PATCH] removes bool in favor of custom error type --- frontend/database.go | 33 +++++++++--------- frontend/frontend.go | 79 +++++++++++++++++++++++++++----------------- 2 files changed, 64 insertions(+), 48 deletions(-) diff --git a/frontend/database.go b/frontend/database.go index d38cd4733..9e8431f92 100644 --- a/frontend/database.go +++ b/frontend/database.go @@ -3,7 +3,7 @@ package main import ( "context" "encoding/json" - "fmt" + "errors" "os" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" @@ -17,6 +17,8 @@ const ( asyncContainer = "AsyncOperations" ) +var ErrNotFound = errors.New("DocumentNotFound") + // DBClient defines the needed values to perform CRUD operations against the async DB type DBClient struct { client *azcosmos.Client @@ -79,10 +81,10 @@ func (d *DBClient) DBConnectionTest(ctx context.Context) (string, error) { } // GetClusterDoc retreives a cluster document from async DB using resource ID -func (d *DBClient) GetClusterDoc(ctx context.Context, resourceID string, partitionKey string) (*HCPOpenShiftClusterDocument, bool, error) { +func (d *DBClient) GetClusterDoc(ctx context.Context, resourceID string, partitionKey string) (*HCPOpenShiftClusterDocument, error) { container, err := d.client.NewContainer(d.config.DBName, clustersContainer) if err != nil { - return nil, false, err + return nil, err } query := "SELECT * FROM c WHERE c.key = @key" @@ -98,20 +100,20 @@ func (d *DBClient) GetClusterDoc(ctx context.Context, resourceID string, partiti for queryPager.More() { queryResponse, err := queryPager.NextPage(ctx) if err != nil { - return nil, false, err + return nil, err } for _, item := range queryResponse.Items { err = json.Unmarshal(item, &doc) if err != nil { - return nil, false, err + return nil, err } } } if doc != nil { - return doc, true, nil + return doc, nil } - return nil, false, nil + return nil, ErrNotFound } // SetClusterDoc creates/updates a cluster document in the async DB during cluster creation/patching @@ -136,10 +138,7 @@ func (d *DBClient) SetClusterDoc(ctx context.Context, doc *HCPOpenShiftClusterDo // DeleteClusterDoc removes a cluter document from the async DB using resource ID func (d *DBClient) DeleteClusterDoc(ctx context.Context, resourceID string, partitionKey string) error { - doc, found, err := d.GetClusterDoc(ctx, resourceID, partitionKey) - if !found { - return fmt.Errorf("document with key %s not found", partitionKey) - } + doc, err := d.GetClusterDoc(ctx, resourceID, partitionKey) if err != nil { return err } @@ -157,10 +156,10 @@ func (d *DBClient) DeleteClusterDoc(ctx context.Context, resourceID string, part } // GetSubscriptionDoc retreives a subscription document from async DB using the subscription ID -func (d *DBClient) GetSubscriptionDoc(ctx context.Context, partitionKey string) (*SubscriptionDocument, bool, error) { +func (d *DBClient) GetSubscriptionDoc(ctx context.Context, partitionKey string) (*SubscriptionDocument, error) { container, err := d.client.NewContainer(d.config.DBName, subsContainer) if err != nil { - return nil, false, err + return nil, err } query := "SELECT * FROM c WHERE c.partitionKey = @partitionKey" @@ -176,20 +175,20 @@ func (d *DBClient) GetSubscriptionDoc(ctx context.Context, partitionKey string) for queryPager.More() { queryResponse, err := queryPager.NextPage(ctx) if err != nil { - return nil, false, err + return nil, err } for _, item := range queryResponse.Items { err = json.Unmarshal(item, &doc) if err != nil { - return nil, false, err + return nil, err } } } if doc != nil { - return doc, true, nil + return doc, nil } - return nil, false, nil + return nil, ErrNotFound } // SetClusterDoc creates/updates a subscription document in the async DB during cluster creation/patching diff --git a/frontend/frontend.go b/frontend/frontend.go index ac4384b4c..41cf42617 100644 --- a/frontend/frontend.go +++ b/frontend/frontend.go @@ -6,6 +6,7 @@ package main import ( "context" "encoding/json" + "errors" "fmt" "log/slog" "net" @@ -312,21 +313,23 @@ func (f *Frontend) ArmResourceCreateOrUpdate(writer http.ResponseWriter, request parsed, _ := azure.ParseResourceID(resourceID) var doc *HCPOpenShiftClusterDocument - doc, found, err := f.dbClient.GetClusterDoc(ctx, resourceID, parsed.SubscriptionID) + doc, err = f.dbClient.GetClusterDoc(ctx, resourceID, parsed.SubscriptionID) if err != nil { - f.logger.Error("failed to fetch document for %s: %v", resourceID, err) - arm.WriteInternalServerError(writer) - return - } - if !found { - f.logger.Info(fmt.Sprintf("existing document not found for cluster - creating one for %s", resourceID)) - doc = &HCPOpenShiftClusterDocument{ - ID: uuid.New().String(), - Key: resourceID, - ClusterID: NewUID(), - PartitionKey: parsed.SubscriptionID, + if errors.Is(err, ErrNotFound) { + f.logger.Info(fmt.Sprintf("existing document not found for cluster - creating one for %s", resourceID)) + doc = &HCPOpenShiftClusterDocument{ + ID: uuid.New().String(), + Key: resourceID, + ClusterID: NewUID(), + PartitionKey: parsed.SubscriptionID, + } + } else { + f.logger.Error("failed to fetch document for %s: %v", resourceID, err) + arm.WriteInternalServerError(writer) + return } } + err = f.dbClient.SetClusterDoc(ctx, doc) if err != nil { f.logger.Error("failed to create document for resource %s: %v", resourceID, err) @@ -388,9 +391,15 @@ func (f *Frontend) ArmResourceDelete(writer http.ResponseWriter, request *http.R parsed, _ := azure.ParseResourceID(resourceID) err = f.dbClient.DeleteClusterDoc(ctx, resourceID, parsed.SubscriptionID) if err != nil { - f.logger.Error(err.Error()) - arm.WriteInternalServerError(writer) - return + if errors.Is(err, ErrNotFound) { + f.logger.Info(fmt.Sprintf("cluster document cannot be deleted -- document not found for %s", resourceID)) + writer.WriteHeader(http.StatusNoContent) + return + } else { + f.logger.Error(err.Error()) + arm.WriteInternalServerError(writer) + return + } } f.logger.Info(fmt.Sprintf("document deleted for resource %s", resourceID)) @@ -416,12 +425,17 @@ func (f *Frontend) ArmSubscriptionGet(writer http.ResponseWriter, request *http. ctx := request.Context() subId := request.PathValue(PathSegmentSubscriptionID) - doc, found, err := f.dbClient.GetSubscriptionDoc(ctx, subId) + doc, err := f.dbClient.GetSubscriptionDoc(ctx, subId) if err != nil { - f.logger.Error("failed to get document for subscription %s: %v", subId, err) - } - if !found { - f.logger.Error(fmt.Sprintf("document not found for subscription %s", subId)) + if errors.Is(err, ErrNotFound) { + f.logger.Error(fmt.Sprintf("document not found for subscription %s", subId)) + writer.WriteHeader(http.StatusNotFound) + return + } else { + f.logger.Error(err.Error()) + writer.WriteHeader(http.StatusInternalServerError) + return + } } resp, err := json.Marshal(&doc) @@ -460,22 +474,25 @@ func (f *Frontend) ArmSubscriptionPut(writer http.ResponseWriter, request *http. f.cache.SetSubscription(subId, &subscription) var doc *SubscriptionDocument - doc, found, err := f.dbClient.GetSubscriptionDoc(ctx, subId) + doc, err = f.dbClient.GetSubscriptionDoc(ctx, subId) if err != nil { - f.logger.Error("failed to fetch document for %s: %v", subId, err) - arm.WriteInternalServerError(writer) - return - } - if !found { - f.logger.Info(fmt.Sprintf("existing document not found for subscription - creating one for %s", subId)) - doc = &SubscriptionDocument{ - ID: uuid.New().String(), - PartitionKey: subId, - Subscription: &subscription, + if errors.Is(err, ErrNotFound) { + f.logger.Info(fmt.Sprintf("existing document not found for subscription - creating one for %s", subId)) + doc = &SubscriptionDocument{ + ID: uuid.New().String(), + PartitionKey: subId, + Subscription: &subscription, + } + } else { + f.logger.Error("failed to fetch document for %s: %v", subId, err) + arm.WriteInternalServerError(writer) + return } } else { + f.logger.Info(fmt.Sprintf("existing document found for subscription - will update document for subscription %s", subId)) doc.Subscription = &subscription } + err = f.dbClient.SetSubscriptionDoc(ctx, doc) if err != nil { f.logger.Error("failed to create document for subscription %s: %v", subId, err)