| @@ -9,6 +9,7 @@ import ( | |||||
| "github.com/jedib0t/go-pretty/v6/table" | "github.com/jedib0t/go-pretty/v6/table" | ||||
| "gitlink.org.cn/cloudream/client/config" | "gitlink.org.cn/cloudream/client/config" | ||||
| "gitlink.org.cn/cloudream/client/services" | |||||
| myio "gitlink.org.cn/cloudream/utils/io" | myio "gitlink.org.cn/cloudream/utils/io" | ||||
| ) | ) | ||||
| @@ -118,7 +119,7 @@ func Read(localFilePath string, objectID int) error { | |||||
| 否则,像目前一样,使用grpc向指定节点获取 | 否则,像目前一样,使用grpc向指定节点获取 | ||||
| */ | */ | ||||
| // 下载文件 | // 下载文件 | ||||
| reader, err := svc.DownloadObject(0, objectID) | |||||
| reader, err := services.ObjectSvc(svc).DownloadObject(0, objectID) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("download object failed, err: %w", err) | return fmt.Errorf("download object failed, err: %w", err) | ||||
| } | } | ||||
| @@ -156,7 +157,7 @@ func RepWrite(localFilePath string, bucketID int, objectName string, repNum int) | |||||
| } | } | ||||
| fileSize := fileInfo.Size() | fileSize := fileInfo.Size() | ||||
| err = svc.UploadRepObject(0, bucketID, objectName, file, fileSize, repNum) | |||||
| err = services.ObjectSvc(svc).UploadRepObject(0, bucketID, objectName, file, fileSize, repNum) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("upload file data failed, err: %w", err) | return fmt.Errorf("upload file data failed, err: %w", err) | ||||
| } | } | ||||
| @@ -165,7 +166,7 @@ func RepWrite(localFilePath string, bucketID int, objectName string, repNum int) | |||||
| } | } | ||||
| func Move(objectID int, storageID int) error { | func Move(objectID int, storageID int) error { | ||||
| return svc.MoveObjectToStorage(0, objectID, storageID) | |||||
| return services.StorageSvc(svc).MoveObjectToStorage(0, objectID, storageID) | |||||
| } | } | ||||
| func EcWrite(localFilePath string, bucketID int, objectName string, ecName string) error { | func EcWrite(localFilePath string, bucketID int, objectName string, ecName string) error { | ||||
| @@ -176,7 +177,7 @@ func EcWrite(localFilePath string, bucketID int, objectName string, ecName strin | |||||
| func GetUserBuckets() error { | func GetUserBuckets() error { | ||||
| userID := 0 | userID := 0 | ||||
| buckets, err := svc.GetUserBuckets(userID) | |||||
| buckets, err := services.BucketSvc(svc).GetUserBuckets(userID) | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -197,7 +198,7 @@ func GetUserBuckets() error { | |||||
| func GetBucketObjects(bucketID int) error { | func GetBucketObjects(bucketID int) error { | ||||
| userID := 0 | userID := 0 | ||||
| objects, err := svc.GetBucketObjects(userID, bucketID) | |||||
| objects, err := services.BucketSvc(svc).GetBucketObjects(userID, bucketID) | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -214,3 +215,15 @@ func GetBucketObjects(bucketID int) error { | |||||
| fmt.Print(tb.Render()) | fmt.Print(tb.Render()) | ||||
| return nil | return nil | ||||
| } | } | ||||
| func CreateBucket(bucketName string) error { | |||||
| userID := 0 | |||||
| bucketID, err := services.BucketSvc(svc).CreateBucket(userID, bucketName) | |||||
| if err != nil { | |||||
| return err | |||||
| } | |||||
| fmt.Printf("Create bucket %s success, id: %d", bucketName, bucketID) | |||||
| return nil | |||||
| } | |||||
| @@ -6,35 +6,56 @@ import ( | |||||
| "gitlink.org.cn/cloudream/db/model" | "gitlink.org.cn/cloudream/db/model" | ||||
| ) | ) | ||||
| func (svc *Service) GetBucket(userID int, bucketID int) (model.Bucket, error) { | |||||
| type BucketService struct { | |||||
| *Service | |||||
| } | |||||
| func BucketSvc(svc *Service) *BucketService { | |||||
| return &BucketService{Service: svc} | |||||
| } | |||||
| func (svc *BucketService) GetBucket(userID int, bucketID int) (model.Bucket, error) { | |||||
| // TODO | // TODO | ||||
| panic("not implement yet") | panic("not implement yet") | ||||
| } | } | ||||
| func (svc *Service) GetUserBuckets(userID int) ([]model.Bucket, error) { | |||||
| func (svc *BucketService) GetUserBuckets(userID int) ([]model.Bucket, error) { | |||||
| resp, err := svc.coordinator.GetUserBuckets(userID) | resp, err := svc.coordinator.GetUserBuckets(userID) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("get user buckets failed, err: %w", err) | return nil, fmt.Errorf("get user buckets failed, err: %w", err) | ||||
| } | } | ||||
| if !resp.IsOK() { | |||||
| return nil, fmt.Errorf("create bucket objects failed, code: %s, message: %s", resp.ErrorCode, resp.Message) | |||||
| } | |||||
| return resp.Buckets, nil | return resp.Buckets, nil | ||||
| } | } | ||||
| func (svc *Service) GetBucketObjects(userID int, bucketID int) ([]model.Object, error) { | |||||
| func (svc *BucketService) GetBucketObjects(userID int, bucketID int) ([]model.Object, error) { | |||||
| resp, err := svc.coordinator.GetBucketObjects(userID, bucketID) | resp, err := svc.coordinator.GetBucketObjects(userID, bucketID) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("get bucket objects failed, err: %w", err) | return nil, fmt.Errorf("get bucket objects failed, err: %w", err) | ||||
| } | } | ||||
| if !resp.IsOK() { | |||||
| return nil, fmt.Errorf("create bucket objects failed, code: %s, message: %s", resp.ErrorCode, resp.Message) | |||||
| } | |||||
| return resp.Objects, nil | return resp.Objects, nil | ||||
| } | } | ||||
| func (svc *Service) CreateBucket(userID int, bucketName string) (model.Bucket, error) { | |||||
| // TODO | |||||
| panic("not implement yet") | |||||
| func (svc *BucketService) CreateBucket(userID int, bucketName string) (int, error) { | |||||
| resp, err := svc.coordinator.CreateBucket(userID, bucketName) | |||||
| if err != nil { | |||||
| return 0, fmt.Errorf("create bucket objects failed, err: %w", err) | |||||
| } | |||||
| if !resp.IsOK() { | |||||
| return 0, fmt.Errorf("create bucket objects failed, code: %s, message: %s", resp.ErrorCode, resp.Message) | |||||
| } | |||||
| return resp.BucketID, nil | |||||
| } | } | ||||
| func (src *Service) DeleteBucket(userID int, bucketID int) error { | |||||
| func (src *BucketService) DeleteBucket(userID int, bucketID int) error { | |||||
| // TODO | // TODO | ||||
| panic("not implement yet") | panic("not implement yet") | ||||
| } | } | ||||
| @@ -8,7 +8,6 @@ import ( | |||||
| "gitlink.org.cn/cloudream/client/config" | "gitlink.org.cn/cloudream/client/config" | ||||
| "gitlink.org.cn/cloudream/db/model" | "gitlink.org.cn/cloudream/db/model" | ||||
| agentcaller "gitlink.org.cn/cloudream/proto" | agentcaller "gitlink.org.cn/cloudream/proto" | ||||
| racli "gitlink.org.cn/cloudream/rabbitmq/client" | |||||
| "gitlink.org.cn/cloudream/utils/consts" | "gitlink.org.cn/cloudream/utils/consts" | ||||
| "gitlink.org.cn/cloudream/utils/consts/errorcode" | "gitlink.org.cn/cloudream/utils/consts/errorcode" | ||||
| mygrpc "gitlink.org.cn/cloudream/utils/grpc" | mygrpc "gitlink.org.cn/cloudream/utils/grpc" | ||||
| @@ -17,14 +16,20 @@ import ( | |||||
| "google.golang.org/grpc/credentials/insecure" | "google.golang.org/grpc/credentials/insecure" | ||||
| ) | ) | ||||
| type BucketService = Service | |||||
| type ObjectService struct { | |||||
| *Service | |||||
| } | |||||
| func ObjectSvc(svc *Service) *ObjectService { | |||||
| return &ObjectService{Service: svc} | |||||
| } | |||||
| func (svc *BucketService) GetObject(userID int, objectID int) (model.Object, error) { | |||||
| func (svc *ObjectService) GetObject(userID int, objectID int) (model.Object, error) { | |||||
| // TODO | // TODO | ||||
| panic("not implement yet") | panic("not implement yet") | ||||
| } | } | ||||
| func (svc *BucketService) DownloadObject(userID int, objectID int) (io.ReadCloser, error) { | |||||
| func (svc *ObjectService) DownloadObject(userID int, objectID int) (io.ReadCloser, error) { | |||||
| readResp, err := svc.coordinator.Read(objectID, userID) | readResp, err := svc.coordinator.Read(objectID, userID) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, fmt.Errorf("request to coordinator failed, err: %w", err) | return nil, fmt.Errorf("request to coordinator failed, err: %w", err) | ||||
| @@ -55,7 +60,7 @@ func (svc *BucketService) DownloadObject(userID int, objectID int) (io.ReadClose | |||||
| return nil, fmt.Errorf("unsupported redundancy type: %s", readResp.Redundancy) | return nil, fmt.Errorf("unsupported redundancy type: %s", readResp.Redundancy) | ||||
| } | } | ||||
| func (svc *BucketService) downloadAsRepObject(nodeIP string, fileHash string) (io.ReadCloser, error) { | |||||
| func (svc *ObjectService) downloadAsRepObject(nodeIP string, fileHash string) (io.ReadCloser, error) { | |||||
| // 连接grpc | // 连接grpc | ||||
| grpcAddr := fmt.Sprintf("%s:%d", nodeIP, config.Cfg().GRPCPort) | grpcAddr := fmt.Sprintf("%s:%d", nodeIP, config.Cfg().GRPCPort) | ||||
| conn, err := grpc.Dial(grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) | conn, err := grpc.Dial(grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) | ||||
| @@ -78,7 +83,7 @@ func (svc *BucketService) downloadAsRepObject(nodeIP string, fileHash string) (i | |||||
| return reader, nil | return reader, nil | ||||
| } | } | ||||
| func (svc *BucketService) UploadRepObject(userID int, bucketID int, objectName string, file io.ReadCloser, fileSize int64, repNum int) error { | |||||
| func (svc *ObjectService) UploadRepObject(userID int, bucketID int, objectName string, file io.ReadCloser, fileSize int64, repNum int) error { | |||||
| //发送写请求,请求Coor分配写入节点Ip | //发送写请求,请求Coor分配写入节点Ip | ||||
| repWriteResp, err := svc.coordinator.RepWrite(bucketID, objectName, fileSize, repNum, userID) | repWriteResp, err := svc.coordinator.RepWrite(bucketID, objectName, fileSize, repNum, userID) | ||||
| @@ -142,7 +147,7 @@ type fileSender struct { | |||||
| err error | err error | ||||
| } | } | ||||
| func (svc *BucketService) startSendFile(numRep int, senders []fileSender, nodeIDs []int, nodeIPs []string) { | |||||
| func (svc *ObjectService) startSendFile(numRep int, senders []fileSender, nodeIDs []int, nodeIPs []string) { | |||||
| for i := 0; i < numRep; i++ { | for i := 0; i < numRep; i++ { | ||||
| sender := &senders[i] | sender := &senders[i] | ||||
| @@ -169,7 +174,7 @@ func (svc *BucketService) startSendFile(numRep int, senders []fileSender, nodeID | |||||
| } | } | ||||
| } | } | ||||
| func (svc *BucketService) sendFileData(file io.ReadCloser, numRep int, senders []fileSender) error { | |||||
| func (svc *ObjectService) sendFileData(file io.ReadCloser, numRep int, senders []fileSender) error { | |||||
| // 共用的发送数据缓冲区 | // 共用的发送数据缓冲区 | ||||
| buf := make([]byte, 2048) | buf := make([]byte, 2048) | ||||
| @@ -239,7 +244,7 @@ func (svc *BucketService) sendFileData(file io.ReadCloser, numRep int, senders [ | |||||
| return nil | return nil | ||||
| } | } | ||||
| func (svc *BucketService) sendFinish(numRep int, senders []fileSender) { | |||||
| func (svc *ObjectService) sendFinish(numRep int, senders []fileSender) { | |||||
| for i := 0; i < numRep; i++ { | for i := 0; i < numRep; i++ { | ||||
| sender := &senders[i] | sender := &senders[i] | ||||
| @@ -262,47 +267,12 @@ func (svc *BucketService) sendFinish(numRep int, senders []fileSender) { | |||||
| } | } | ||||
| } | } | ||||
| func (svc *BucketService) UploadECObject(userID int, file io.ReadCloser, fileSize int64, ecName string) error { | |||||
| func (svc *ObjectService) UploadECObject(userID int, file io.ReadCloser, fileSize int64, ecName string) error { | |||||
| // TODO | // TODO | ||||
| panic("not implement yet") | panic("not implement yet") | ||||
| } | } | ||||
| func (svc *BucketService) MoveObjectToStorage(userID int, objectID int, storageID int) error { | |||||
| // 先向协调端请求文件相关的元数据 | |||||
| moveResp, err := svc.coordinator.Move(objectID, storageID, userID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("request to coordinator failed, err: %w", err) | |||||
| } | |||||
| if moveResp.ErrorCode != errorcode.OK { | |||||
| return fmt.Errorf("coordinator operation failed, code: %s, message: %s", moveResp.ErrorCode, moveResp.Message) | |||||
| } | |||||
| // 然后向代理端发送移动文件的请求 | |||||
| agentClient, err := racli.NewAgentClient(moveResp.NodeID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("create agent client to %d failed, err: %w", storageID, err) | |||||
| } | |||||
| defer agentClient.Close() | |||||
| switch moveResp.Redundancy { | |||||
| case consts.REDUNDANCY_REP: | |||||
| agentMoveResp, err := agentClient.RepMove(moveResp.Directory, moveResp.Hashes, objectID, userID, moveResp.FileSizeInBytes) | |||||
| if err != nil { | |||||
| return fmt.Errorf("request to agent %d failed, err: %w", storageID, err) | |||||
| } | |||||
| if agentMoveResp.ErrorCode != errorcode.OK { | |||||
| return fmt.Errorf("agent %d operation failed, code: %s, messsage: %s", storageID, agentMoveResp.ErrorCode, agentMoveResp.Message) | |||||
| } | |||||
| case consts.REDUNDANCY_EC: | |||||
| agentMoveResp, err := agentClient.ECMove(moveResp.Directory, moveResp.Hashes, moveResp.IDs, *moveResp.ECName, objectID, userID, moveResp.FileSizeInBytes) | |||||
| if err != nil { | |||||
| return fmt.Errorf("request to agent %d failed, err: %w", storageID, err) | |||||
| } | |||||
| if agentMoveResp.ErrorCode != errorcode.OK { | |||||
| return fmt.Errorf("agent %d operation failed, code: %s, messsage: %s", storageID, agentMoveResp.ErrorCode, agentMoveResp.Message) | |||||
| } | |||||
| } | |||||
| return nil | |||||
| func (svc *ObjectService) Delete(userID int, objectID int) error { | |||||
| // TODO | |||||
| panic("not implement yet") | |||||
| } | } | ||||
| @@ -1,7 +1,7 @@ | |||||
| package services | package services | ||||
| import ( | import ( | ||||
| racli "gitlink.org.cn/cloudream/rabbitmq/client" | |||||
| racli "gitlink.org.cn/cloudream/rabbitmq/client/coordinator" | |||||
| ) | ) | ||||
| type Service struct { | type Service struct { | ||||
| @@ -0,0 +1,62 @@ | |||||
| package services | |||||
| import ( | |||||
| "fmt" | |||||
| racli "gitlink.org.cn/cloudream/rabbitmq/client" | |||||
| "gitlink.org.cn/cloudream/utils/consts" | |||||
| "gitlink.org.cn/cloudream/utils/consts/errorcode" | |||||
| ) | |||||
| type StorageService struct { | |||||
| *Service | |||||
| } | |||||
| func StorageSvc(svc *Service) *StorageService { | |||||
| return &StorageService{Service: svc} | |||||
| } | |||||
| func (svc *StorageService) MoveObjectToStorage(userID int, objectID int, storageID int) error { | |||||
| // 先向协调端请求文件相关的元数据 | |||||
| moveResp, err := svc.coordinator.Move(objectID, storageID, userID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("request to coordinator failed, err: %w", err) | |||||
| } | |||||
| if moveResp.ErrorCode != errorcode.OK { | |||||
| return fmt.Errorf("coordinator operation failed, code: %s, message: %s", moveResp.ErrorCode, moveResp.Message) | |||||
| } | |||||
| // 然后向代理端发送移动文件的请求 | |||||
| agentClient, err := racli.NewAgentClient(moveResp.NodeID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("create agent client to %d failed, err: %w", storageID, err) | |||||
| } | |||||
| defer agentClient.Close() | |||||
| switch moveResp.Redundancy { | |||||
| case consts.REDUNDANCY_REP: | |||||
| agentMoveResp, err := agentClient.RepMove(moveResp.Directory, moveResp.Hashes, objectID, userID, moveResp.FileSizeInBytes) | |||||
| if err != nil { | |||||
| return fmt.Errorf("request to agent %d failed, err: %w", storageID, err) | |||||
| } | |||||
| if agentMoveResp.ErrorCode != errorcode.OK { | |||||
| return fmt.Errorf("agent %d operation failed, code: %s, messsage: %s", storageID, agentMoveResp.ErrorCode, agentMoveResp.Message) | |||||
| } | |||||
| case consts.REDUNDANCY_EC: | |||||
| agentMoveResp, err := agentClient.ECMove(moveResp.Directory, moveResp.Hashes, moveResp.IDs, *moveResp.ECName, objectID, userID, moveResp.FileSizeInBytes) | |||||
| if err != nil { | |||||
| return fmt.Errorf("request to agent %d failed, err: %w", storageID, err) | |||||
| } | |||||
| if agentMoveResp.ErrorCode != errorcode.OK { | |||||
| return fmt.Errorf("agent %d operation failed, code: %s, messsage: %s", storageID, agentMoveResp.ErrorCode, agentMoveResp.Message) | |||||
| } | |||||
| } | |||||
| return nil | |||||
| } | |||||
| func (svc *StorageService) DeleteStorageObject(userID int, objectID int, storageID int) error { | |||||
| // TODO | |||||
| panic("not implement yet") | |||||
| } | |||||