From 350b040a594ba97dbd5c95c8355707e79a401575 Mon Sep 17 00:00:00 2001 From: lash Date: Fri, 6 Sep 2024 01:28:51 +0100 Subject: [PATCH] Add storage retrieval solution for http handler --- cmd/http/main.go | 26 ++++++++++++------- cmd/main.go | 20 ++++++++++---- {http => internal/http}/server.go | 21 +++++++-------- internal/http/storage.go | 43 +++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 26 deletions(-) rename {http => internal/http}/server.go (88%) create mode 100644 internal/http/storage.go diff --git a/cmd/http/main.go b/cmd/http/main.go index 5c0db03..4a52b7b 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -17,8 +17,9 @@ import ( "git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/logging" + "git.grassecon.net/urdt/ussd/internal/handlers/ussd" - httpserver "git.grassecon.net/urdt/ussd/http" + httpserver "git.grassecon.net/urdt/ussd/internal/http" ) var ( @@ -77,7 +78,7 @@ func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, userdataStore return ussdHandlers, nil } -func getPersister(dbDir string, ctx context.Context) (*persist.Persister, error) { +func getStateStore(dbDir string, ctx context.Context) (db.Db, error) { err := os.MkdirAll(dbDir, 0700) if err != nil { return nil, fmt.Errorf("state dir create exited with error: %v\n", err) @@ -85,8 +86,7 @@ func getPersister(dbDir string, ctx context.Context) (*persist.Persister, error) store := gdbmdb.NewGdbmDb() storeFile := path.Join(dbDir, "state.gdbm") store.Connect(ctx, storeFile) - pr := persist.NewPersister(store) - return pr, nil + return store, nil } func getUserdataDb(dbDir string, ctx context.Context) db.Db { @@ -160,7 +160,7 @@ func main() { // os.Exit(1) // } - store := getUserdataDb(dbDir, ctx) + userdataStore := getUserdataDb(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -171,21 +171,27 @@ func main() { os.Exit(1) } - hl, err := getHandler(flagParser, dbResource, store) + hl, err := getHandler(flagParser, dbResource, userdataStore) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - sh := httpserver.NewSessionHandler(cfg, rs, store, hl.Init) + stateStore, err := getStateStore(dbDir, ctx) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + sh := httpserver.NewSessionHandler(cfg, rs, userdataStore, stateStore, hl.Init) s := &http.Server{ - Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(port)), + Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))), Handler: sh, } - err = engine.Loop(ctx, en, os.Stdin, os.Stdout) + err = s.ListenAndServe() if err != nil { - fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err) + fmt.Fprintf(os.Stderr, "Server error: %s", err) os.Exit(1) } } diff --git a/cmd/main.go b/cmd/main.go index 613eb68..e918806 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -34,10 +34,11 @@ func getFlags(fp string, debug bool) (*asm.FlagParser, error) { func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, pe *persist.Persister, userdataStore db.Db) (*ussd.Handlers, error) { - ussdHandlers, err := ussd.NewHandlers(appFlags, pe, userdataStore) + ussdHandlers, err := ussd.NewHandlers(appFlags, userdataStore) if err != nil { return nil, err } + ussdHandlers = ussdHandlers.WithPersister(pe) rs.AddLocalFunc("select_language", ussdHandlers.SetLanguage) rs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) rs.AddLocalFunc("save_pin", ussdHandlers.SavePin) @@ -104,6 +105,11 @@ func getResource(resourceDir string, ctx context.Context) (resource.Resource, er return rfs, nil } +func getEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) *engine.DefaultEngine { + en := engine.NewEngine(cfg, rs) + en = en.WithPersister(pr) + return en +} func main() { var dbDir string @@ -142,7 +148,7 @@ func main() { os.Exit(1) } - pr, err := getPersister(dbDir, ctx) + pe, err := getPersister(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -156,13 +162,17 @@ func main() { dbResource, ok := rs.(*resource.DbResource) if !ok { + fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - hl := getHandler(flagParser, dbResource, store) - hl = hl.WithPersister(pe) + hl, err := getHandler(flagParser, dbResource, pe, store) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } - en := getEngine(cfg, rs, pr) + en := getEngine(cfg, rs, pe) en = en.WithFirst(hl.Init) if debug { en = en.WithDebug(nil) diff --git a/http/server.go b/internal/http/server.go similarity index 88% rename from http/server.go rename to internal/http/server.go index 4cc4388..e8ae9c3 100644 --- a/http/server.go +++ b/internal/http/server.go @@ -4,7 +4,6 @@ import ( "fmt" "io/ioutil" "net/http" - "os" "git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/engine" @@ -37,14 +36,16 @@ type SessionHandler struct { rp RequestParser rs resource.Resource first resource.EntryFunc + provider StorageProvider } -func NewSessionHandler(cfg engine.Config, rs resource.Resource, userdataDb db.Db, first resource.EntryFunc) *SessionHandler { +func NewSessionHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, first resource.EntryFunc) *SessionHandler { return &SessionHandler{ cfgTemplate: cfg, rs: rs, first: first, rp: RequestParser{}, + provider: NewSimpleStorageProvider(stateDb, userdataDb), } } @@ -76,7 +77,12 @@ func(f *SessionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { cfg := f.cfgTemplate cfg.SessionId = sessionId - en := getEngine(cfg, f.rs, f.pr) + storage, err := f.provider.Get(cfg.SessionId) + if err != nil { + f.writeError(w, 500, "Storage retrieval fail", err) + return + } + en := getEngine(cfg, f.rs, storage.Persister) en = en.WithFirst(f.first) if cfg.EngineDebug { en = en.WithDebug(nil) @@ -87,17 +93,11 @@ func(f *SessionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } else { r, err = en.Exec(ctx, input) } - - _, err = en.Init(ctx) - if err != nil { - fmt.Fprintf(os.Stderr, "engine init exited with error: %v\n", err) - os.Exit(1) - } - if err != nil { f.writeError(w, 500, "Engine exec fail", err) return } + w.WriteHeader(200) w.Header().Set("Content-Type", "text/plain") _, err = en.WriteResult(ctx, w) @@ -111,7 +111,6 @@ func(f *SessionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } _ = r - } func getEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) *engine.DefaultEngine { diff --git a/internal/http/storage.go b/internal/http/storage.go new file mode 100644 index 0000000..eb17f92 --- /dev/null +++ b/internal/http/storage.go @@ -0,0 +1,43 @@ +package http + +import ( + "git.defalsify.org/vise.git/db" + "git.defalsify.org/vise.git/persist" +) + +type Storage struct { + Persister *persist.Persister + UserdataDb db.Db +} + +type StorageProvider interface { + Get(sessionId string) (Storage, error) + Put(sessionId string, storage Storage) error + Close() error +} + +type SimpleStorageProvider struct { + Storage +} + +func NewSimpleStorageProvider(stateStore db.Db, userdataStore db.Db) StorageProvider { + pe := persist.NewPersister(stateStore) + return &SimpleStorageProvider{ + Storage: Storage{ + Persister: pe, + UserdataDb: userdataStore, + }, + } +} + +func (*SimpleStorageProvider) Get(sessionId string) (Storage, error) { + return Storage{}, nil +} + +func (*SimpleStorageProvider) Put(sessionId string, storage Storage) error { + return nil +} + +func (*SimpleStorageProvider) Close() error { + return nil +}