Skip to content

Commit

Permalink
add /dav/spaces endpoint
Browse files Browse the repository at this point in the history
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
  • Loading branch information
butonic committed Jun 18, 2021
1 parent 087ec08 commit 21f6901
Show file tree
Hide file tree
Showing 49 changed files with 1,890 additions and 758 deletions.
95 changes: 66 additions & 29 deletions internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,23 +131,23 @@ func (s *svc) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSp

if id != nil {
// query that specific story provider
parts := strings.SplitN(id.OpaqueId, "!", 2)
if len(parts) != 2 {
return &provider.ListStorageSpacesResponse{
Status: status.NewInvalidArg(ctx, "space id must be separated by !"),
}, nil
}
parts := strings.SplitN(id.OpaqueId, "!", 2)
if len(parts) != 2 {
return &provider.ListStorageSpacesResponse{
Status: status.NewInvalidArg(ctx, "space id must be separated by !"),
}, nil
}
res, err := c.GetStorageProviders(ctx, &registry.GetStorageProvidersRequest{
Ref: &provider.Reference{ResourceId: &provider.ResourceId{
StorageId: parts[0], // FIXME REFERENCE the StorageSpaceId is a storageid + an opaqueid
OpaqueId: parts[1],
OpaqueId: parts[1],
}},
})
if err != nil {
return &provider.ListStorageSpacesResponse{
if err != nil {
return &provider.ListStorageSpacesResponse{
Status: status.NewStatusFromErrType(ctx, "ListStorageSpaces filters: req "+req.String(), err),
}, nil
}
}, nil
}
if res.Status.Code != rpc.Code_CODE_OK {
return &provider.ListStorageSpacesResponse{
Status: res.Status,
Expand All @@ -158,8 +158,8 @@ func (s *svc) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSp
// get list of all storage providers
res, err := c.ListStorageProviders(ctx, &registry.ListStorageProvidersRequest{})

if err != nil {
return &provider.ListStorageSpacesResponse{
if err != nil {
return &provider.ListStorageSpacesResponse{
Status: status.NewStatusFromErrType(ctx, "error listing providers", err),
}, nil
}
Expand Down Expand Up @@ -209,8 +209,8 @@ func (s *svc) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSp
return &provider.ListStorageSpacesResponse{
Status: status.NewOK(ctx),
StorageSpaces: spaces,
}, nil
}
}, nil
}

func (s *svc) listStorageSpacesOnProvider(ctx context.Context, req *provider.ListStorageSpacesRequest, res *[]*provider.StorageSpace, p *registry.ProviderInfo, e *error, wg *sync.WaitGroup) {
defer wg.Done()
Expand Down Expand Up @@ -291,6 +291,11 @@ func (s *svc) getHome(_ context.Context) string {

func (s *svc) InitiateFileDownload(ctx context.Context, req *provider.InitiateFileDownloadRequest) (*gateway.InitiateFileDownloadResponse, error) {
log := appctx.GetLogger(ctx)

if utils.IsRelativeReference(req.Ref) {
return s.initiateFileDownload(ctx, req)
}

p, st := s.getPath(ctx, req.Ref)
if st.Code != rpc.Code_CODE_OK {
return &gateway.InitiateFileDownloadResponse{
Expand Down Expand Up @@ -501,6 +506,9 @@ func (s *svc) initiateFileDownload(ctx context.Context, req *provider.InitiateFi

func (s *svc) InitiateFileUpload(ctx context.Context, req *provider.InitiateFileUploadRequest) (*gateway.InitiateFileUploadResponse, error) {
log := appctx.GetLogger(ctx)
if utils.IsRelativeReference(req.Ref) {
return s.initiateFileUpload(ctx, req)
}
p, st := s.getPath(ctx, req.Ref)
if st.Code != rpc.Code_CODE_OK {
return &gateway.InitiateFileUploadResponse{
Expand Down Expand Up @@ -723,6 +731,11 @@ func (s *svc) GetPath(ctx context.Context, req *provider.GetPathRequest) (*provi

func (s *svc) CreateContainer(ctx context.Context, req *provider.CreateContainerRequest) (*provider.CreateContainerResponse, error) {
log := appctx.GetLogger(ctx)

if utils.IsRelativeReference(req.Ref) {
return s.createContainer(ctx, req)
}

p, st := s.getPath(ctx, req.Ref)
if st.Code != rpc.Code_CODE_OK {
return &provider.CreateContainerResponse{
Expand Down Expand Up @@ -1167,14 +1180,19 @@ func (s *svc) stat(ctx context.Context, req *provider.StatRequest) (*provider.St
}

resPath := req.Ref.GetPath()
if len(providers) == 1 && (resPath == "" || strings.HasPrefix(resPath, providers[0].ProviderPath)) {
if len(providers) == 1 && (utils.IsRelativeReference(req.Ref) || resPath == "" || strings.HasPrefix(resPath, providers[0].ProviderPath)) {
c, err := s.getStorageProviderClient(ctx, providers[0])
if err != nil {
return &provider.StatResponse{
Status: status.NewInternal(ctx, err, "error connecting to storage provider="+providers[0].Address),
}, nil
}
return c.Stat(ctx, req)
rsp, err := c.Stat(ctx, req)
if err != nil || rsp.Status.Code != rpc.Code_CODE_OK {
return rsp, err
}

return rsp, nil
}

infoFromProviders := make([]*provider.ResourceInfo, len(providers))
Expand Down Expand Up @@ -1222,12 +1240,16 @@ func (s *svc) statOnProvider(ctx context.Context, req *provider.StatRequest, res
return
}

resPath := path.Clean(req.Ref.GetPath())
newPath := req.Ref.GetPath()
if resPath != "" && !strings.HasPrefix(resPath, p.ProviderPath) {
newPath = p.ProviderPath
if utils.IsAbsoluteReference(req.Ref) {
resPath := path.Clean(req.Ref.GetPath())
newPath := req.Ref.GetPath()
if resPath != "" && !strings.HasPrefix(resPath, p.ProviderPath) {
newPath = p.ProviderPath
}
req.Ref = &provider.Reference{Path: newPath}
}
r, err := c.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{Path: newPath}})

r, err := c.Stat(ctx, req)
if err != nil {
*e = errors.Wrap(err, "gateway: error calling ListContainer")
return
Expand All @@ -1239,6 +1261,11 @@ func (s *svc) statOnProvider(ctx context.Context, req *provider.StatRequest, res
}

func (s *svc) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) {

if utils.IsRelativeReference(req.Ref) {
return s.stat(ctx, req)
}

p, st := s.getPath(ctx, req.Ref, req.ArbitraryMetadataKeys...)
if st.Code != rpc.Code_CODE_OK {
return &provider.StatResponse{
Expand Down Expand Up @@ -1538,14 +1565,15 @@ func (s *svc) listContainer(ctx context.Context, req *provider.ListContainerRequ

infos := []*provider.ResourceInfo{}
indirects := make(map[string][]*provider.ResourceInfo)
trimPrefix := utils.IsAbsoluteReference(req.Ref)
for i := range providers {
if errors[i] != nil {
return &provider.ListContainerResponse{
Status: status.NewStatusFromErrType(ctx, "listContainer ref: "+req.Ref.String(), errors[i]),
}, nil
}
for _, inf := range infoFromProviders[i] {
if parent := path.Dir(inf.Path); resPath != "" && resPath != parent {
if parent := path.Dir(inf.Path); trimPrefix && resPath != "." && resPath != parent {
parts := strings.Split(strings.TrimPrefix(inf.Path, resPath), "/")
p := path.Join(resPath, parts[1])
indirects[p] = append(indirects[p], inf)
Expand Down Expand Up @@ -1583,12 +1611,16 @@ func (s *svc) listContainerOnProvider(ctx context.Context, req *provider.ListCon
return
}

resPath := path.Clean(req.Ref.GetPath())
newPath := req.Ref.GetPath()
if resPath != "" && !strings.HasPrefix(resPath, p.ProviderPath) {
newPath = p.ProviderPath
if utils.IsAbsoluteReference(req.Ref) {
resPath := path.Clean(req.Ref.GetPath())
newPath := req.Ref.GetPath()
if resPath != "" && !strings.HasPrefix(resPath, p.ProviderPath) {
newPath = p.ProviderPath
}
req.Ref = &provider.Reference{Path: newPath}
}
r, err := c.ListContainer(ctx, &provider.ListContainerRequest{Ref: &provider.Reference{Path: newPath}})

r, err := c.ListContainer(ctx, req)
if err != nil {
*e = errors.Wrap(err, "gateway: error calling ListContainer")
return
Expand All @@ -1598,6 +1630,11 @@ func (s *svc) listContainerOnProvider(ctx context.Context, req *provider.ListCon

func (s *svc) ListContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) {
log := appctx.GetLogger(ctx)

if utils.IsRelativeReference(req.Ref) {
return s.listContainer(ctx, req)
}

p, st := s.getPath(ctx, req.Ref, req.ArbitraryMetadataKeys...)
if st.Code != rpc.Code_CODE_OK {
return &provider.ListContainerResponse{
Expand Down Expand Up @@ -1786,7 +1823,7 @@ func (s *svc) getPath(ctx context.Context, ref *provider.Reference, keys ...stri
return res.Info.Path, res.Status
}

if ref.Path != "" {
if ref.ResourceId == nil && strings.HasPrefix(ref.Path, "/") {
return ref.Path, &rpc.Status{Code: rpc.Code_CODE_OK}
}
return "", &rpc.Status{Code: rpc.Code_CODE_INTERNAL}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ func (s *service) unwrap(ctx context.Context, ref *provider.Reference) (token st
return "", "", errtypes.BadRequest("need absolute path ref: got " + ref.String())
}

if ref.GetPath() == "" {
if !strings.HasPrefix(ref.GetPath(), "/") {
// abort, no valid id nor path
return "", "", errtypes.BadRequest("invalid ref: " + ref.String())
}
Expand Down
Loading

0 comments on commit 21f6901

Please sign in to comment.