Skip to content

Commit

Permalink
fix upload with seeker reset, update interfaces to stores
Browse files Browse the repository at this point in the history
Signed-off-by: Sarah Funkhouser <[email protected]>
  • Loading branch information
golanglemonade committed Oct 13, 2024
1 parent d86af7f commit 24bd82c
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 6 deletions.
9 changes: 4 additions & 5 deletions internal/middleware/objects/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ import (
ent "github.com/theopenlane/core/internal/ent/generated"
"github.com/theopenlane/core/pkg/middleware/transaction"
"github.com/theopenlane/core/pkg/objects"
"github.com/theopenlane/core/pkg/objects/storage"
)

// Upload is the object that handles the file upload process
type Upload struct {
// ObjectStorage is the object storage configuration
ObjectStorage *objects.Objects
// Storage is the storage type to use, in this case, S3
Storage *storage.S3Store
// Storage is the storage type to use, this can be S3 or Disk
Storage objects.Storage
}

// FileUpload is the object that holds the file information
Expand Down Expand Up @@ -338,10 +337,10 @@ func (u *Upload) createFile(ctx context.Context, f FileUpload) (*ent.File, error
DetectedContentType: contentType,
Md5Hash: &md5Hash,
StoreKey: &f.Key,
StorageScheme: &u.Storage.Scheme,
StorageScheme: u.Storage.GetScheme(),
}

// get file contents
// get file contents to store in the database
contents, err := objects.StreamToByte(f.File)
if err != nil {
log.Error().Err(err).Str("file", f.Filename).Msg("failed to read file contents")
Expand Down
10 changes: 9 additions & 1 deletion pkg/objects/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@ import (
"os"

"github.com/gabriel-vasile/mimetype"
"github.com/rs/zerolog/log"
)

// StreamToByte function reads the content of the provided io.Reader and returns it as a byte slice
func StreamToByte(stream io.Reader) ([]byte, error) {
func StreamToByte(stream io.ReadSeeker) ([]byte, error) {
buf := new(bytes.Buffer)

if _, err := buf.ReadFrom(stream); err != nil {
return nil, err
}

// reset the file to the beginning
if _, err := stream.Seek(0, io.SeekStart); err != nil {
log.Error().Err(err).Msg("failed to reset file")

return nil, err
}

return buf.Bytes(), nil
}

Expand Down
47 changes: 47 additions & 0 deletions pkg/objects/mocks/mock_Storage.go

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

2 changes: 2 additions & 0 deletions pkg/objects/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type Storage interface {
Download(context.Context, string, *DownloadFileOptions) (*DownloadFileMetadata, io.ReadCloser, error)
// GetPresignedURL is used to get a presigned URL for a file in the storage backend
GetPresignedURL(context.Context, string) (string, error)
// GetScheme returns the scheme of the storage backend
GetScheme() *string
io.Closer
}

Expand Down
26 changes: 26 additions & 0 deletions pkg/objects/storage/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ type Disk struct {
Scheme string
}

// ensure Disk satisfies the Storage interface
var _ objects.Storage = &Disk{}

func NewDiskStorage(folder string) (*Disk, error) {
if len(strings.TrimSpace(folder)) == 0 {
return nil, fmt.Errorf("%w: please provide a valid folder path", ErrInvalidFolderPath)
Expand Down Expand Up @@ -45,3 +48,26 @@ func (d *Disk) Upload(ctx context.Context, r io.Reader, opts *objects.UploadFile
Key: opts.FileName,
}, err
}

// GetScheme returns the scheme of the storage backend
func (d *Disk) GetScheme() *string {
return &d.Scheme
}

// ManagerUpload uploads multiple files to disk
// TODO: Implement this method
func (d *Disk) ManagerUpload(ctx context.Context, files [][]byte) error {
return nil
}

// Download is used to download a file from the storage backend
// TODO: Implement this method
func (d *Disk) Download(ctx context.Context, key string, opts *objects.DownloadFileOptions) (*objects.DownloadFileMetadata, io.ReadCloser, error) {
return nil, nil, nil
}

// GetPresignedURL is used to get a presigned URL for a file in the storage backend
// TODO: Implement this method
func (d *Disk) GetPresignedURL(ctx context.Context, key string) (string, error) {
return "", nil
}
8 changes: 8 additions & 0 deletions pkg/objects/storage/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ var (
presignedURLTimeout = 15 * time.Minute
)

// ensure S3Store satisfies the Storage interface
var _ objects.Storage = &S3Store{}

// S3Options is used to configure the S3Store
type S3Options struct {
// Bucket to store objects in
Expand Down Expand Up @@ -185,3 +188,8 @@ func (s *S3Store) GetPresignedURLWithCustomDuration(ctx context.Context, key str

return presignURL.URL, nil
}

// GetScheme returns the scheme of the storage backend
func (s *S3Store) GetScheme() *string {
return &s.Scheme
}

0 comments on commit 24bd82c

Please sign in to comment.