From 838154ce9c17959b2055d2549b837e3527be99a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A0Ilya=20Atamas?= Date: Mon, 22 Apr 2019 12:49:19 +0300 Subject: [PATCH] feat: database as plugin --- cli/list.go | 2 +- cli/main.go | 12 +++++++----- cli/purge.go | 2 +- cli/root.go | 4 ++-- example/main.go | 16 +++++++++------- proxy/cache.go | 20 ++++++++++---------- proxy/database_redis.go | 31 +++++++++++++++++++++++++++++++ proxy/main.go | 18 ++++++++++++------ proxy/server.go | 2 +- readme.md | 16 ++++++++-------- 10 files changed, 82 insertions(+), 41 deletions(-) create mode 100644 proxy/database_redis.go diff --git a/cli/list.go b/cli/list.go index b4a4d14..17e765d 100644 --- a/cli/list.go +++ b/cli/list.go @@ -14,7 +14,7 @@ var listCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { proxy := getProxy(func() (npmproxy.Options, error) { return npmproxy.Options{ - RedisPrefix: persistentOptions.RedisPrefix, + DatabasePrefix: persistentOptions.RedisPrefix, }, nil }) diff --git a/cli/main.go b/cli/main.go index 80b396c..132cab6 100644 --- a/cli/main.go +++ b/cli/main.go @@ -27,11 +27,13 @@ func init() { func getProxy(getOptions func() (npmproxy.Options, error)) *npmproxy.Proxy { return &npmproxy.Proxy{ - RedisClient: redis.NewClient(&redis.Options{ - Addr: persistentOptions.RedisAddress, - DB: persistentOptions.RedisDatabase, - Password: persistentOptions.RedisPassword, - }), + Database: npmproxy.DatabaseRedis{ + Client: redis.NewClient(&redis.Options{ + Addr: persistentOptions.RedisAddress, + DB: persistentOptions.RedisDatabase, + Password: persistentOptions.RedisPassword, + }), + }, HttpClient: &http.Client{ Transport: http.DefaultTransport, }, diff --git a/cli/purge.go b/cli/purge.go index 3112189..9f52f80 100644 --- a/cli/purge.go +++ b/cli/purge.go @@ -12,7 +12,7 @@ var purgeCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { proxy := getProxy(func() (npmproxy.Options, error) { return npmproxy.Options{ - RedisPrefix: persistentOptions.RedisPrefix, + DatabasePrefix: persistentOptions.RedisPrefix, }, nil }) diff --git a/cli/root.go b/cli/root.go index 0caa1cf..db18a16 100644 --- a/cli/root.go +++ b/cli/root.go @@ -31,8 +31,8 @@ func init() { func run(cmd *cobra.Command, args []string) { proxy := getProxy(func() (npmproxy.Options, error) { return npmproxy.Options{ - RedisPrefix: persistentOptions.RedisPrefix, - RedisExpireTimeout: time.Duration(rootOptions.CacheTTL) * time.Second, + DatabasePrefix: persistentOptions.RedisPrefix, + DatabaseExpiration: time.Duration(rootOptions.CacheTTL) * time.Second, UpstreamAddress: rootOptions.UpstreamAddress, }, nil }) diff --git a/example/main.go b/example/main.go index 33ec560..be04d87 100644 --- a/example/main.go +++ b/example/main.go @@ -10,16 +10,18 @@ import ( func main() { proxy := npmproxy.Proxy{ - RedisClient: redis.NewClient(&redis.Options{ - Addr: "localhost:6379", - DB: 0, - Password: "", - }), + Database: npmproxy.DatabaseRedis{ + Client: redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + DB: 0, + Password: "", + }), + }, HttpClient: &http.Client{}, GetOptions: func() (npmproxy.Options, error) { return npmproxy.Options{ - RedisPrefix: "ncp-", - RedisExpireTimeout: 1 * time.Hour, + DatabasePrefix: "ncp-", + DatabaseExpiration: 1 * time.Hour, UpstreamAddress: "https://registry.npmjs.org", }, nil }, diff --git a/proxy/cache.go b/proxy/cache.go index c5817ab..1c89dc9 100644 --- a/proxy/cache.go +++ b/proxy/cache.go @@ -13,8 +13,8 @@ func (proxy Proxy) GetMetadata(name string, originalPath string, header http.Hea return nil, err } - // get package from redis - pkg, err := proxy.RedisClient.Get(options.RedisPrefix + name).Result() + // get package from database + pkg, err := proxy.Database.Get(options.DatabasePrefix + name) // either package doesn't exist or there's some other problem if err != nil { @@ -50,11 +50,11 @@ func (proxy Proxy) GetMetadata(name string, originalPath string, header http.Hea pkg = string(body) // save to redis - _, err = proxy.RedisClient.Set( - options.RedisPrefix+name, + err = proxy.Database.Set( + options.DatabasePrefix+name, pkg, - options.RedisExpireTimeout, - ).Result() + options.DatabaseExpiration, + ) if err != nil { return nil, err } @@ -74,14 +74,14 @@ func (proxy Proxy) ListMetadata() ([]string, error) { return nil, err } - metadata, err := proxy.RedisClient.Keys(options.RedisPrefix + "*").Result() + metadata, err := proxy.Database.Keys(options.DatabasePrefix) if err != nil { return nil, err } deprefixedMetadata := make([]string, 0) for _, record := range metadata { - deprefixedMetadata = append(deprefixedMetadata, strings.Replace(record, options.RedisPrefix, "", 1)) + deprefixedMetadata = append(deprefixedMetadata, strings.Replace(record, options.DatabasePrefix, "", 1)) } return deprefixedMetadata, nil @@ -94,13 +94,13 @@ func (proxy Proxy) PurgeMetadata() error { return err } - metadata, err := proxy.RedisClient.Keys(options.RedisPrefix + "*").Result() + metadata, err := proxy.Database.Keys(options.DatabasePrefix) if err != nil { return err } for _, record := range metadata { - _, err := proxy.RedisClient.Del(record).Result() + err := proxy.Database.Delete(record) if err != nil { return err } diff --git a/proxy/database_redis.go b/proxy/database_redis.go new file mode 100644 index 0000000..f7caa52 --- /dev/null +++ b/proxy/database_redis.go @@ -0,0 +1,31 @@ +package proxy + +import ( + "time" + + "github.com/go-redis/redis" +) + +type DatabaseRedis struct { + Client *redis.Client +} + +func (db DatabaseRedis) Get(key string) (string, error) { + return db.Client.Get(key).Result() +} + +func (db DatabaseRedis) Set(key string, value string, expiration time.Duration) error { + return db.Client.Set(key, value, expiration).Err() +} + +func (db DatabaseRedis) Delete(key string) error { + return db.Client.Del(key).Err() +} + +func (db DatabaseRedis) Keys(prefix string) ([]string, error) { + return db.Client.Keys(prefix + "*").Result() +} + +func (db DatabaseRedis) Health() error { + return db.Client.Ping().Err() +} diff --git a/proxy/main.go b/proxy/main.go index c1a523a..e5a7398 100644 --- a/proxy/main.go +++ b/proxy/main.go @@ -3,19 +3,25 @@ package proxy import ( "net/http" "time" - - "github.com/go-redis/redis" ) type Proxy struct { - RedisClient *redis.Client - HttpClient *http.Client + Database Database + HttpClient *http.Client GetOptions func() (Options, error) } type Options struct { - RedisPrefix string - RedisExpireTimeout time.Duration + DatabasePrefix string + DatabaseExpiration time.Duration UpstreamAddress string } + +type Database interface { + Get(key string) (string, error) + Set(key string, value string, ttl time.Duration) error + Delete(key string) error + Keys(prefix string) ([]string, error) + Health() error +} diff --git a/proxy/server.go b/proxy/server.go index 3695b0b..e08e626 100644 --- a/proxy/server.go +++ b/proxy/server.go @@ -52,7 +52,7 @@ func (proxy Proxy) NoRouteHandler(c *gin.Context) { // } else if c.Request.URL.Path == "/" { - _, err := proxy.RedisClient.Ping().Result() + err := proxy.Database.Health() if err != nil { c.AbortWithStatusJSON(503, err) diff --git a/readme.md b/readme.md index 7945b3d..39a5226 100644 --- a/readme.md +++ b/readme.md @@ -28,7 +28,7 @@ Start proxy server. | `--cache-ttl ` | `CACHE_TTL` | `3600` | Cache expiration timeout in seconds | | `--redis-address
` | `REDIS_ADDRESS` | `http://localhost:6379` | Redis address | | `--redis-database ` | `REDIS_DATABASE` | `0` | Redis database | -| `--redis-password ` | `REDIS_PASSWORD` | - | Redis password | +| `--redis-password ` | `REDIS_PASSWORD` | - | Redis password | | `--redis-prefix ` | `REDIS_PREFIX` | `ncp-` | Redis keys prefix | ### `ncp list` @@ -54,16 +54,16 @@ import ( func main() { proxy := npmproxy.Proxy{ - RedisClient: redis.NewClient(&redis.Options{ - Addr: "localhost:6379", - DB: 0, - Password: "", - }), + Database: npmproxy.DatabaseRedis{ + Client: redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + }), + }, HttpClient: &http.Client{}, GetOptions: func() (npmproxy.Options, error) { return npmproxy.Options{ - RedisPrefix: "ncp-", - RedisExpireTimeout: 1 * time.Hour, + DatabasePrefix: "ncp-", + DatabaseExpiration: 1 * time.Hour, UpstreamAddress: "https://registry.npmjs.org", }, nil },