diff --git a/cmd/stock/main.go b/cmd/stock/main.go index a1f9862..e246a10 100644 --- a/cmd/stock/main.go +++ b/cmd/stock/main.go @@ -35,7 +35,9 @@ func main() { log.Log.Panic(err) } grw := models.NewGoodReleaseWorker(config.GoodRelease) + cw := models.NewCacheWorker(config.CacheClean) go grw.Start() + go cw.Start() // Startwebsrver router := goji.NewMux() web.BindAPI(router) @@ -53,6 +55,7 @@ func main() { // Stop services srv.Close() grw.Close() + cw.Close() database.Close() log.Log.Info("received", sig) diff --git a/config_example.conf b/config_example.conf index ef50a03..8c7e367 100644 --- a/config_example.conf +++ b/config_example.conf @@ -1,5 +1,6 @@ webserver_bind = ":8080" + good_availablity_template = "contrib/good_availablity.svg" [database] @@ -10,5 +11,9 @@ connection = "file::memory:?mode=memory&cache=shared" # read_connection = "" [good_release] -timer = "5m" +every = "5m" +after = "30m" + +[cache_clean] +every = "5m" after = "30m" diff --git a/models/auth.go b/models/auth.go new file mode 100644 index 0000000..7b6bf08 --- /dev/null +++ b/models/auth.go @@ -0,0 +1,64 @@ +package models + +import ( + "fmt" + "net/http" + "time" + + "github.com/genofire/hs_master-kss-monolith/lib/log" +) + +// TODO DRAFT for a rest request to a other microservice +const PermissionURL = "https://google.com/?q=%sa%d" + +type Permission int + +const ( + PermissionCreateGood = 1 + PermissionDeleteGood = 2 +) + +type permissionMicroServiceCache struct { + LastCheck time.Time + session string + permissions map[Permission]boolMicroServiceCache +} + +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) { + return cache.Value, nil + } + } + + url := fmt.Sprintf(PermissionURL, c.session, p) + log.Log.WithField("url", url).Info("has permission?") + res, err := http.Get(url) + + c.permissions[p] = boolMicroServiceCache{ + LastCheck: c.LastCheck, + Value: (res.StatusCode == http.StatusOK), + } + return c.permissions[p].Value, err +} + +var permissionCache map[string]*permissionMicroServiceCache + +func init() { + permissionCache = make(map[string]*permissionMicroServiceCache) +} + +func HasPermission(session string, p Permission) (bool, error) { + _, ok := permissionCache[session] + if !ok { + permissionCache[session] = &permissionMicroServiceCache{ + LastCheck: time.Now(), + session: session, + permissions: make(map[Permission]boolMicroServiceCache), + } + } + return permissionCache[session].HasPermission(p) +} diff --git a/models/auth_test.go b/models/auth_test.go new file mode 100644 index 0000000..45503cb --- /dev/null +++ b/models/auth_test.go @@ -0,0 +1,15 @@ +package models + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAuth(t *testing.T) { + assert := assert.New(t) + + perm, err := HasPermission("session", PermissionCreateGood) + assert.NoError(err) + assert.True(perm) +} diff --git a/models/cache_worker.go b/models/cache_worker.go new file mode 100644 index 0000000..6d79d6e --- /dev/null +++ b/models/cache_worker.go @@ -0,0 +1,25 @@ +package models + +import "time" + +type CacheWorkerConfig struct { + Every Duration + After Duration +} + +func NewCacheWorker(config CacheWorkerConfig) (w *Worker) { + return NewWorker(config.Every.Duration, func() { + // Cache if product exists + for index, cache := range productExistCache { + if cache.LastCheck.After(time.Now().Add(-config.After.Duration)) { + delete(productExistCache, index) + } + } + // Cache for permissions + for index, cache := range permissionCache { + if cache.LastCheck.After(time.Now().Add(-config.After.Duration)) { + delete(permissionCache, index) + } + } + }) +} diff --git a/models/config.go b/models/config.go index 9bca021..1b19ac6 100644 --- a/models/config.go +++ b/models/config.go @@ -11,13 +11,11 @@ import ( //Config the config File of this daemon type Config struct { - WebserverBind string `toml:"webserver_bind"` - Database database.Config `toml:"database"` - GoodAvailablityTemplate string `toml:"good_availablity_template"` - GoodRelease struct { - After Duration `toml:"after"` - Timer Duration `toml:"timer"` - } `toml:"good_release"` + WebserverBind string `toml:"webserver_bind"` + Database database.Config `toml:"database"` + GoodAvailablityTemplate string `toml:"good_availablity_template"` + GoodRelease GoodReleaseConfig `toml:"good_release"` + CacheClean CacheWorkerConfig `toml:"cache_clean"` } // ReadConfigFile reads a config model from path of a yml file diff --git a/models/good.go b/models/good.go index 56c41fd..f1fca0b 100644 --- a/models/good.go +++ b/models/good.go @@ -19,7 +19,7 @@ type Good struct { RecievedAt *time.Time `sql:"default:current_timestamp"` // Make it temporary unusable LockedAt *time.Time - LockedSecret string + LockedSecret string `json:"-"` // Make it unusable DeletedAt *time.Time Sended bool diff --git a/models/good_release.go b/models/good_release.go index ccb4623..c218450 100644 --- a/models/good_release.go +++ b/models/good_release.go @@ -4,45 +4,17 @@ import ( "time" "github.com/genofire/hs_master-kss-monolith/lib/database" - "github.com/genofire/hs_master-kss-monolith/lib/log" ) type GoodReleaseConfig struct { After Duration `toml:"after"` - Timer Duration `toml:"timer"` + Every Duration `toml:"every"` } -type GoodReleaseWorker struct { - unlockTimer time.Duration - unlockAfter time.Duration - quit chan struct{} -} - -func NewGoodReleaseWorker(grc GoodReleaseConfig) (rw *GoodReleaseWorker) { - rw = &GoodReleaseWorker{ - unlockTimer: grc.Timer.Duration, - unlockAfter: grc.After.Duration, - quit: make(chan struct{}), - } - return -} - -func (rw *GoodReleaseWorker) Start() { - ticker := time.NewTicker(rw.unlockTimer) - for { - select { - case <-ticker.C: - count := goodRelease(rw.unlockAfter) - log.Log.WithField("count", count).Info("goods released") - case <-rw.quit: - ticker.Stop() - return - } - } -} - -func (rw *GoodReleaseWorker) Close() { - close(rw.quit) +func NewGoodReleaseWorker(grc GoodReleaseConfig) *Worker { + return NewWorker(grc.Every.Duration, func() { + goodRelease(grc.After.Duration) + }) } func goodRelease(unlockAfter time.Duration) int64 { diff --git a/models/good_release_test.go b/models/good_release_test.go index 7c4ed8f..24989cd 100644 --- a/models/good_release_test.go +++ b/models/good_release_test.go @@ -32,7 +32,7 @@ func TestGoodRelease(t *testing.T) { assert.Equal(int64(1), count, "unlock after timeout") grw := NewGoodReleaseWorker(GoodReleaseConfig{ - Timer: Duration{Duration: time.Duration(3) * time.Millisecond}, + Every: Duration{Duration: time.Duration(3) * time.Millisecond}, After: Duration{Duration: time.Duration(5) * time.Millisecond}, }) go grw.Start() diff --git a/models/worker.go b/models/worker.go new file mode 100644 index 0000000..9b26ca0 --- /dev/null +++ b/models/worker.go @@ -0,0 +1,34 @@ +package models + +import "time" + +type Worker struct { + every time.Duration + run func() + quit chan struct{} +} + +func NewWorker(every time.Duration, f func()) (w *Worker) { + w = &Worker{ + every: every, + run: f, + quit: make(chan struct{}), + } + return +} + +func (w *Worker) Start() { + ticker := time.NewTicker(w.every) + for { + select { + case <-ticker.C: + w.run() + case <-w.quit: + ticker.Stop() + return + } + } +} +func (w *Worker) Close() { + close(w.quit) +} diff --git a/profile.cov b/profile.cov new file mode 100644 index 0000000..7be0896 --- /dev/null +++ b/profile.cov @@ -0,0 +1,103 @@ +mode: count +github.com/genofire/hs_master-kss-monolith/models/cache_worker.go:10.59,11.49 1 0 +github.com/genofire/hs_master-kss-monolith/models/cache_worker.go:11.49,13.47 1 0 +github.com/genofire/hs_master-kss-monolith/models/cache_worker.go:19.3,19.45 1 0 +github.com/genofire/hs_master-kss-monolith/models/cache_worker.go:13.47,14.69 1 0 +github.com/genofire/hs_master-kss-monolith/models/cache_worker.go:14.69,16.5 1 0 +github.com/genofire/hs_master-kss-monolith/models/cache_worker.go:19.45,20.69 1 0 +github.com/genofire/hs_master-kss-monolith/models/cache_worker.go:20.69,22.5 1 0 +github.com/genofire/hs_master-kss-monolith/models/worker.go:11.59,18.2 2 1 +github.com/genofire/hs_master-kss-monolith/models/worker.go:20.26,22.6 2 1 +github.com/genofire/hs_master-kss-monolith/models/worker.go:22.6,23.10 1 6 +github.com/genofire/hs_master-kss-monolith/models/worker.go:24.19,25.11 1 5 +github.com/genofire/hs_master-kss-monolith/models/worker.go:26.17,28.10 2 1 +github.com/genofire/hs_master-kss-monolith/models/worker.go:32.26,34.2 1 1 +github.com/genofire/hs_master-kss-monolith/models/good_release.go:14.58,15.46 1 1 +github.com/genofire/hs_master-kss-monolith/models/good_release.go:15.46,17.3 1 5 +github.com/genofire/hs_master-kss-monolith/models/good_release.go:20.51,23.2 2 7 +github.com/genofire/hs_master-kss-monolith/models/product_cache.go:21.13,23.2 1 1 +github.com/genofire/hs_master-kss-monolith/models/product_cache.go:25.42,26.46 1 2 +github.com/genofire/hs_master-kss-monolith/models/product_cache.go:34.2,42.43 5 1 +github.com/genofire/hs_master-kss-monolith/models/product_cache.go:26.46,29.38 2 1 +github.com/genofire/hs_master-kss-monolith/models/product_cache.go:29.38,31.4 1 1 +github.com/genofire/hs_master-kss-monolith/models/auth.go:27.81,29.39 2 1 +github.com/genofire/hs_master-kss-monolith/models/auth.go:37.2,45.36 5 1 +github.com/genofire/hs_master-kss-monolith/models/auth.go:29.39,32.38 2 0 +github.com/genofire/hs_master-kss-monolith/models/auth.go:32.38,34.4 1 0 +github.com/genofire/hs_master-kss-monolith/models/auth.go:50.13,52.2 1 1 +github.com/genofire/hs_master-kss-monolith/models/auth.go:54.64,56.9 2 1 +github.com/genofire/hs_master-kss-monolith/models/auth.go:63.2,63.50 1 1 +github.com/genofire/hs_master-kss-monolith/models/auth.go:56.9,62.3 1 1 +github.com/genofire/hs_master-kss-monolith/models/config.go:22.42,25.16 3 3 +github.com/genofire/hs_master-kss-monolith/models/config.go:29.2,29.53 1 2 +github.com/genofire/hs_master-kss-monolith/models/config.go:33.2,33.15 1 1 +github.com/genofire/hs_master-kss-monolith/models/config.go:25.16,27.3 1 1 +github.com/genofire/hs_master-kss-monolith/models/config.go:29.53,31.3 1 1 +github.com/genofire/hs_master-kss-monolith/models/duration.go:19.67,21.30 2 20 +github.com/genofire/hs_master-kss-monolith/models/duration.go:28.2,28.19 1 19 +github.com/genofire/hs_master-kss-monolith/models/duration.go:32.2,34.16 3 18 +github.com/genofire/hs_master-kss-monolith/models/duration.go:38.2,38.14 1 17 +github.com/genofire/hs_master-kss-monolith/models/duration.go:55.2,55.12 1 16 +github.com/genofire/hs_master-kss-monolith/models/duration.go:22.14,23.32 1 19 +github.com/genofire/hs_master-kss-monolith/models/duration.go:24.10,25.63 1 1 +github.com/genofire/hs_master-kss-monolith/models/duration.go:28.19,30.3 1 1 +github.com/genofire/hs_master-kss-monolith/models/duration.go:34.16,36.3 1 1 +github.com/genofire/hs_master-kss-monolith/models/duration.go:39.11,40.50 1 2 +github.com/genofire/hs_master-kss-monolith/models/duration.go:41.11,42.50 1 6 +github.com/genofire/hs_master-kss-monolith/models/duration.go:43.11,44.48 1 2 +github.com/genofire/hs_master-kss-monolith/models/duration.go:45.11,46.53 1 2 +github.com/genofire/hs_master-kss-monolith/models/duration.go:47.11,48.57 1 2 +github.com/genofire/hs_master-kss-monolith/models/duration.go:49.11,50.59 1 2 +github.com/genofire/hs_master-kss-monolith/models/duration.go:51.10,52.63 1 1 +github.com/genofire/hs_master-kss-monolith/models/good.go:28.54,30.2 1 1 +github.com/genofire/hs_master-kss-monolith/models/good.go:32.36,36.2 3 1 +github.com/genofire/hs_master-kss-monolith/models/good.go:37.30,39.2 1 4 +github.com/genofire/hs_master-kss-monolith/models/good.go:40.44,41.30 1 2 +github.com/genofire/hs_master-kss-monolith/models/good.go:46.2,46.35 1 1 +github.com/genofire/hs_master-kss-monolith/models/good.go:41.30,45.3 3 1 +github.com/genofire/hs_master-kss-monolith/models/good.go:49.13,51.2 1 1 +github.com/genofire/hs_master-kss-monolith/lib/log/main.go:14.13,18.2 2 1 +github.com/genofire/hs_master-kss-monolith/lib/log/main.go:21.42,23.18 2 1 +github.com/genofire/hs_master-kss-monolith/lib/log/main.go:26.2,30.4 1 1 +github.com/genofire/hs_master-kss-monolith/lib/log/main.go:23.18,25.3 1 1 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:25.33,29.16 4 4 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:32.2,37.36 6 3 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:51.2,52.8 2 2 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:29.16,31.3 1 1 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:37.36,40.17 3 2 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:43.3,47.60 5 1 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:40.17,42.4 1 1 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:48.3,50.3 1 1 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:55.14,58.36 3 2 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:61.2,61.12 1 2 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:58.36,60.3 1 1 +github.com/genofire/hs_master-kss-monolith/lib/database/main.go:64.30,66.2 1 2 +github.com/genofire/hs_master-kss-monolith/lib/http/main.go:10.56,11.56 1 2 +github.com/genofire/hs_master-kss-monolith/lib/http/main.go:15.2,16.8 2 1 +github.com/genofire/hs_master-kss-monolith/lib/http/main.go:11.56,14.3 2 1 +github.com/genofire/hs_master-kss-monolith/lib/http/main.go:20.53,22.16 2 2 +github.com/genofire/hs_master-kss-monolith/lib/http/main.go:26.2,27.13 2 1 +github.com/genofire/hs_master-kss-monolith/lib/http/main.go:22.16,25.3 2 1 +github.com/genofire/hs_master-kss-monolith/http/main.go:8.32,12.2 3 3 +github.com/genofire/hs_master-kss-monolith/http/status.go:12.53,31.2 8 1 +github.com/genofire/hs_master-kss-monolith/http/good.go:16.56,19.16 3 3 +github.com/genofire/hs_master-kss-monolith/http/good.go:24.2,27.30 4 2 +github.com/genofire/hs_master-kss-monolith/http/good.go:32.2,33.18 2 1 +github.com/genofire/hs_master-kss-monolith/http/good.go:19.16,23.3 3 1 +github.com/genofire/hs_master-kss-monolith/http/good.go:27.30,31.3 3 1 +github.com/genofire/hs_master-kss-monolith/http/good.go:36.91,39.16 3 4 +github.com/genofire/hs_master-kss-monolith/http/good.go:44.2,47.16 4 3 +github.com/genofire/hs_master-kss-monolith/http/good.go:51.2,51.9 1 3 +github.com/genofire/hs_master-kss-monolith/http/good.go:56.2,58.24 3 3 +github.com/genofire/hs_master-kss-monolith/http/good.go:39.16,43.3 3 1 +github.com/genofire/hs_master-kss-monolith/http/good.go:47.16,50.3 2 0 +github.com/genofire/hs_master-kss-monolith/http/good.go:51.9,55.3 3 0 +github.com/genofire/hs_master-kss-monolith/http/good.go:60.65,62.15 2 4 +github.com/genofire/hs_master-kss-monolith/http/good.go:65.2,66.38 2 3 +github.com/genofire/hs_master-kss-monolith/http/good.go:72.2,72.18 1 3 +github.com/genofire/hs_master-kss-monolith/http/good.go:62.15,64.3 1 1 +github.com/genofire/hs_master-kss-monolith/http/good.go:67.26,68.22 1 2 +github.com/genofire/hs_master-kss-monolith/http/good.go:69.10,70.34 1 1 +github.com/genofire/hs_master-kss-monolith/http/good_temp.go:13.38,15.2 1 1 +github.com/genofire/hs_master-kss-monolith/http/good_temp.go:17.56,19.2 1 1 +github.com/genofire/hs_master-kss-monolith/http/good_temp.go:21.62,37.2 10 1