mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-07 23:00:55 +03:00
161 lines
4.5 KiB
Go
161 lines
4.5 KiB
Go
package metadata
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
"google.golang.org/protobuf/types/known/emptypb"
|
|
|
|
"github.com/drakkan/sftpgo/v2/sdk/plugin/metadata/proto"
|
|
)
|
|
|
|
const (
|
|
rpcTimeout = 20 * time.Second
|
|
)
|
|
|
|
// GRPCClient is an implementation of Metadater interface that talks over RPC.
|
|
type GRPCClient struct {
|
|
client proto.MetadataClient
|
|
}
|
|
|
|
// SetModificationTime implements the Metadater interface
|
|
func (c *GRPCClient) SetModificationTime(storageID, objectPath string, mTime int64) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
|
|
defer cancel()
|
|
|
|
_, err := c.client.SetModificationTime(ctx, &proto.SetModificationTimeRequest{
|
|
StorageId: storageID,
|
|
ObjectPath: objectPath,
|
|
ModificationTime: mTime,
|
|
})
|
|
|
|
return c.checkError(err)
|
|
}
|
|
|
|
// GetModificationTime implements the Metadater interface
|
|
func (c *GRPCClient) GetModificationTime(storageID, objectPath string) (int64, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
|
|
defer cancel()
|
|
|
|
resp, err := c.client.GetModificationTime(ctx, &proto.GetModificationTimeRequest{
|
|
StorageId: storageID,
|
|
ObjectPath: objectPath,
|
|
})
|
|
|
|
if err != nil {
|
|
return 0, c.checkError(err)
|
|
}
|
|
|
|
return resp.ModificationTime, nil
|
|
}
|
|
|
|
// GetModificationTimes implements the Metadater interface
|
|
func (c *GRPCClient) GetModificationTimes(storageID, objectPath string) (map[string]int64, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout*4)
|
|
defer cancel()
|
|
|
|
resp, err := c.client.GetModificationTimes(ctx, &proto.GetModificationTimesRequest{
|
|
StorageId: storageID,
|
|
FolderPath: objectPath,
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, c.checkError(err)
|
|
}
|
|
|
|
return resp.Pairs, nil
|
|
}
|
|
|
|
// RemoveMetadata implements the Metadater interface
|
|
func (c *GRPCClient) RemoveMetadata(storageID, objectPath string) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
|
|
defer cancel()
|
|
|
|
_, err := c.client.RemoveMetadata(ctx, &proto.RemoveMetadataRequest{
|
|
StorageId: storageID,
|
|
ObjectPath: objectPath,
|
|
})
|
|
|
|
return c.checkError(err)
|
|
}
|
|
|
|
// GetFolders implements the Metadater interface
|
|
func (c *GRPCClient) GetFolders(storageID string, limit int, from string) ([]string, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), rpcTimeout)
|
|
defer cancel()
|
|
|
|
resp, err := c.client.GetFolders(ctx, &proto.GetFoldersRequest{
|
|
StorageId: storageID,
|
|
Limit: int32(limit),
|
|
From: from,
|
|
})
|
|
if err != nil {
|
|
return nil, c.checkError(err)
|
|
}
|
|
return resp.Folders, nil
|
|
}
|
|
|
|
func (c *GRPCClient) checkError(err error) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
if s, ok := status.FromError(err); ok {
|
|
if s.Code() == codes.NotFound {
|
|
return ErrNoSuchObject
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
// GRPCServer defines the gRPC server that GRPCClient talks to.
|
|
type GRPCServer struct {
|
|
Impl Metadater
|
|
}
|
|
|
|
// SetModificationTime implements the server side set modification time method
|
|
func (s *GRPCServer) SetModificationTime(ctx context.Context, req *proto.SetModificationTimeRequest) (*emptypb.Empty, error) {
|
|
err := s.Impl.SetModificationTime(req.StorageId, req.ObjectPath, req.ModificationTime)
|
|
|
|
return &emptypb.Empty{}, err
|
|
}
|
|
|
|
// GetModificationTime implements the server side get modification time method
|
|
func (s *GRPCServer) GetModificationTime(ctx context.Context, req *proto.GetModificationTimeRequest) (
|
|
*proto.GetModificationTimeResponse, error,
|
|
) {
|
|
mTime, err := s.Impl.GetModificationTime(req.StorageId, req.ObjectPath)
|
|
|
|
return &proto.GetModificationTimeResponse{
|
|
ModificationTime: mTime,
|
|
}, err
|
|
}
|
|
|
|
// GetModificationTimes implements the server side get modification times method
|
|
func (s *GRPCServer) GetModificationTimes(ctx context.Context, req *proto.GetModificationTimesRequest) (
|
|
*proto.GetModificationTimesResponse, error,
|
|
) {
|
|
res, err := s.Impl.GetModificationTimes(req.StorageId, req.FolderPath)
|
|
|
|
return &proto.GetModificationTimesResponse{
|
|
Pairs: res,
|
|
}, err
|
|
}
|
|
|
|
// RemoveMetadata implements the server side remove metadata method
|
|
func (s *GRPCServer) RemoveMetadata(ctx context.Context, req *proto.RemoveMetadataRequest) (*emptypb.Empty, error) {
|
|
err := s.Impl.RemoveMetadata(req.StorageId, req.ObjectPath)
|
|
|
|
return &emptypb.Empty{}, err
|
|
}
|
|
|
|
// GetFolders implements the server side get folders method
|
|
func (s *GRPCServer) GetFolders(ctx context.Context, req *proto.GetFoldersRequest) (*proto.GetFoldersResponse, error) {
|
|
res, err := s.Impl.GetFolders(req.StorageId, int(req.Limit), req.From)
|
|
|
|
return &proto.GetFoldersResponse{
|
|
Folders: res,
|
|
}, err
|
|
}
|