Skip to content

Commit

Permalink
Swift: Add "bulk-delete" URL argument support for container
Browse files Browse the repository at this point in the history
  • Loading branch information
kayrus committed Apr 11, 2020
1 parent 8fc29ba commit 07cf4b8
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 4 deletions.
48 changes: 45 additions & 3 deletions openstack/objectstorage/v1/containers/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,43 @@ func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsB
return
}

// DeleteOptsBuilder allows extensions to add additional parameters to the
// Delete request.
type DeleteOptsBuilder interface {
ToContainerDeleteQuery() (string, error)
}

// DeleteOpts is a structure that holds parameters for deleting a container.
type DeleteOpts struct {
BulkDelete bool `q:"bulk-delete"`
}

// ToContainerDeleteQuery formats a DeleteOpts into a query string.
func (opts DeleteOpts) ToContainerDeleteQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
}

// Delete is a function that deletes a container.
func Delete(c *gophercloud.ServiceClient, containerName string) (r DeleteResult) {
_, r.Err = c.Delete(deleteURL(c, containerName), nil)
func Delete(c *gophercloud.ServiceClient, containerName string, opts DeleteOptsBuilder) (r DeleteResult) {
url := deleteURL(c, containerName)
if opts != nil {
query, err := opts.ToContainerDeleteQuery()
if err != nil {
r.Err = err
return
}
url += query
}
_, r.Err = c.Delete(url, nil)
return
}

// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToContainerUpdateMap() (map[string]string, error)
ToContainerUpdateQuery() (string, error)
}

// UpdateOpts is a structure that holds parameters for updating, creating, or
Expand All @@ -145,6 +172,7 @@ type UpdateOpts struct {
HistoryLocation string `h:"X-History-Location"`
TempURLKey string `h:"X-Container-Meta-Temp-URL-Key"`
TempURLKey2 string `h:"X-Container-Meta-Temp-URL-Key-2"`
BulkDelete bool `q:"bulk-delete"`
}

// ToContainerUpdateMap formats a UpdateOpts into a map of headers.
Expand All @@ -165,11 +193,25 @@ func (opts UpdateOpts) ToContainerUpdateMap() (map[string]string, error) {
return h, nil
}

// ToContainerUpdateQuery formats a UpdateOpts into a query string.
func (opts UpdateOpts) ToContainerUpdateQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
return q.String(), err
}

// Update is a function that creates, updates, or deletes a container's
// metadata.
func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsBuilder) (r UpdateResult) {
url := updateURL(c, containerName)
h := make(map[string]string)
if opts != nil {
query, err := opts.ToContainerUpdateQuery()
if err != nil {
r.Err = err
return
}
url += query

headers, err := opts.ToContainerUpdateMap()
if err != nil {
r.Err = err
Expand All @@ -180,7 +222,7 @@ func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsB
h[k] = v
}
}
resp, err := c.Request("POST", updateURL(c, containerName), &gophercloud.RequestOpts{
resp, err := c.Request("POST", url, &gophercloud.RequestOpts{
MoreHeaders: h,
OkCodes: []int{201, 202, 204},
})
Expand Down
34 changes: 34 additions & 0 deletions openstack/objectstorage/v1/containers/testing/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ func HandleDeleteContainerSuccessfully(t *testing.T) {
th.TestMethod(t, r, "DELETE")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Accept", "application/json")
th.TestFormValues(t, r, map[string]string{})

w.WriteHeader(http.StatusNoContent)
})
}

// HandleDeleteContainerWithOptsSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that
// responds with a `Delete` response.
func HandleDeleteContainerWithOptsSuccessfully(t *testing.T) {
th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "DELETE")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Accept", "application/json")
th.TestFormValues(t, r, map[string]string{
"bulk-delete": "true",
})

w.WriteHeader(http.StatusNoContent)
})
}
Expand All @@ -129,6 +146,23 @@ func HandleUpdateContainerSuccessfully(t *testing.T) {
th.TestMethod(t, r, "POST")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Accept", "application/json")
th.TestFormValues(t, r, map[string]string{})

w.WriteHeader(http.StatusNoContent)
})
}

// HandleUpdateContainerBulkDeleteSuccessfully creates an HTTP handler at `/testContainer` on the test handler mux that
// responds with a `Update` response.
func HandleUpdateContainerBulkDeleteSuccessfully(t *testing.T) {
th.Mux.HandleFunc("/testContainer", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "POST")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "Accept", "application/json")
th.TestFormValues(t, r, map[string]string{
"bulk-delete": "true",
})

w.WriteHeader(http.StatusNoContent)
})
}
Expand Down
24 changes: 23 additions & 1 deletion openstack/objectstorage/v1/containers/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,19 @@ func TestDeleteContainer(t *testing.T) {
defer th.TeardownHTTP()
HandleDeleteContainerSuccessfully(t)

res := containers.Delete(fake.ServiceClient(), "testContainer")
res := containers.Delete(fake.ServiceClient(), "testContainer", nil)
th.CheckNoErr(t, res.Err)
}

func TestDeleteContainerWithOpts(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
HandleDeleteContainerWithOptsSuccessfully(t)

opts := &containers.DeleteOpts{
BulkDelete: true,
}
res := containers.Delete(fake.ServiceClient(), "testContainer", opts)
th.CheckNoErr(t, res.Err)
}

Expand All @@ -118,6 +130,16 @@ func TestUpdateContainer(t *testing.T) {
th.CheckNoErr(t, res.Err)
}

func TestUpdateContainerBulkDelete(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
HandleUpdateContainerBulkDeleteSuccessfully(t)

options := &containers.UpdateOpts{Metadata: map[string]string{"foo": "bar"}, BulkDelete: true}
res := containers.Update(fake.ServiceClient(), "testContainer", options)
th.CheckNoErr(t, res.Err)
}

func TestGetContainer(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
Expand Down

0 comments on commit 07cf4b8

Please sign in to comment.