From 8103a9768c513bd676affe8d420d2b946346688b Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Wed, 5 Apr 2017 20:23:29 +0200 Subject: [PATCH] [TASK] move worker to lib + add permission handler to lib --- cmd/stock/main.go | 3 +- lib/http/{main.go => io.go} | 0 lib/http/{main_test.go => io_test.go} | 0 lib/http/permission.go | 26 +++++++++++++ lib/http/permission_test.go | 55 +++++++++++++++++++++++++++ {models => lib/worker}/worker.go | 2 +- lib/worker/worker_test.go | 24 ++++++++++++ models/auth.go | 5 +-- models/auth_test.go | 4 ++ models/cache_worker.go | 17 ++++++--- models/cache_worker_test.go | 24 ++++++++++++ models/good_release.go | 5 ++- models/product_cache.go | 6 +-- 13 files changed, 154 insertions(+), 17 deletions(-) rename lib/http/{main.go => io.go} (100%) rename lib/http/{main_test.go => io_test.go} (100%) create mode 100644 lib/http/permission.go create mode 100644 lib/http/permission_test.go rename {models => lib/worker}/worker.go (96%) create mode 100644 lib/worker/worker_test.go create mode 100644 models/cache_worker_test.go diff --git a/cmd/stock/main.go b/cmd/stock/main.go index e246a10..ff5bb55 100644 --- a/cmd/stock/main.go +++ b/cmd/stock/main.go @@ -27,6 +27,7 @@ func main() { // load config config = models.ReadConfigFile(configFile) web.GoodAvailablityTemplate = config.GoodAvailablityTemplate + models.CacheConfig = config.CacheClean log.Log.Info("Starting rezension monolith") @@ -35,7 +36,7 @@ func main() { log.Log.Panic(err) } grw := models.NewGoodReleaseWorker(config.GoodRelease) - cw := models.NewCacheWorker(config.CacheClean) + cw := models.NewCacheWorker() go grw.Start() go cw.Start() // Startwebsrver diff --git a/lib/http/main.go b/lib/http/io.go similarity index 100% rename from lib/http/main.go rename to lib/http/io.go diff --git a/lib/http/main_test.go b/lib/http/io_test.go similarity index 100% rename from lib/http/main_test.go rename to lib/http/io_test.go diff --git a/lib/http/permission.go b/lib/http/permission.go new file mode 100644 index 0000000..698e4f2 --- /dev/null +++ b/lib/http/permission.go @@ -0,0 +1,26 @@ +package http + +import "net/http" + +type HasPermission func(string, int) (bool, error) + +func PermissionHandler(h func(w http.ResponseWriter, r *http.Request), perm HasPermission, permission int) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + session, err := r.Cookie("session") + if err != nil { + http.Error(w, err.Error(), http.StatusNonAuthoritativeInfo) + return + } + ok, err := perm(session.Value, permission) + if err != nil { + http.Error(w, err.Error(), http.StatusGatewayTimeout) + return + } + if ok { + h(w, r) + return + } + http.Error(w, "Not allowed", http.StatusForbidden) + + } +} diff --git a/lib/http/permission_test.go b/lib/http/permission_test.go new file mode 100644 index 0000000..0086f4b --- /dev/null +++ b/lib/http/permission_test.go @@ -0,0 +1,55 @@ +package http + +import ( + "errors" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPermission(t *testing.T) { + assert := assert.New(t) + + w := httptest.NewRecorder() + r, _ := http.NewRequest("GET", "/", nil) + + // Request without session cookie + reached := false + PermissionHandler(func(w http.ResponseWriter, r *http.Request) { + reached = true + }, func(s string, i int) (bool, error) { + return true, nil + }, 1)(w, r) + assert.False(reached) + + r.AddCookie(&http.Cookie{Name: "session"}) + + // HasPermission respond a true + reached = false + PermissionHandler(func(w http.ResponseWriter, r *http.Request) { + reached = true + }, func(s string, i int) (bool, error) { + return true, nil + }, 1)(w, r) + assert.True(reached) + + // HasPermission respond a false + reached = false + PermissionHandler(func(w http.ResponseWriter, r *http.Request) { + reached = true + }, func(s string, i int) (bool, error) { + return false, nil + }, 1)(w, r) + assert.False(reached) + + // HasPermission respond a error + reached = false + PermissionHandler(func(w http.ResponseWriter, r *http.Request) { + reached = true + }, func(s string, i int) (bool, error) { + return false, errors.New("text") + }, 1)(w, r) + assert.False(reached) +} diff --git a/models/worker.go b/lib/worker/worker.go similarity index 96% rename from models/worker.go rename to lib/worker/worker.go index 9b26ca0..2353ce2 100644 --- a/models/worker.go +++ b/lib/worker/worker.go @@ -1,4 +1,4 @@ -package models +package worker import "time" diff --git a/lib/worker/worker_test.go b/lib/worker/worker_test.go new file mode 100644 index 0000000..c72f47d --- /dev/null +++ b/lib/worker/worker_test.go @@ -0,0 +1,24 @@ +package worker + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestWorker(t *testing.T) { + assert := assert.New(t) + + runtime := 0 + + w := NewWorker(time.Duration(5)*time.Millisecond, func() { + runtime = runtime + 1 + }) + go w.Start() + time.Sleep(time.Duration(18) * time.Millisecond) + w.Close() + + assert.Equal(3, runtime) + time.Sleep(time.Duration(8) * time.Millisecond) +} diff --git a/models/auth.go b/models/auth.go index 7b6bf08..0c94d64 100644 --- a/models/auth.go +++ b/models/auth.go @@ -27,9 +27,8 @@ type permissionMicroServiceCache struct { func (c *permissionMicroServiceCache) HasPermission(p Permission) (bool, error) { c.LastCheck = time.Now() if cache, ok := c.permissions[p]; ok { - // cache for 5min - before := time.Now().Add(-time.Minute * 5) - if !cache.LastCheck.Before(before) { + before := time.Now().Add(-CacheConfig.After.Duration) + if before.After(cache.LastCheck) { return cache.Value, nil } } diff --git a/models/auth_test.go b/models/auth_test.go index 45503cb..b290f99 100644 --- a/models/auth_test.go +++ b/models/auth_test.go @@ -12,4 +12,8 @@ func TestAuth(t *testing.T) { perm, err := HasPermission("session", PermissionCreateGood) assert.NoError(err) assert.True(perm) + + perm, err = HasPermission("session", PermissionCreateGood) + assert.NoError(err) + assert.True(perm) } diff --git a/models/cache_worker.go b/models/cache_worker.go index 6d79d6e..aa5b500 100644 --- a/models/cache_worker.go +++ b/models/cache_worker.go @@ -1,23 +1,30 @@ package models -import "time" +import ( + "time" + + "github.com/genofire/hs_master-kss-monolith/lib/worker" +) + +var CacheConfig CacheWorkerConfig type CacheWorkerConfig struct { Every Duration After Duration } -func NewCacheWorker(config CacheWorkerConfig) (w *Worker) { - return NewWorker(config.Every.Duration, func() { +func NewCacheWorker() (w *worker.Worker) { + return worker.NewWorker(CacheConfig.Every.Duration, func() { + before := time.Now().Add(-CacheConfig.After.Duration) // Cache if product exists for index, cache := range productExistCache { - if cache.LastCheck.After(time.Now().Add(-config.After.Duration)) { + if before.After(cache.LastCheck) { delete(productExistCache, index) } } // Cache for permissions for index, cache := range permissionCache { - if cache.LastCheck.After(time.Now().Add(-config.After.Duration)) { + if before.After(cache.LastCheck) { delete(permissionCache, index) } } diff --git a/models/cache_worker_test.go b/models/cache_worker_test.go new file mode 100644 index 0000000..046a761 --- /dev/null +++ b/models/cache_worker_test.go @@ -0,0 +1,24 @@ +package models + +import ( + "testing" + "time" +) + +func TestCacheWorker(t *testing.T) { + + productExistCache[2] = boolMicroServiceCache{LastCheck: time.Now(), Value: true} + permissionCache["blub"] = &permissionMicroServiceCache{ + LastCheck: time.Now(), + session: "blub", + permissions: make(map[Permission]boolMicroServiceCache), + } + CacheConfig = CacheWorkerConfig{ + Every: Duration{Duration: time.Duration(3) * time.Millisecond}, + After: Duration{Duration: time.Duration(5) * time.Millisecond}, + } + cw := NewCacheWorker() + go cw.Start() + time.Sleep(time.Duration(15) * time.Millisecond) + cw.Close() +} diff --git a/models/good_release.go b/models/good_release.go index c218450..0543e90 100644 --- a/models/good_release.go +++ b/models/good_release.go @@ -4,6 +4,7 @@ import ( "time" "github.com/genofire/hs_master-kss-monolith/lib/database" + "github.com/genofire/hs_master-kss-monolith/lib/worker" ) type GoodReleaseConfig struct { @@ -11,8 +12,8 @@ type GoodReleaseConfig struct { Every Duration `toml:"every"` } -func NewGoodReleaseWorker(grc GoodReleaseConfig) *Worker { - return NewWorker(grc.Every.Duration, func() { +func NewGoodReleaseWorker(grc GoodReleaseConfig) *worker.Worker { + return worker.NewWorker(grc.Every.Duration, func() { goodRelease(grc.After.Duration) }) } diff --git a/models/product_cache.go b/models/product_cache.go index 19061e1..4844f77 100644 --- a/models/product_cache.go +++ b/models/product_cache.go @@ -24,11 +24,7 @@ func init() { func (p *Product) Exists() (bool, error) { if cache, ok := productExistCache[p.ID]; ok { - // cache for 5min - before := time.Now().Add(-time.Minute * 5) - if !cache.LastCheck.Before(before) { - return cache.Value, nil - } + return cache.Value, nil } url := fmt.Sprintf(ProductURL, p.ID)