package obs import ( "fmt" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory/reg" s3stg "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/s3" stgtypes "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types" jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types" ) func init() { reg.RegisterBuilder[*jcstypes.OBSType](newBuilder) } type builder struct { stgtypes.EmptyBuilder detail *jcstypes.UserSpaceDetail } func newBuilder(detail *jcstypes.UserSpaceDetail) stgtypes.StorageBuilder { return &builder{ detail: detail, } } func (b *builder) FeatureDesc() stgtypes.FeatureDesc { return stgtypes.FeatureDesc{} } func (b *builder) CreateShardStore(typeOnly bool) (stgtypes.ShardStore, error) { stgType := b.detail.UserSpace.Storage.(*jcstypes.OBSType) cred, ok := b.detail.UserSpace.Credential.(*jcstypes.OBSCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } if typeOnly { return (*ShardStore)(nil), nil } cli, bucket, err := createClient(stgType, cred) if err != nil { return nil, err } return NewShardStore(b.detail, stgType, cred, cli, bucket) } func (b *builder) CreateBaseStore(typeOnly bool) (stgtypes.BaseStore, error) { stgType := b.detail.UserSpace.Storage.(*jcstypes.OBSType) cred, ok := b.detail.UserSpace.Credential.(*jcstypes.OBSCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } if typeOnly { return (*s3stg.BaseStore)(nil), nil } cli, bucket, err := createClient(stgType, cred) if err != nil { return nil, err } return s3stg.NewBaseStore(b.detail, cli, bucket, s3stg.BaseStoreOption{UseAWSSha256: false}) } func createClient(stgType *jcstypes.OBSType, cred *jcstypes.OBSCred) (*s3.Client, string, error) { awsConfig := aws.Config{} cre := aws.Credentials{ AccessKeyID: cred.AK, SecretAccessKey: cred.SK, } awsConfig.Credentials = &credentials.StaticCredentialsProvider{Value: cre} awsConfig.Region = stgType.Region awsConfig.RetryMaxAttempts = 1 options := []func(*s3.Options){} options = append(options, func(s3Opt *s3.Options) { s3Opt.BaseEndpoint = &stgType.Endpoint }) cli := s3.NewFromConfig(awsConfig, options...) return cli, stgType.Bucket, nil } func (b *builder) CreateMultiparter(typeOnly bool) (stgtypes.Multiparter, error) { stgType := b.detail.UserSpace.Storage.(*jcstypes.OBSType) feat := stgtypes.FindFeature[*jcstypes.MultipartUploadFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature %T not found", jcstypes.MultipartUploadFeature{}) } if typeOnly { return (*s3stg.Multiparter)(nil), nil } cred, ok := b.detail.UserSpace.Credential.(*jcstypes.OBSCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } cli, bucket, err := createClient(stgType, cred) if err != nil { return nil, err } return s3stg.NewMultiparter( b.detail, feat, bucket, cli, ), nil } func (b *builder) CreateS2STransfer(typeOnly bool) (stgtypes.S2STransfer, error) { stgType := b.detail.UserSpace.Storage.(*jcstypes.OBSType) feat := stgtypes.FindFeature[*jcstypes.S2STransferFeature](b.detail) if feat == nil { return nil, fmt.Errorf("feature %T not found", jcstypes.S2STransferFeature{}) } if typeOnly { return (*S2STransfer)(nil), nil } cred, ok := b.detail.UserSpace.Credential.(*jcstypes.OBSCred) if !ok { return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential) } return NewS2STransfer(b.detail, stgType, cred, feat), nil }