Skip to content

Commit

Permalink
Merge pull request #2 from isd-sgcu/feature/s3client
Browse files Browse the repository at this point in the history
Feature/s3client
  • Loading branch information
bookpanda authored Dec 31, 2023
2 parents 3cad41b + d45adb6 commit 660ca3a
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 43 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ publish:

mock-gen:
mockgen -source ./pkg/repository/image/image.repository.go -destination ./mocks/repository/image/image.mock.go
mockgen -source ./pkg/client/bucket/bucket.client.go -destination ./mocks/client/bucket/bucket.mock.go

test:
go vet ./...
Expand Down
1 change: 1 addition & 0 deletions cfgldr/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Database struct {

type S3 struct {
BucketName string `mapstructure:"bucket_name"`
Region string `mapstructure:"region"`
}

type App struct {
Expand Down
81 changes: 81 additions & 0 deletions client/bucket/bucket.client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package bucket

import (
"bytes"
"context"
"fmt"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/isd-sgcu/johnjud-file/cfgldr"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)

type Client struct {
conf cfgldr.S3
s3 *s3.Client
}

func NewClient(conf cfgldr.S3, awsClient *s3.Client) *Client {
return &Client{conf: conf, s3: awsClient}
}

func (c *Client) Upload(file []byte, objectKey string) (string, string, error) {
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 50*time.Second)
defer cancel()

buffer := bytes.NewReader(file)
var partMiBs int64 = 10
uploader := manager.NewUploader(c.s3, func(u *manager.Uploader) {
u.PartSize = partMiBs * 1024 * 1024
})

uploadOutput, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{
Bucket: aws.String(c.conf.BucketName),
Key: aws.String(objectKey),
Body: buffer,
})

if err != nil {
log.Error().
Err(err).
Str("service", "file").
Str("module", "bucket client").
Msgf("Couldn't upload object to %v:%v.", c.conf.BucketName, objectKey)

return "", "", errors.Wrap(err, "Error while uploading the object")
}

return fmt.Sprintf("https://%v.s3.%v.amazonaws.com/%v", c.conf.Region, c.conf.BucketName, uploadOutput.Key), *uploadOutput.Key, nil
}

func (c *Client) Delete(objectKey string) error {
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 50*time.Second)
defer cancel()

var objectIds []types.ObjectIdentifier
objectIds = append(objectIds, types.ObjectIdentifier{Key: aws.String(objectKey)})

_, err := c.s3.DeleteObjects(context.TODO(), &s3.DeleteObjectsInput{
Bucket: aws.String(c.conf.BucketName),
Delete: &types.Delete{Objects: objectIds},
})

if err != nil {
log.Error().
Err(err).
Str("service", "file").
Str("module", "bucket client").
Msgf("Couldn't delete object from bucket %v:%v.", c.conf.BucketName, objectKey)

return errors.Wrap(err, "Error while deleting the object")
}

return nil
}
165 changes: 164 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,168 @@
package main

import (
"context"
"fmt"
"net"
"os"
"os/signal"
"sync"
"syscall"
"time"

"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/isd-sgcu/johnjud-file/cfgldr"
"github.com/isd-sgcu/johnjud-file/database"
"github.com/isd-sgcu/johnjud-file/pkg/client/bucket"
imageRepo "github.com/isd-sgcu/johnjud-file/pkg/repository/image"
imageSvc "github.com/isd-sgcu/johnjud-file/pkg/service/image"
imagePb "github.com/isd-sgcu/johnjud-go-proto/johnjud/file/image/v1"
"github.com/rs/zerolog/log"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection"
)

type operation func(ctx context.Context) error

