1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-17 09:37:02 +00:00

storage: Make type/params configurable for #88

This commit is contained in:
James Hillyerd
2018-03-24 13:18:51 -07:00
parent bb0fb410c1
commit 281cc21412
8 changed files with 53 additions and 18 deletions

View File

@@ -69,10 +69,11 @@ type Web struct {
// Storage contains the mail store configuration.
type Storage struct {
Path string `required:"true" default:"/tmp/inbucket" desc:"Mail store path"`
RetentionPeriod time.Duration `required:"true" default:"24h" desc:"Duration to retain messages"`
RetentionSleep time.Duration `required:"true" default:"50ms" desc:"Duration to sleep between mailboxes"`
MailboxMsgCap int `required:"true" default:"500" desc:"Maximum messages per mailbox"`
Type string `required:"true" default:"memory" desc:"Storage impl: file or memory"`
Params map[string]string `desc:"Storage impl parameters, see docs."`
RetentionPeriod time.Duration `required:"true" default:"24h" desc:"Duration to retain messages"`
RetentionSleep time.Duration `required:"true" default:"50ms" desc:"Duration to sleep between mailboxes"`
MailboxMsgCap int `required:"true" default:"500" desc:"Maximum messages per mailbox"`
}
// Process loads and parses configuration from the environment.

View File

@@ -48,11 +48,10 @@ type Store struct {
}
// New creates a new DataStore object using the specified path
func New(cfg config.Storage) storage.Store {
path := cfg.Path
func New(cfg config.Storage) (storage.Store, error) {
path := cfg.Params["path"]
if path == "" {
log.Errorf("No value configured for datastore path")
return nil
return nil, fmt.Errorf("'path' parameter not specified")
}
mailPath := filepath.Join(path, "mail")
if _, err := os.Stat(mailPath); err != nil {
@@ -61,7 +60,7 @@ func New(cfg config.Storage) storage.Store {
log.Errorf("Error creating dir %q: %v", mailPath, err)
}
}
return &Store{path: path, mailPath: mailPath, messageCap: cfg.MailboxMsgCap}
return &Store{path: path, mailPath: mailPath, messageCap: cfg.MailboxMsgCap}, nil
}
// AddMessage adds a message to the specified mailbox.

View File

@@ -265,13 +265,18 @@ func setupDataStore(cfg config.Storage) (*Store, *bytes.Buffer) {
if err != nil {
panic(err)
}
// Capture log output
// Capture log output.
buf := new(bytes.Buffer)
log.SetOutput(buf)
cfg.Path = path
return New(cfg).(*Store), buf
if cfg.Params == nil {
cfg.Params = make(map[string]string)
}
cfg.Params["path"] = path
s, err := New(cfg)
if err != nil {
panic(err)
}
return s.(*Store), buf
}
// deliverMessage creates and delivers a message to the specific mailbox, returning

View File

@@ -6,6 +6,7 @@ import (
"strconv"
"sync"
"github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/pkg/storage"
)
@@ -25,10 +26,10 @@ type mbox struct {
var _ storage.Store = &Store{}
// New returns an emtpy memory store.
func New() *Store {
func New(cfg config.Storage) (storage.Store, error) {
return &Store{
boxes: make(map[string]*mbox),
}
}, nil
}
// AddMessage stores the message, message ID and Size will be ignored.

View File

@@ -3,6 +3,7 @@ package mem
import (
"testing"
"github.com/jhillyerd/inbucket/pkg/config"
"github.com/jhillyerd/inbucket/pkg/storage"
"github.com/jhillyerd/inbucket/pkg/test"
)
@@ -10,7 +11,7 @@ import (
// TestSuite runs storage package test suite on file store.
func TestSuite(t *testing.T) {
test.StoreSuite(t, func() (storage.Store, func(), error) {
s := New()
s, _ := New(config.Storage{})
destroy := func() {}
return s, destroy, nil
})

View File

@@ -3,9 +3,12 @@ package storage
import (
"errors"
"fmt"
"io"
"net/mail"
"time"
"github.com/jhillyerd/inbucket/pkg/config"
)
var (
@@ -14,6 +17,9 @@ var (
// ErrNotWritable indicates the message is closed; no longer writable
ErrNotWritable = errors.New("Message not writable")
// Constructors tracks registered storage constructors
Constructors = make(map[string]func(config.Storage) (Store, error))
)
// Store is the interface Inbucket uses to interact with storage implementations.
@@ -38,3 +44,11 @@ type Message interface {
Source() (io.ReadCloser, error)
Size() int64
}
// FromConfig creates an instance of the Store based on the provided configuration.
func FromConfig(c config.Storage) (store Store, err error) {
if cf := Constructors[c.Type]; cf != nil {
return cf(c)
}
return nil, fmt.Errorf("unknown storage type configured: %q", c.Type)
}