storj/lib/uplink/bucket.go

148 lines
4.2 KiB
Go
Raw Normal View History

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package uplink
import (
"context"
"io"
"time"
"github.com/zeebo/errs"
"storj.io/storj/pkg/metainfo/kvmetainfo"
"storj.io/storj/pkg/storage/streams"
"storj.io/storj/pkg/storj"
"storj.io/storj/pkg/stream"
)
// Bucket represents operations you can perform on a bucket
type Bucket struct {
storj.Bucket
Config BucketConfig
metainfo *kvmetainfo.DB
streams streams.Store
pathCipher storj.Cipher
}
// OpenObject returns an Object handle, if authorized.
func (b *Bucket) OpenObject(ctx context.Context, path storj.Path) (o *Object, err error) {
defer mon.Task()(&ctx)(&err)
info, err := b.metainfo.GetObject(ctx, b.Name, path)
if err != nil {
return nil, err
}
return &Object{
Meta: ObjectMeta{
Bucket: info.Bucket.Name,
Path: info.Path,
IsPrefix: info.IsPrefix,
ContentType: info.ContentType,
Metadata: info.Metadata,
Created: info.Created,
Modified: info.Modified,
Expires: info.Expires,
Size: info.Size,
Checksum: info.Checksum,
Volatile: struct {
EncryptionParameters storj.EncryptionParameters
RedundancyScheme storj.RedundancyScheme
}{
EncryptionParameters: info.ToEncryptionParameters(),
RedundancyScheme: info.RedundancyScheme,
},
},
metainfo: b.metainfo,
streams: b.streams,
}, nil
}
// UploadOptions controls options about uploading a new Object, if authorized.
type UploadOptions struct {
// ContentType, if set, gives a MIME content-type for the Object.
ContentType string
// Metadata contains additional information about an Object. It can
// hold arbitrary textual fields and can be retrieved together with the
// Object. Field names can be at most 1024 bytes long. Field values are
// not individually limited in size, but the total of all metadata
// (fields and values) can not exceed 4 kiB.
Metadata map[string]string
// Expires is the time at which the new Object can expire (be deleted
// automatically from storage nodes).
Expires time.Time
// Volatile groups config values that are likely to change semantics
// or go away entirely between releases. Be careful when using them!
Volatile struct {
// EncryptionParameters determines the cipher suite to use for
// the Object's data encryption. If not set, the Bucket's
// defaults will be used.
EncryptionParameters storj.EncryptionParameters
// RedundancyScheme determines the Reed-Solomon and/or Forward
// Error Correction encoding parameters to be used for this
// Object.
RedundancyScheme storj.RedundancyScheme
}
}
// UploadObject uploads a new object, if authorized.
func (b *Bucket) UploadObject(ctx context.Context, path storj.Path, data io.Reader, opts *UploadOptions) (err error) {
defer mon.Task()(&ctx)(&err)
if opts == nil {
opts = &UploadOptions{}
}
createInfo := storj.CreateObject{
ContentType: opts.ContentType,
Metadata: opts.Metadata,
Expires: opts.Expires,
RedundancyScheme: opts.Volatile.RedundancyScheme,
EncryptionScheme: opts.Volatile.EncryptionParameters.ToEncryptionScheme(),
}
obj, err := b.metainfo.CreateObject(ctx, b.Name, path, &createInfo)
if err != nil {
return err
}
mutableStream, err := obj.CreateStream(ctx)
if err != nil {
return err
}
upload := stream.NewUpload(ctx, mutableStream, b.streams)
_, err = io.Copy(upload, data)
return errs.Combine(err, upload.Close())
}
// DeleteObject removes an object, if authorized.
func (b *Bucket) DeleteObject(ctx context.Context, path storj.Path) (err error) {
defer mon.Task()(&ctx)(&err)
return b.metainfo.DeleteObject(ctx, b.Bucket.Name, path)
}
// ListOptions controls options for the ListObjects() call.
type ListOptions = storj.ListOptions
// ListObjects lists objects a user is authorized to see.
// TODO(paul): should probably have a ListOptions defined in this package, for consistency's sake
func (b *Bucket) ListObjects(ctx context.Context, cfg *ListOptions) (list storj.ObjectList, err error) {
defer mon.Task()(&ctx)(&err)
if cfg == nil {
cfg = &storj.ListOptions{}
}
return b.metainfo.ListObjects(ctx, b.Bucket.Name, *cfg)
}
// Close closes the Bucket session.
func (b *Bucket) Close() error {
return nil
}