Skip to content

Commit

Permalink
add: external service code for delete S3 bucket
Browse files Browse the repository at this point in the history
  • Loading branch information
nao1215 committed Dec 29, 2023
1 parent 89110b0 commit 7e0bfa3
Show file tree
Hide file tree
Showing 10 changed files with 468 additions and 39 deletions.
35 changes: 28 additions & 7 deletions app/di/wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ import (
// S3App is the application service for S3.
type S3App struct {
// S3BucketCreator is the usecase for creating a new S3 bucket.
S3BucketCreator usecase.S3BucketCreator
usecase.S3BucketCreator
// S3BucketLister is the usecase for listing S3 buckets.
S3BucketLister usecase.S3BucketLister
usecase.S3BucketLister
// S3BucketDeleter is the usecase for deleting a S3 bucket.
usecase.S3BucketDeleter
// S3BucketObjectsLister is the usecase for listing S3 bucket objects.
usecase.S3BucketObjectsLister
// S3BucketObjectsDeleter is the usecase for deleting S3 bucket objects.
usecase.S3BucketObjectsDeleter
}

// NewS3App creates a new S3App.
Expand All @@ -30,16 +36,31 @@ func NewS3App(ctx context.Context, profile model.AWSProfile, region model.Region
external.S3BucketCreatorSet,
external.S3BucketListerSet,
external.S3BucketLocationGetterSet,
interactor.S3bucketCreatorSet,
interactor.S3bucketListerSet,
external.S3BucketDeleterSet,
external.S3BucketObjectsListerSet,
external.S3BucketObjectsDeleterSet,
interactor.S3BucketCreatorSet,
interactor.S3BucketListerSet,
interactor.S3BucketDeleterSet,
interactor.S3BucketObjectsListerSet,
interactor.S3BucketObjectsDeleterSet,
newS3App,
)
return nil, nil
}

