2015-07-29 10:00:04 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2017-12-28 01:40:20 +00:00
|
|
|
"context"
|
2015-07-29 10:00:04 +00:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/url"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2017-12-24 19:10:43 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
2015-07-29 10:00:04 +00:00
|
|
|
"github.com/xuyu/goredis"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
registerStorage("redis+tcp", newRedisStorage)
|
|
|
|
registerStorage("redis+udp", newRedisStorage)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RedisStorage implements a storage option for redis server
|
|
|
|
type RedisStorage struct {
|
|
|
|
conn *goredis.Redis
|
|
|
|
prefix string
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewRedisStorage checks config, creates the path and initializes a RedisStorage
|
|
|
|
func newRedisStorage(u *url.URL) (storageAdapter, error) {
|
|
|
|
client, err := goredis.DialURL(strings.Replace(u.String(), "redis+", "", -1))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &RedisStorage{
|
|
|
|
conn: client,
|
|
|
|
prefix: u.Query().Get("prefix"),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write store the data of a dataObject into the storage
|
2017-12-28 01:40:20 +00:00
|
|
|
func (r *RedisStorage) Write(ctx context.Context, identifier string, data io.Reader) error {
|
2015-07-29 10:00:04 +00:00
|
|
|
d, err := ioutil.ReadAll(data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.conn.Set(r.prefix+identifier, string(d), 0, 0, false, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read reads the data of a dataObject from the storage
|
2017-12-28 01:40:20 +00:00
|
|
|
func (r *RedisStorage) Read(ctx context.Context, identifier string) (io.Reader, error) {
|
2015-07-29 10:00:04 +00:00
|
|
|
content, err := r.conn.Get(r.prefix + identifier)
|
|
|
|
return bytes.NewReader(content), err
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsPresent checks for the presence of an userfile identifier
|
2017-12-28 01:40:20 +00:00
|
|
|
func (r *RedisStorage) IsPresent(ctx context.Context, identifier string) bool {
|
2015-07-29 10:00:04 +00:00
|
|
|
e, err := r.conn.Exists(r.prefix + identifier)
|
|
|
|
if err != nil {
|
2017-12-24 19:10:43 +00:00
|
|
|
log.WithError(err).WithFields(log.Fields{
|
|
|
|
"storagedriver": "redis",
|
|
|
|
"identifier": identifier,
|
|
|
|
}).Error("Unable to check key existence")
|
2015-07-29 10:00:04 +00:00
|
|
|
}
|
|
|
|
return e && err == nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Backup creates a backup of the old data
|
2017-12-28 01:40:20 +00:00
|
|
|
func (r *RedisStorage) Backup(ctx context.Context, identifier string) error {
|
2015-07-29 10:00:04 +00:00
|
|
|
ts := strconv.FormatInt(time.Now().Unix(), 10)
|
2017-12-28 01:40:20 +00:00
|
|
|
data, err := r.Read(ctx, identifier)
|
2015-07-29 10:00:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-12-28 01:40:20 +00:00
|
|
|
return r.Write(ctx, identifier+":backup:"+ts, data)
|
2015-07-29 10:00:04 +00:00
|
|
|
}
|