func gracefulShutdown(ctx context.Context, timeout time.Duration, ops map[string]operation) <-chan struct{} {
wait := make(chan struct{})
go func() {
s := make(chan os.Signal, 1)

signal.Notify(s, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
sig := <-s

log.Info().
Str("service", "graceful shutdown").
Msgf("got signal \"%v\" shutting down service", sig)

timeoutFunc := time.AfterFunc(timeout, func() {
log.Error().
Str("service", "graceful shutdown").
Msgf("timeout %v ms has been elapsed, force exit", timeout.Milliseconds())
os.Exit(0)
})

defer timeoutFunc.Stop()

var wg sync.WaitGroup

for key, op := range ops {
wg.Add(1)
innerOp := op
innerKey := key
go func() {
defer wg.Done()

log.Info().
Str("service", "graceful shutdown").
Msgf("cleaning up: %v", innerKey)
if err := innerOp(ctx); err != nil {
log.Error().
Str("service", "graceful shutdown").
Err(err).
Msgf("%v: clean up failed: %v", innerKey, err.Error())
return
}

log.Info().
Str("service", "graceful shutdown").
Msgf("%v was shutdown gracefully", innerKey)
}()
}

wg.Wait()
close(wait)
}()

return wait
}

func main() {
// Code
conf, err := cfgldr.LoadConfig()
if err != nil {
log.Fatal().
Err(err).
Str("service", "file").
Msg("Failed to load config")
}

db, err := database.InitPostgresDatabase(&conf.Database, conf.App.Debug)
if err != nil {
log.Fatal().
Err(err).
Str("service", "file").
Msg("Failed to init postgres connection")
}

sdkConfig, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
log.Fatal().
Err(err).
Str("service", "file").
Msg("Failed to load AWS SDK config")
return
}

lis, err := net.Listen("tcp", fmt.Sprintf(":%v", conf.App.Port))
if err != nil {
log.Fatal().
Err(err).
Str("service", "file").
Msg("Failed to start service")
}

grpcServer := grpc.NewServer()

awsClient := s3.NewFromConfig(sdkConfig)
bucketClient := bucket.NewClient(conf.S3, awsClient)

imageRepository := imageRepo.NewRepository(db)

imageService := imageSvc.NewService(bucketClient, imageRepository)

grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer())
imagePb.RegisterImageServiceServer(grpcServer, imageService)

reflection.Register(grpcServer)
go func() {
log.Info().
Str("service", "file").
Msgf("JohnJud file starting at port %v", conf.App.Port)

if err := grpcServer.Serve(lis); err != nil {
log.Fatal().
Err(err).
Str("service", "file").
Msg("Failed to start service")
}
}()

wait := gracefulShutdown(context.Background(), 2*time.Second, map[string]operation{
"server": func(ctx context.Context) error {
grpcServer.GracefulStop()
return nil
},
"database": func(ctx context.Context) error {
sqlDB, err := db.DB()
if err != nil {
return nil
}
return sqlDB.Close()
},
})

<-wait

grpcServer.GracefulStop()
log.Info().
Str("service", "file").
Msg("Closing the listener")
lis.Close()
log.Info().
Str("service", "file").
Msg("End the program")
}
3 changes: 2 additions & 1 deletion config/config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ database:
password: root

s3:
bucket_name: <bucket name>
bucket_name: <bucket name>
region: <region>
20 changes: 20 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ require (
)

require (
github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect
github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9 // indirect
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect
github.com/aws/smithy-go v1.19.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
Expand All @@ -25,6 +44,7 @@ require (
github.com/jackc/pgx/v5 v5.4.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
Expand Down
42 changes: 42 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk=
github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo=
github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc=
github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8=
github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8=
github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.9 h1:5zA8qVCXMPGt6YneFnll5B157SfdK2SewU85PH9/yM0=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.9/go.mod h1:t4gy210hPxkbtYM8xOzrWdxVq1PyekR76OOKXy3s0Vs=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9/go.mod h1:Xjqy+Nyj7VDLBtCMkQYOw1QYfAEZCVLrfI0ezve8wd4=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrwK1SKFIJrA9pOJ5yu2eSHnmls=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 h1:ugD6qzjYtB7zM5PN/ZIeaAIyefPaD82G8+SJopgvUpw=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9/go.mod h1:YD0aYBWCrPENpHolhKw2XDlTIWae2GKXT1T4o6N6hiM=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9 h1:/90OR2XbSYfXucBMJ4U14wrjlfleq/0SB6dZDPncgmo=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9/go.mod h1:dN/Of9/fNZet7UrQQ6kTDo/VSwKPIq94vjlU16bRARc=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJR8CSImIVCONRi4g0Su3J+TSTbS7G0pUeMU=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9 h1:iEAeF6YC3l4FzlJPP9H3Ko1TXpdjdqWffxXjp8SY6uk=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9/go.mod h1:kjsXoK23q9Z/tLBrckZLLyvjhZoS+AGrzqzUfEClvMM=
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.7 h1:o0ASbVwUAIrfp/WcCac+6jioZt4Hd8k/1X8u7GJ/QeM=
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.7/go.mod h1:vADO6Jn+Rq4nDtfwNjhgR84qkZwiC6FqCaXdw/kYwjA=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU=
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -32,6 +70,9 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand Down Expand Up @@ -136,6 +177,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
21 changes: 0 additions & 21 deletions internal/client/s3/s3.client.go

This file was deleted.

Loading

0 comments on commit 660ca3a

Please sign in to comment.