func newS3App(s3bucketCreator usecase.S3BucketCreator, s3bucketLister usecase.S3BucketLister) *S3App {
func newS3App(
s3BucketCreator usecase.S3BucketCreator,
s3BucketLister usecase.S3BucketLister,
s3BucketDeleter usecase.S3BucketDeleter,
s3BucketObjectsLister usecase.S3BucketObjectsLister,
s3BucketObjectsDeleter usecase.S3BucketObjectsDeleter,
) *S3App {
return &S3App{
S3BucketCreator: s3bucketCreator,
S3BucketLister: s3bucketLister,
S3BucketCreator: s3BucketCreator,
S3BucketLister: s3BucketLister,
S3BucketDeleter: s3BucketDeleter,
S3BucketObjectsLister: s3BucketObjectsLister,
S3BucketObjectsDeleter: s3BucketObjectsDeleter,
}
}
40 changes: 33 additions & 7 deletions app/di/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions app/domain/model/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/nao1215/rainbow/utils/errfmt"
"github.com/nao1215/rainbow/utils/xregex"
)
Expand Down Expand Up @@ -244,3 +246,55 @@ func (b BucketSets) Len() int {
func (b BucketSets) Empty() bool {
return b.Len() == 0
}

// S3ObjectSets is the set of the S3ObjectSet.
type S3ObjectSets []S3Object

// Len returns the length of the S3ObjectSets.
func (s S3ObjectSets) Len() int {
return len(s)
}

// ToS3ObjectIdentifiers converts the S3ObjectSets to the ObjectIdentifiers.
func (s S3ObjectSets) ToS3ObjectIdentifiers() []types.ObjectIdentifier {
var ids []types.ObjectIdentifier
for _, o := range s {
ids = append(ids, *o.ToS3ObjectIdentifier())
}
return ids
}

// S3Object is the object in the S3 bucket.
type S3Object struct {
// S3Key is the name of the object.
S3Key S3Key
// VersionID is the version ID for the specific version of the object to delete.
VersionID VersionID
}

// ToS3ObjectIdentifier converts the S3Object to the ObjectIdentifier.
func (o S3Object) ToS3ObjectIdentifier() *types.ObjectIdentifier {
return &types.ObjectIdentifier{
Key: aws.String(o.S3Key.String()),
VersionId: aws.String(o.VersionID.String()),
}
}

// S3Key is the name of the object.
// Replacement must be made for object keys containing special characters (such as carriage returns) when using XML requests.
// For more information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints).
type S3Key string

// String returns the string representation of the S3Key.
func (k S3Key) String() string {
return string(k)
}

// VersionID is the version ID for the specific version of the object to delete.
// This functionality is not supported for directory buckets.
type VersionID string

// String returns the string representation of the VersionID.
func (v VersionID) String() string {
return string(v)
}
55 changes: 52 additions & 3 deletions app/domain/service/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type S3BucketCreatorOutput struct{}

// S3BucketCreator is the interface that wraps the basic CreateBucket method.
type S3BucketCreator interface {
CreateBucket(ctx context.Context, input *S3BucketCreatorInput) (*S3BucketCreatorOutput, error)
CreateS3Bucket(ctx context.Context, input *S3BucketCreatorInput) (*S3BucketCreatorOutput, error)
}

// S3BucketListerInput is the input of the ListBuckets method.
Expand All @@ -34,7 +34,7 @@ type S3BucketListerOutput struct {

// S3BucketLister is the interface that wraps the basic ListBuckets method.
type S3BucketLister interface {
ListBuckets(ctx context.Context, input *S3BucketListerInput) (*S3BucketListerOutput, error)
ListS3Buckets(ctx context.Context, input *S3BucketListerInput) (*S3BucketListerOutput, error)
}

// S3BucketLocationGetterInput is the input of the GetBucketLocation method.
Expand All @@ -50,5 +50,54 @@ type S3BucketLocationGetterOutput struct {

// S3BucketLocationGetter is the interface that wraps the basic GetBucketLocation method.
type S3BucketLocationGetter interface {
GetBucketLocation(ctx context.Context, input *S3BucketLocationGetterInput) (*S3BucketLocationGetterOutput, error)
GetS3BucketLocation(ctx context.Context, input *S3BucketLocationGetterInput) (*S3BucketLocationGetterOutput, error)
}

// S3BucketDeleterInput is the input of the DeleteBucket method.
type S3BucketDeleterInput struct {
// Bucket is the name of the bucket to delete.
Bucket model.Bucket
// Region is the region of the bucket that you want to delete.
Region model.Region
}

// S3BucketDeleterOutput is the output of the DeleteBucket method.
type S3BucketDeleterOutput struct{}

// S3BucketDeleter is the interface that wraps the basic DeleteBucket method.
type S3BucketDeleter interface {
DeleteS3Bucket(ctx context.Context, input *S3BucketDeleterInput) (*S3BucketDeleterOutput, error)
}

// S3BucketObjectsDeleterInput is the input of the DeleteBucketObjects method.
type S3BucketObjectsDeleterInput struct {
// Bucket is the name of the bucket to delete.
Bucket model.Bucket
// S3ObjectSets is the list of the objects to delete.
S3ObjectSets model.S3ObjectSets
}

// S3BucketObjectsDeleterOutput is the output of the DeleteBucketObjects method.
type S3BucketObjectsDeleterOutput struct{}

// S3BucketObjectsDeleter is the interface that wraps the basic DeleteBucketObjects method.
type S3BucketObjectsDeleter interface {
DeleteS3BucketObjects(ctx context.Context, input *S3BucketObjectsDeleterInput) (*S3BucketObjectsDeleterOutput, error)
}

// S3BucketObjectsListerInput is the input of the ListBucketObjects method.
type S3BucketObjectsListerInput struct {
// Bucket is the name of the bucket to list.
Bucket model.Bucket
}

// S3BucketObjectsListerOutput is the output of the ListBucketObjects method.
type S3BucketObjectsListerOutput struct {
// Objects is the list of the objects.
Objects model.S3ObjectSets
}

// S3BucketObjectsLister is the interface that wraps the basic ListBucketObjects method.
type S3BucketObjectsLister interface {
ListS3BucketObjects(ctx context.Context, input *S3BucketObjectsListerInput) (*S3BucketObjectsListerOutput, error)
}
119 changes: 113 additions & 6 deletions app/external/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func NewS3BucketCreator(client *s3.Client) *S3BucketCreator {
return &S3BucketCreator{client: client}
}

// CreateBucket creates a new S3 bucket.
func (c *S3BucketCreator) CreateBucket(ctx context.Context, input *service.S3BucketCreatorInput) (*service.S3BucketCreatorOutput, error) {
// CreateS3Bucket creates a new S3 bucket.
func (c *S3BucketCreator) CreateS3Bucket(ctx context.Context, input *service.S3BucketCreatorInput) (*service.S3BucketCreatorOutput, error) {
// If region is us-east-1, you must not specify the location constraint.
// If you specify the location constraint in this case, the following error will occur.
// [api error InvalidLocationConstraint: The specified location-constraint is not valid]
Expand Down Expand Up @@ -81,8 +81,8 @@ func NewS3BucketLister(client *s3.Client) *S3BucketLister {
return &S3BucketLister{client: client}
}

// ListBuckets lists the buckets.
func (c *S3BucketLister) ListBuckets(ctx context.Context, _ *service.S3BucketListerInput) (*service.S3BucketListerOutput, error) {
// ListS3Buckets lists the buckets.
func (c *S3BucketLister) ListS3Buckets(ctx context.Context, _ *service.S3BucketListerInput) (*service.S3BucketListerOutput, error) {
out, err := c.client.ListBuckets(ctx, &s3.ListBucketsInput{})
if err != nil {
return nil, err
Expand Down Expand Up @@ -118,8 +118,8 @@ func NewS3BucketLocationGetter(client *s3.Client) *S3BucketLocationGetter {
return &S3BucketLocationGetter{client: client}
}

// GetBucketLocation gets the location of the bucket.
func (c *S3BucketLocationGetter) GetBucketLocation(ctx context.Context, input *service.S3BucketLocationGetterInput) (*service.S3BucketLocationGetterOutput, error) {
// GetS3BucketLocation gets the location of the bucket.
func (c *S3BucketLocationGetter) GetS3BucketLocation(ctx context.Context, input *service.S3BucketLocationGetterInput) (*service.S3BucketLocationGetterOutput, error) {
out, err := c.client.GetBucketLocation(ctx, &s3.GetBucketLocationInput{
Bucket: aws.String(input.Bucket.String()),
})
Expand All @@ -136,3 +136,110 @@ func (c *S3BucketLocationGetter) GetBucketLocation(ctx context.Context, input *s
Region: region,
}, nil
}

// S3BucketDeleter implements the S3BucketDeleter interface.
type S3BucketDeleter struct {
client *s3.Client
}

// S3BucketDeleterSet is a provider set for S3BucketDeleter.
//
//nolint:gochecknoglobals
var S3BucketDeleterSet = wire.NewSet(
NewS3BucketDeleter,
wire.Bind(new(service.S3BucketDeleter), new(*S3BucketDeleter)),
)

var _ service.S3BucketDeleter = (*S3BucketDeleter)(nil)

// NewS3BucketDeleter creates a new S3BucketDeleter.
func NewS3BucketDeleter(client *s3.Client) *S3BucketDeleter {
return &S3BucketDeleter{client: client}
}

// DeleteS3Bucket deletes the bucket.
func (c *S3BucketDeleter) DeleteS3Bucket(ctx context.Context, input *service.S3BucketDeleterInput) (*service.S3BucketDeleterOutput, error) {
_, err := c.client.DeleteBucket(ctx,
&s3.DeleteBucketInput{
Bucket: aws.String(input.Bucket.String()),
},
func(o *s3.Options) {
o.Region = input.Region.String()
})
if err != nil {
return nil, err
}
return &service.S3BucketDeleterOutput{}, nil
}

// S3BucketObjectsDeleter implements the S3BucketObjectsDeleter interface.
type S3BucketObjectsDeleter struct {
client *s3.Client
}

// S3BucketObjectsDeleterSet is a provider set for S3BucketObjectsDeleter.
//
//nolint:gochecknoglobals
var S3BucketObjectsDeleterSet = wire.NewSet(
NewS3BucketObjectsDeleter,
wire.Bind(new(service.S3BucketObjectsDeleter), new(*S3BucketObjectsDeleter)),
)

var _ service.S3BucketObjectsDeleter = (*S3BucketObjectsDeleter)(nil)

// NewS3BucketObjectsDeleter creates a new S3BucketObjectsDeleter.
func NewS3BucketObjectsDeleter(client *s3.Client) *S3BucketObjectsDeleter {
return &S3BucketObjectsDeleter{client: client}
}

// DeleteS3BucketObjects deletes the objects in the bucket.
func (c *S3BucketObjectsDeleter) DeleteS3BucketObjects(ctx context.Context, input *service.S3BucketObjectsDeleterInput) (*service.S3BucketObjectsDeleterOutput, error) {
_, err := c.client.DeleteObjects(ctx, &s3.DeleteObjectsInput{
Bucket: aws.String(input.Bucket.String()),
Delete: &types.Delete{
Objects: input.S3ObjectSets.ToS3ObjectIdentifiers(),
},
})
if err != nil {
return nil, err
}
return &service.S3BucketObjectsDeleterOutput{}, nil
}

// S3BucketObjectsLister implements the S3BucketObjectsLister interface.
type S3BucketObjectsLister struct {
client *s3.Client
}

// S3BucketObjectsListerSet is a provider set for S3BucketObjectsLister.
//
//nolint:gochecknoglobals
var S3BucketObjectsListerSet = wire.NewSet(
NewS3BucketObjectsLister,
wire.Bind(new(service.S3BucketObjectsLister), new(*S3BucketObjectsLister)),
)

var _ service.S3BucketObjectsLister = (*S3BucketObjectsLister)(nil)

// NewS3BucketObjectsLister creates a new S3BucketObjectsLister.
func NewS3BucketObjectsLister(client *s3.Client) *S3BucketObjectsLister {
return &S3BucketObjectsLister{client: client}
}

// ListS3BucketObjects lists the objects in the bucket.
func (c *S3BucketObjectsLister) ListS3BucketObjects(ctx context.Context, input *service.S3BucketObjectsListerInput) (*service.S3BucketObjectsListerOutput, error) {
out, err := c.client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{
Bucket: aws.String(input.Bucket.String()),
})
if err != nil {
return nil, err
}

var objects model.S3ObjectSets
for _, o := range out.Contents {
objects = append(objects, model.S3Object{
S3Key: model.S3Key(*o.Key),
})
}
return &service.S3BucketObjectsListerOutput{Objects: objects}, nil
}
Loading

0 comments on commit 7e0bfa3

Please sign in to comment.