From 931800856fbeac2d31e806c49f71bb27c8abfce1 Mon Sep 17 00:00:00 2001 From: maastha <122359335+maastha@users.noreply.github.com> Date: Tue, 16 May 2023 15:03:40 +0100 Subject: [PATCH] INTMDB-802: Add Data Federation Query Limit (#475) --- mongodbatlas/data_federation.go | 128 ++++++++++++++++++++++- mongodbatlas/data_federation_test.go | 145 +++++++++++++++++++++++++++ 2 files changed, 272 insertions(+), 1 deletion(-) diff --git a/mongodbatlas/data_federation.go b/mongodbatlas/data_federation.go index 537611b96..fb725ef9a 100644 --- a/mongodbatlas/data_federation.go +++ b/mongodbatlas/data_federation.go @@ -21,7 +21,8 @@ import ( ) const ( - dataFederationBasePath = "api/atlas/v1.0/groups/%s/dataFederation" + dataFederationBasePath = "api/atlas/v1.0/groups/%s/dataFederation" + dataFederationQueryLimitBasePath = "api/atlas/v1.0/groups/%s/dataFederation/%s/limits" ) // DataFederationService is an interface for interfacing with the Data Federation endpoints of the MongoDB Atlas API. @@ -33,6 +34,10 @@ type DataFederationService interface { Create(context.Context, string, *DataFederationInstance) (*DataFederationInstance, *Response, error) Update(context.Context, string, string, *DataFederationInstance, *DataFederationUpdateOptions) (*DataFederationInstance, *Response, error) Delete(context.Context, string, string) (*Response, error) + ListQueryLimits(context.Context, string, string) ([]*DataFederationQueryLimit, *Response, error) + GetQueryLimit(context.Context, string, string, string) (*DataFederationQueryLimit, *Response, error) + ConfigureQueryLimit(context.Context, string, string, string, *DataFederationQueryLimit) (*DataFederationQueryLimit, *Response, error) + DeleteQueryLimit(context.Context, string, string, string) (*Response, error) } // DataFederationServiceOp handles communication with the DataFederationService related methods of the @@ -133,6 +138,18 @@ type DataFederationUpdateOptions struct { SkipRoleValidation bool `url:"skipRoleValidation"` } +// DataFederationQueryLimit Details of a tenant-level query limit for Data Federation. +type DataFederationQueryLimit struct { + CurrentUsage int64 `json:"currentUsage,omitempty"` + DefaultLimit int64 `json:"defaultLimit,omitempty"` + LastModifiedDate string `json:"lastModifiedDate,omitempty"` + MaximumLimit int64 `json:"maximumLimit,omitempty"` + Name string `json:"name,omitempty"` + OverrunPolicy string `json:"overrunPolicy,omitempty"` + TenantName string `json:"tenantName,omitempty"` + Value int64 `json:"value,omitempty"` +} + // List gets the details of all federated database instances in the specified project. // // See more: https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Data-Federation/operation/listFederatedDatabases @@ -276,3 +293,112 @@ func (s *DataFederationServiceOp) Delete(ctx context.Context, groupID, name stri return resp, err } + +// ConfigureQueryLimit Creates or updates one query limit for one federated database instance. +// +// See more: https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Data-Federation/operation/createOneDataFederationQueryLimit +func (s *DataFederationServiceOp) ConfigureQueryLimit(ctx context.Context, groupID, name, limitName string, queryLimit *DataFederationQueryLimit) (*DataFederationQueryLimit, *Response, error) { + if groupID == "" { + return nil, nil, NewArgError("groupID", "must be set") + } + if name == "" { + return nil, nil, NewArgError("name", "must be set") + } + if limitName == "" { + return nil, nil, NewArgError("limitName", "must be set") + } + if queryLimit == nil { + return nil, nil, NewArgError("queryLimit", "must be set") + } + + basePath := fmt.Sprintf(dataFederationQueryLimitBasePath, groupID, name) + path := fmt.Sprintf("%s/%s", basePath, limitName) + req, err := s.Client.NewRequest(ctx, http.MethodPatch, path, queryLimit) + if err != nil { + return nil, nil, err + } + + root := new(DataFederationQueryLimit) + resp, err := s.Client.Do(ctx, req, &root) + if err != nil { + return nil, resp, err + } + + return root, resp, err +} + +func (s *DataFederationServiceOp) DeleteQueryLimit(ctx context.Context, groupID, name, limitName string) (*Response, error) { + if groupID == "" { + return nil, NewArgError("groupId", "must be set") + } + if name == "" { + return nil, NewArgError("name", "must be set") + } + if limitName == "" { + return nil, NewArgError("limitName", "must be set") + } + + basePath := fmt.Sprintf(dataFederationQueryLimitBasePath, groupID, name) + path := fmt.Sprintf("%s/%s", basePath, limitName) + + req, err := s.Client.NewRequest(ctx, http.MethodDelete, path, nil) + if err != nil { + return nil, err + } + + resp, err := s.Client.Do(ctx, req, nil) + + return resp, err +} + +func (s *DataFederationServiceOp) GetQueryLimit(ctx context.Context, groupID, name, limitName string) (*DataFederationQueryLimit, *Response, error) { + if groupID == "" { + return nil, nil, NewArgError("groupID", "must be set") + } + if name == "" { + return nil, nil, NewArgError("name", "must be set") + } + if limitName == "" { + return nil, nil, NewArgError("limitName", "must be set") + } + + basePath := fmt.Sprintf(dataFederationQueryLimitBasePath, groupID, name) + path := fmt.Sprintf("%s/%s", basePath, limitName) + + req, err := s.Client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + root := new(DataFederationQueryLimit) + resp, err := s.Client.Do(ctx, req, &root) + if err != nil { + return nil, resp, err + } + + return root, resp, err +} + +func (s *DataFederationServiceOp) ListQueryLimits(ctx context.Context, groupID, name string) ([]*DataFederationQueryLimit, *Response, error) { + if groupID == "" { + return nil, nil, NewArgError("groupID", "must be set") + } + if name == "" { + return nil, nil, NewArgError("name", "must be set") + } + + path := fmt.Sprintf(dataFederationQueryLimitBasePath, groupID, name) + + req, err := s.Client.NewRequest(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, nil, err + } + + var root []*DataFederationQueryLimit + resp, err := s.Client.Do(ctx, req, &root) + if err != nil { + return nil, resp, err + } + + return root, resp, err +} diff --git a/mongodbatlas/data_federation_test.go b/mongodbatlas/data_federation_test.go index 3f6325bdb..b3456c5f1 100644 --- a/mongodbatlas/data_federation_test.go +++ b/mongodbatlas/data_federation_test.go @@ -767,3 +767,148 @@ func TestDataFederation_Delete(t *testing.T) { t.Fatalf("DataFederation.Delete returned error: %v", err) } } + +func TestDataFederationQueryLimit_List(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + groupID := "6c7498dg87d9e6526801572b" + tenantName := "TestInstance" + + path := fmt.Sprintf("/api/atlas/v1.0/groups/%s/dataFederation/%s/limits", groupID, tenantName) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + fmt.Fprint(w, `[{ + "currentUsage": 0, + "lastModifiedDate": "2023-05-12T10:41:03Z", + "name": "bytesProcessed.daily", + "overrunPolicy": "BLOCK", + "tenantName": "TestInstance", + "value": 2147483648 + }]`) + }) + + dataFederationQueryLimits, _, err := client.DataFederation.ListQueryLimits(ctx, groupID, tenantName) + if err != nil { + t.Fatalf("DataFederation.ListQueryLimit returned error: %v", err) + } + + expected := []*DataFederationQueryLimit{ + { + CurrentUsage: 0, + LastModifiedDate: "2023-05-12T10:41:03Z", + Name: "bytesProcessed.daily", + OverrunPolicy: "BLOCK", + TenantName: "TestInstance", + Value: 2147483648, + }, + } + + if diff := deep.Equal(dataFederationQueryLimits, expected); diff != nil { + t.Error(diff) + } +} + +func TestDataFederationQueryLimit_Get(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + groupID := "6c7498dg87d9e6526801572b" + tenantName := "TestInstance" + limitName := "bytesProcessed.daily" + + path := fmt.Sprintf("/api/atlas/v1.0/groups/%s/dataFederation/%s/limits/%s", groupID, tenantName, limitName) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + fmt.Fprint(w, `{ + "currentUsage": 0, + "lastModifiedDate": "2023-05-12T10:41:03Z", + "name": "bytesProcessed.daily", + "overrunPolicy": "BLOCK", + "tenantName": "TestInstance", + "value": 2147483648 + }`) + }) + + dataFederationQueryLimits, _, err := client.DataFederation.GetQueryLimit(ctx, groupID, tenantName, limitName) + if err != nil { + t.Fatalf("DataFederation.GetQueryLimit returned error: %v", err) + } + + expected := DataFederationQueryLimit{ + CurrentUsage: 0, + LastModifiedDate: "2023-05-12T10:41:03Z", + Name: "bytesProcessed.daily", + OverrunPolicy: "BLOCK", + TenantName: "TestInstance", + Value: 2147483648, + } + + if diff := deep.Equal(*dataFederationQueryLimits, expected); diff != nil { + t.Error(diff) + } +} + +func TestDataFederation_Configure(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + groupID := "6c7498dg87d9e6526801572b" + tenantName := "TestInstance" + limitName := "bytesProcessed.daily" + + path := fmt.Sprintf("/api/atlas/v1.0/groups/%s/dataFederation/%s/limits/%s", groupID, tenantName, limitName) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPatch) + fmt.Fprint(w, `{ + "currentUsage": 0, + "lastModifiedDate": "2023-05-12T10:41:03Z", + "name": "bytesProcessed.daily", + "overrunPolicy": "BLOCK", + "tenantName": "TestInstance", + "value": 2147483648 + }`) + }) + + requestBody := &DataFederationQueryLimit{OverrunPolicy: "BLOCK", Value: 2147483648} + dataFederationQueryLimit, _, err := client.DataFederation.ConfigureQueryLimit(ctx, groupID, tenantName, limitName, requestBody) + if err != nil { + t.Fatalf("DataFederation.ConfigureQueryLimit returned error: %v", err) + } + + expected := DataFederationQueryLimit{ + CurrentUsage: 0, + LastModifiedDate: "2023-05-12T10:41:03Z", + Name: "bytesProcessed.daily", + OverrunPolicy: "BLOCK", + TenantName: "TestInstance", + Value: 2147483648, + } + + if diff := deep.Equal(*dataFederationQueryLimit, expected); diff != nil { + t.Error(diff) + } +} + +func TestDataFederationQueryLimit_Delete(t *testing.T) { + client, mux, teardown := setup() + defer teardown() + + groupID := "6c7498dg87d9e6526801572b" + tenantName := "TestInstance" + limitName := "bytesProcessed.daily" + + path := fmt.Sprintf("/api/atlas/v1.0/groups/%s/dataFederation/%s/limits/%s", groupID, tenantName, limitName) + + mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodDelete) + }) + + _, err := client.DataFederation.DeleteQueryLimit(ctx, groupID, tenantName, limitName) + if err != nil { + t.Fatalf("DataFederation.DeleteQueryLimit returned error: %v", err) + } +}