Skip to content
This repository has been archived by the owner on Dec 8, 2020. It is now read-only.

Commit

Permalink
New: storage API.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Maher committed Aug 2, 2019
1 parent d2e7cee commit b68b742
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
79 changes: 79 additions & 0 deletions storage/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package storage

// Look here for various implementations:
// https://github.com/puppetlabs/nebula-libs/tree/master/storage"
//

import (
"context"
"io"
"fmt"
)

type ErrorCode string

const (
AuthError ErrorCode = "AuthError"
NotFoundError ErrorCode = "NotFoundError"
TimeoutError ErrorCode = "TimeoutError"
UnknownError ErrorCode = "UnknownError"
)

type errorImpl struct {
message string
code ErrorCode
cause error
}

func (e *errorImpl) Error() string {
return e.message
}

func (e *errorImpl) Unwrap() error {
return e.cause
}

func Errorf(cause error, code ErrorCode, format string, a ...interface{}) error {
return &errorImpl{
code: code,
message: fmt.Sprintf(format, a...),
cause: cause,
}
}

func IsAuthError(err error) bool {
e, ok := err.(*errorImpl)
return ok && e.code == AuthError
}

func IsNotFoundError(err error) bool {
e, ok := err.(*errorImpl)
return ok && e.code == NotFoundError
}

func IsTimeoutError(err error) bool {
e, ok := err.(*errorImpl)
return ok && e.code == TimeoutError
}

type Sink func(io.Writer) error
type Source func(*Meta, io.Reader) error

type Meta struct {
ContentType string
}
type PutOptions struct {
ContentType string
}
type GetOptions struct {
// TODO: Support range requests?
}
type DeleteOptions struct {
// TODO: Support conditional deletes?
}

type BlobStore interface {
Put(ctx context.Context, key string, sink Sink, opts PutOptions) error
Get(ctx context.Context, key string, source Source, opts GetOptions) error
Delete(ctx context.Context, key string, opts DeleteOptions) error
}
49 changes: 49 additions & 0 deletions storage/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package storage

import (
"fmt"
"net/url"
"strings"
"sync"
)

var (
factoriesMu sync.RWMutex
factories = make(map[string]BlobStoreFactory)
)

type BlobStoreFactory func(url.URL) (BlobStore, error)

func NewBlobStore(u url.URL) (BlobStore, error) {
scheme := strings.ToLower(u.Scheme)
factoriesMu.RLock()
factory, ok := factories[scheme]
factoriesMu.RUnlock()
if !ok {
return nil, fmt.Errorf("stroage: unknown scheme %q (forgotten import?)", scheme)
}
return factory(u)
}

func RegisterFactory(scheme string, factory BlobStoreFactory) {
scheme = strings.ToLower(scheme)
factoriesMu.Lock()
defer factoriesMu.Unlock()
if nil == factory {
panic("storage: RegisterFactory passed a nil factory")
}
if _, dup := factories[scheme]; dup {
panic("storage: RegisterFactory called twice for factory " + scheme)
}
factories[scheme] = factory
}

func SupportedSchemes() []string {
factoriesMu.RLock()
defer factoriesMu.RUnlock()
var list []string
for scheme := range factories {
list = append(list, scheme)
}
return list
}

0 comments on commit b68b742

Please sign in to comment.