diff --git a/s3_utils/s3_utils.go b/s3/s3.go similarity index 59% rename from s3_utils/s3_utils.go rename to s3/s3.go index f1c304962f1801d78bd681fd3661676bca7a0992..f5b2c405275bb0312ba0a753a1d2106baabc7bde 100644 --- a/s3_utils/s3_utils.go +++ b/s3/s3.go @@ -1,4 +1,4 @@ -package s3_utils +package s3 import ( "bytes" @@ -11,13 +11,10 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" "github.com/google/uuid" ) -var s3Session *s3.S3 - // S3UploadResponse defines the structure of a standard JSON response to a PDF/CSV/etc request. type S3UploadResponse struct { URL string `json:"url"` @@ -29,16 +26,16 @@ type S3UploadResponse struct { type MIMEType string const ( - // TypePDF defines the constant for the PDF MIME type. + // MIMETypePDF defines the constant for the PDF MIME type. MIMETypePDF MIMEType = "application/pdf" - // TypeCSV defines the constant for the CSV MIME type. + // MIMETypeCSV defines the constant for the CSV MIME type. MIMETypeCSV MIMEType = "text/csv" - // TypeZIP defines the constant for the ZIP MIME type. + // MIMETypeZIP defines the constant for the ZIP MIME type. MIMETypeZIP MIMEType = "application/zip" - // TypeJSON defines the constant for the JSON MIME type. + // MIMETypeJSON defines the constant for the JSON MIME type. MIMETypeJSON MIMEType = "application/json" // MIMETypeText defines the constant for the Plain text MIME type. @@ -47,11 +44,21 @@ const ( // MIMETypeImage defines the constant for the Image MIME type. MIMETypeImage MIMEType = "image/*" - // TypeDefault defines the constant for the default MIME type. + // MIMETypeDefault defines the constant for the default MIME type. MIMETypeDefault MIMEType = "application/octet-stream" ) -func Upload(data []byte, bucket, fileName string, metadata *map[string]*string, isDebug bool) (*s3.PutObjectOutput, error) { +type SessionWithHelpers struct { + S3Session *s3.S3 +} + +func NewSession(session *s3.S3) *SessionWithHelpers { + return &SessionWithHelpers{ + S3Session: session, + } +} + +func (s SessionWithHelpers) Upload(data []byte, bucket, fileName string, metadata *map[string]*string, isDebug bool) (*s3.PutObjectOutput, error) { mimeType := getTypeForFilename(fileName) putInput := &s3.PutObjectInput{ Bucket: aws.String(bucket), @@ -64,7 +71,7 @@ func Upload(data []byte, bucket, fileName string, metadata *map[string]*string, putInput.Metadata = *metadata } - response, err := getSession(isDebug).PutObject(putInput) + response, err := s.S3Session.PutObject(putInput) if err != nil { return nil, err } @@ -72,7 +79,7 @@ func Upload(data []byte, bucket, fileName string, metadata *map[string]*string, return response, nil } -func UploadWithExpiry(data []byte, bucket, fileName string, mimeType MIMEType, isDebug bool) (string, error) { +func (s SessionWithHelpers) UploadWithExpiry(data []byte, bucket, fileName string, mimeType MIMEType, isDebug bool) (string, error) { if mimeType == "" { mimeType = getTypeForFilename(fileName) } @@ -86,30 +93,30 @@ func UploadWithExpiry(data []byte, bucket, fileName string, mimeType MIMEType, i Expires: &expiry, } - _, err := getSession(isDebug).PutObject(putInput) + _, err := s.S3Session.PutObject(putInput) if err != nil { return "", err } - return GetSignedDownloadURL(bucket, fileName, 24*time.Hour, isDebug) + return s.GetSignedDownloadURL(bucket, fileName, 24*time.Hour, isDebug) } // GetSignedDownloadURL gets a signed download URL for the duration. If scv is nil, a new session will be created. -func GetSignedDownloadURL(bucket string, fileName string, duration time.Duration, isDebug bool) (string, error) { +func (s SessionWithHelpers) GetSignedDownloadURL(bucket string, fileName string, duration time.Duration, isDebug bool) (string, error) { getInput := &s3.GetObjectInput{ Bucket: aws.String(bucket), Key: aws.String(fileName), } - getRequest, _ := getSession(isDebug).GetObjectRequest(getInput) + getRequest, _ := s.S3Session.GetObjectRequest(getInput) return getRequest.Presign(duration) } // UploadWithFileExtension will upload a file to S3 and return a standard S3UploadResponse. -func UploadWithFileExtension(data []byte, bucket, filePrefix string, fileExt string, mimeType MIMEType, isDebug bool) (*S3UploadResponse, error) { +func (s SessionWithHelpers) UploadWithFileExtension(data []byte, bucket, filePrefix string, fileExt string, mimeType MIMEType, isDebug bool) (*S3UploadResponse, error) { fileName := fmt.Sprintf("%s_%s.%s", filePrefix, uuid.New().String(), fileExt) - uploadUrl, err := UploadWithExpiry(data, bucket, fileName, mimeType, isDebug) + uploadUrl, err := s.UploadWithExpiry(data, bucket, fileName, mimeType, isDebug) if err != nil { return nil, err } @@ -143,24 +150,24 @@ func getTypeForFilename(f string) MIMEType { return MIMETypeDefault } -func GetObject(bucket string, fileName string, isDebug bool) (*s3.GetObjectOutput, error) { +func (s SessionWithHelpers) GetObject(bucket string, fileName string, isDebug bool) (*s3.GetObjectOutput, error) { getInput := &s3.GetObjectInput{ Bucket: aws.String(bucket), Key: aws.String(fileName), } - getObjectOutput, err := getSession(isDebug).GetObject(getInput) + getObjectOutput, err := s.S3Session.GetObject(getInput) if err != nil { return nil, err } return getObjectOutput, nil } -func GetObjectMetadata(bucket string, fileName string, isDebug bool) (map[string]*string, error) { +func (s SessionWithHelpers) GetObjectMetadata(bucket string, fileName string, isDebug bool) (map[string]*string, error) { headObjectInput := &s3.HeadObjectInput{ Bucket: aws.String(bucket), Key: aws.String(fileName), } - headObjectOutput, err := getSession(isDebug).HeadObject(headObjectInput) + headObjectOutput, err := s.S3Session.HeadObject(headObjectInput) if err != nil { return nil, err } @@ -168,14 +175,14 @@ func GetObjectMetadata(bucket string, fileName string, isDebug bool) (map[string } // MoveObjectBucketToBucket - Move object from one S3 bucket to another -func MoveObjectBucketToBucket(sourceBucket string, destinationBucket string, sourceFileName string, destinationFileName string, isDebug bool) error { +func (s SessionWithHelpers) MoveObjectBucketToBucket(sourceBucket string, destinationBucket string, sourceFileName string, destinationFileName string, isDebug bool) error { - err := CopyObjectBucketToBucket(sourceBucket, destinationBucket, sourceFileName, destinationFileName, isDebug) + err := s.CopyObjectBucketToBucket(sourceBucket, destinationBucket, sourceFileName, destinationFileName, isDebug) if err != nil { return err } - err = DeleteObjectFromBucket(sourceBucket, sourceFileName, isDebug) + err = s.DeleteObjectFromBucket(sourceBucket, sourceFileName, isDebug) if err != nil { return err } @@ -184,7 +191,7 @@ func MoveObjectBucketToBucket(sourceBucket string, destinationBucket string, sou } // CopyObjectBucketToBucket - Copy an object from one S3 bucket to another -func CopyObjectBucketToBucket(sourceBucket string, destinationBucket string, sourceFileName string, destinationFilename string, isDebug bool) error { +func (s SessionWithHelpers) CopyObjectBucketToBucket(sourceBucket string, destinationBucket string, sourceFileName string, destinationFilename string, isDebug bool) error { // copy the file copySource := url.QueryEscape(sourceBucket + "/" + sourceFileName) copyObjectInput := &s3.CopyObjectInput{ @@ -192,13 +199,13 @@ func CopyObjectBucketToBucket(sourceBucket string, destinationBucket string, sou CopySource: aws.String(copySource), //source path (ie: myBucket/myFile.csv) Key: aws.String(destinationFilename), //filename on destination } - _, err := getSession(isDebug).CopyObject(copyObjectInput) + _, err := s.S3Session.CopyObject(copyObjectInput) if err != nil { return err } // wait to see if the file copied successfully - err = getSession(isDebug).WaitUntilObjectExists(&s3.HeadObjectInput{Bucket: aws.String(destinationBucket), Key: aws.String(destinationFilename)}) + err = s.S3Session.WaitUntilObjectExists(&s3.HeadObjectInput{Bucket: aws.String(destinationBucket), Key: aws.String(destinationFilename)}) if err != nil { return err } @@ -207,19 +214,19 @@ func CopyObjectBucketToBucket(sourceBucket string, destinationBucket string, sou } // DeleteObjectFromBucket - Delete an object from an S3 bucket -func DeleteObjectFromBucket(bucket string, fileName string, isDebug bool) error { +func (s SessionWithHelpers) DeleteObjectFromBucket(bucket string, fileName string, isDebug bool) error { // delete the file deleteObjectInput := &s3.DeleteObjectInput{ Bucket: aws.String(bucket), Key: aws.String(fileName), } - _, err := getSession(isDebug).DeleteObject(deleteObjectInput) + _, err := s.S3Session.DeleteObject(deleteObjectInput) if err != nil { return err } // wait to see if the file deleted successfully - err = getSession(isDebug).WaitUntilObjectNotExists(&s3.HeadObjectInput{ + err = s.S3Session.WaitUntilObjectNotExists(&s3.HeadObjectInput{ Bucket: aws.String(bucket), // the bucket we are deleting from Key: aws.String(fileName), // the filename we are deleting }) @@ -247,41 +254,3 @@ func GetS3FileKey(fileName string, folder string) string { return "/" + folder + "/" + fileName } - -func ListObjects(bucketName string, maxKeys int64, function func(*s3.ListObjectsOutput, bool) bool, isDebug bool) error { - listObjectsInput := &s3.ListObjectsInput{ - Bucket: aws.String(bucketName), - MaxKeys: aws.Int64(maxKeys), - } - - err := getSession(isDebug).ListObjectsPages(listObjectsInput, function) - if err != nil { - return err - } - - return nil -} - -func getSession(isDebug bool) *s3.S3 { - if s3Session == nil { - env := os.Getenv("ENVIRONMENT") - options := session.Options{ - Config: aws.Config{ - Region: aws.String("af-south-1"), - }, - } - - if isDebug { - options.Profile = fmt.Sprintf("shiplogic-%s", env) - } - - sess, err := session.NewSessionWithOptions(options) - - if err != nil { - return nil - } - s3Session = s3.New(sess) - } - - return s3Session -}