Merge pull request #23 from nspcc-dev/api-handlers

API Handlers (DeleteObject handler)
This commit is contained in:
Evgeniy Kulikov 2020-08-21 17:25:08 +03:00 committed by GitHub
commit c9ea63f8ab
4 changed files with 54 additions and 28 deletions

View file

@ -34,3 +34,15 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
} }
// DeleteMultipleObjectsHandler :
//
// CyberDuck doesn't use that method for multiple delete.
// Open issue and describe how to test that method.
func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) {
api.WriteErrorResponse(r.Context(), w, api.Error{
Code: "XNeoFSUnimplemented",
Description: "implement me " + mux.CurrentRoute(r).GetName(),
HTTPStatusCode: http.StatusNotImplemented,
}, r.URL)
}

View file

@ -358,11 +358,3 @@ func (h *handler) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Request
HTTPStatusCode: http.StatusNotImplemented, HTTPStatusCode: http.StatusNotImplemented,
}, r.URL) }, r.URL)
} }
func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) {
api.WriteErrorResponse(r.Context(), w, api.Error{
Code: "XNeoFSUnimplemented",
Description: "implement me " + mux.CurrentRoute(r).GetName(),
HTTPStatusCode: http.StatusNotImplemented,
}, r.URL)
}

View file

@ -371,19 +371,25 @@ func (n *layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*ObjectInf
}) })
} }
// DeleteObject from the storage. // DeleteObject removes all objects with passed nice name.
func (n *layer) DeleteObject(ctx context.Context, bucket, object string) error { func (n *layer) DeleteObject(ctx context.Context, bucket, object string) error {
cid, err := refs.CIDFromString(bucket) cid, err := refs.CIDFromString(bucket)
if err != nil { if err != nil {
return err return err
} }
oid, err := n.objectFindID(ctx, cid, object, false) ids, err := n.objectFindIDs(ctx, cid, object)
if err != nil { if err != nil {
return err return errors.Wrap(err, "could not find object")
} }
return n.objectDelete(ctx, delParams{addr: refs.Address{CID: cid, ObjectID: oid}}) for _, id := range ids {
if err = n.objectDelete(ctx, delParams{addr: refs.Address{CID: cid, ObjectID: id}}); err != nil {
return errors.Wrapf(err, "could not remove object: %s => %s", object, id)
}
}
return nil
} }
// DeleteObjects from the storage. // DeleteObjects from the storage.

View file

@ -120,13 +120,10 @@ func (n *layer) objectSearchContainer(ctx context.Context, cid refs.CID) ([]refs
return result, nil return result, nil
} }
// objectFindID returns object id (uuid) based on it's nice name in s3. If // objectFindIDs returns object id's (uuid) based on they nice name in s3. If
// nice name is uuid compatible, then function returns it. // nice name is uuid compatible, then function returns it.
func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put bool) (refs.ObjectID, error) { func (n *layer) objectFindIDs(ctx context.Context, cid refs.CID, name string) ([]refs.ObjectID, error) {
var ( var q query.Query
id refs.ObjectID
q query.Query
)
q.Filters = append(q.Filters, query.Filter{ q.Filters = append(q.Filters, query.Filter{
Type: query.Filter_Exact, Type: query.Filter_Exact,
@ -140,12 +137,12 @@ func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put
queryBinary, err := q.Marshal() queryBinary, err := q.Marshal()
if err != nil { if err != nil {
return id, err return nil, err
} }
conn, err := n.cli.GetConnection(ctx) conn, err := n.cli.GetConnection(ctx)
if err != nil { if err != nil {
return id, err return nil, err
} }
token, err := n.cli.SessionToken(ctx, &pool.SessionParams{ token, err := n.cli.SessionToken(ctx, &pool.SessionParams{
@ -154,7 +151,7 @@ func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put
Verb: service.Token_Info_Search, Verb: service.Token_Info_Search,
}) })
if err != nil { if err != nil {
return id, err return nil, err
} }
req := new(object.SearchRequest) req := new(object.SearchRequest)
@ -167,7 +164,7 @@ func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put
err = service.SignRequestData(n.key, req) err = service.SignRequestData(n.key, req)
if err != nil { if err != nil {
return id, err return nil, err
} }
// todo: think about timeout // todo: think about timeout
@ -176,7 +173,7 @@ func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put
searchClient, err := object.NewServiceClient(conn).Search(ctx, req) searchClient, err := object.NewServiceClient(conn).Search(ctx, req)
if err != nil { if err != nil {
return id, err return nil, err
} }
var response []refs.Address var response []refs.Address
@ -188,18 +185,33 @@ func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put
break break
} }
return id, errors.New("search command received error") return nil, errors.New("search command received error")
} }
response = append(response, resp.Addresses...) response = append(response, resp.Addresses...)
} }
switch ln := len(response); { switch ln := len(response); {
case ln > 1: case ln > 0:
return id, errors.New("several objects with the same name found") result := make([]refs.ObjectID, 0, len(response))
case ln == 1: for i := range response {
return response[0].ObjectID, nil result = append(result, response[i].ObjectID)
}
return result, nil
default: default:
return nil, errors.New("object not found")
}
}
// objectFindID returns object id (uuid) based on it's nice name in s3. If
// nice name is uuid compatible, then function returns it.
func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put bool) (refs.ObjectID, error) {
var id refs.ObjectID
if result, err := n.objectFindIDs(ctx, cid, name); err != nil {
return id, err
} else if ln := len(result); ln == 0 {
// Minio lists all objects with and without nice names. All objects // Minio lists all objects with and without nice names. All objects
// without nice name still have "name" in terms of minio - uuid encoded // without nice name still have "name" in terms of minio - uuid encoded
// into string. There is a tricky case when user upload object // into string. There is a tricky case when user upload object
@ -215,7 +227,11 @@ func (n *layer) objectFindID(ctx context.Context, cid refs.CID, name string, put
} }
} }
return id, errors.New("object not found") return id, errors.New("object not found")
} else if ln == 1 {
return result[0], nil
} }
return id, errors.New("several objects with the same name found")
} }
// objectHead returns all object's headers. // objectHead returns all object's headers.