From a9a429824c6ff2fa055e0bdc00914c4c4b3b4dc9 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Wed, 18 Sep 2024 14:52:56 +0300 Subject: [PATCH 01/15] return if the sessionId cannot be retrieved from the request --- internal/http/at_session_handler.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/http/at_session_handler.go b/internal/http/at_session_handler.go index 4a0cafa..a2a5188 100644 --- a/internal/http/at_session_handler.go +++ b/internal/http/at_session_handler.go @@ -32,6 +32,7 @@ func (ash *ATSessionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) if err != nil { logg.ErrorCtxf(rqs.Ctx, "", "header processing error", err) ash.writeError(w, 400, err) + return } rqs.Config = cfg rqs.Input, err = rp.GetInput(req) From 27aa71e0eede1bd4cd8939792f78f92a6eb9255a Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Wed, 18 Sep 2024 15:11:49 +0300 Subject: [PATCH 02/15] only set the code to 200 if no error exists --- internal/http/at_session_handler.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/internal/http/at_session_handler.go b/internal/http/at_session_handler.go index a2a5188..53c4ba2 100644 --- a/internal/http/at_session_handler.go +++ b/internal/http/at_session_handler.go @@ -42,16 +42,14 @@ func (ash *ATSessionHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) return } - rqs, err = ash.Process(rqs) + rqs, err = ash.Process(rqs) switch err { - case handlers.ErrStorage: - code = 500 - case handlers.ErrEngineInit: - code = 500 - case handlers.ErrEngineExec: + case nil: // set code to 200 if no err + code = 200 + case handlers.ErrStorage, handlers.ErrEngineInit, handlers.ErrEngineExec, handlers.ErrEngineType: code = 500 default: - code = 200 + code = 500 } if code != 200 { From 10de039da031781588f3f0b106abe81139412e68 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Wed, 18 Sep 2024 15:42:56 +0300 Subject: [PATCH 03/15] remove obsolete code --- internal/handlers/ussd/menuhandler.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index b01869b..805dcff 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -29,11 +29,6 @@ var ( translationDir = path.Join(scriptDir, "locale") ) -type FSData struct { - Path string - St *state.State -} - // FlagManager handles centralized flag management type FlagManager struct { parser *asm.FlagParser From 71e1ae6e3c09335ff4b180ce43d473a33395a0bd Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 15:54:23 +0300 Subject: [PATCH 04/15] add function registration service --- cmd/main.go | 132 ++++------------------------ internal/handlers/handlerservice.go | 99 +++++++++++++++++++++ 2 files changed, 115 insertions(+), 116 deletions(-) create mode 100644 internal/handlers/handlerservice.go diff --git a/cmd/main.go b/cmd/main.go index b9ca7aa..7e5bc0d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -7,15 +7,11 @@ import ( "os" "path" - "git.defalsify.org/vise.git/asm" - "git.defalsify.org/vise.git/db" - fsdb "git.defalsify.org/vise.git/db/fs" - gdbmdb "git.defalsify.org/vise.git/db/gdbm" "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" - "git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/resource" - "git.grassecon.net/urdt/ussd/internal/handlers/ussd" + "git.grassecon.net/urdt/ussd/internal/handlers" + "git.grassecon.net/urdt/ussd/internal/storage" ) var ( @@ -23,106 +19,6 @@ var ( scriptDir = path.Join("services", "registration") ) -func getParser(fp string, debug bool) (*asm.FlagParser, error) { - flagParser := asm.NewFlagParser().WithDebug() - _, err := flagParser.Load(fp) - if err != nil { - return nil, err - } - return flagParser, nil -} - -func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, pe *persist.Persister, userdataStore db.Db) (*ussd.Handlers, error) { - - ussdHandlers, err := ussd.NewHandlers(appFlags, userdataStore) - if err != nil { - return nil, err - } - ussdHandlers = ussdHandlers.WithPersister(pe) - rs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) - rs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) - rs.AddLocalFunc("save_pin", ussdHandlers.SavePin) - rs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) - rs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) - rs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) - rs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) - rs.AddLocalFunc("quit", ussdHandlers.Quit) - rs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) - rs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) - rs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) - rs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) - rs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) - rs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) - rs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) - rs.AddLocalFunc("get_sender", ussdHandlers.GetSender) - rs.AddLocalFunc("get_amount", ussdHandlers.GetAmount) - rs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) - rs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) - rs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) - rs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) - rs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) - rs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) - rs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) - rs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) - rs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized) - rs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate) - rs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) - rs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) - rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) - rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) - rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) - rs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) - rs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) - rs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) - rs.AddLocalFunc("quit_with_help",ussdHandlers.QuitWithHelp) - - return ussdHandlers, nil -} - -func ensureDbDir(dbDir string) error { - err := os.MkdirAll(dbDir, 0700) - if err != nil { - return fmt.Errorf("state dir create exited with error: %v\n", err) - } - return nil -} - -func getPersister(dbDir string, ctx context.Context) (*persist.Persister, error) { - err := ensureDbDir(dbDir) - if err != nil { - return nil, err - } - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "state.gdbm") - store.Connect(ctx, storeFile) - pr := persist.NewPersister(store) - return pr, nil -} - -func getUserdataDb(dbDir string, ctx context.Context) db.Db { - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "userdata.gdbm") - store.Connect(ctx, storeFile) - - return store -} - -func getResource(resourceDir string, ctx context.Context) (resource.Resource, error) { - store := fsdb.NewFsDb() - err := store.Connect(ctx, resourceDir) - if err != nil { - return nil, err - } - rfs := resource.NewDbResource(store) - 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 var size uint @@ -139,11 +35,6 @@ func main() { ctx := context.Background() ctx = context.WithValue(ctx, "SessionId", sessionId) pfp := path.Join(scriptDir, "pp.csv") - flagParser, err := getParser(pfp, true) - - if err != nil { - os.Exit(1) - } cfg := engine.Config{ Root: "root", @@ -152,19 +43,21 @@ func main() { FlagCount: uint32(16), } - rs, err := getResource(scriptDir, ctx) + menuStorageService := storage.MenuStorageService{} + + rs, err := menuStorageService.GetResource(scriptDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - pe, err := getPersister(dbDir, ctx) + pe, err := menuStorageService.GetPersister(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - store := getUserdataDb(dbDir, ctx) + userdatastore := menuStorageService.GetUserdataDb(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -176,13 +69,20 @@ func main() { os.Exit(1) } - hl, err := getHandler(flagParser, dbResource, pe, store) + lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, pe, userdatastore, cfg, rs) + if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - en := getEngine(cfg, rs, pe) + hl, err := lhs.GetHandler() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + en := lhs.GetEngine() en = en.WithFirst(hl.Init) if debug { en = en.WithDebug(nil) diff --git a/internal/handlers/handlerservice.go b/internal/handlers/handlerservice.go new file mode 100644 index 0000000..e6d4fb6 --- /dev/null +++ b/internal/handlers/handlerservice.go @@ -0,0 +1,99 @@ +package handlers + +import ( + "git.defalsify.org/vise.git/asm" + "git.defalsify.org/vise.git/db" + "git.defalsify.org/vise.git/engine" + "git.defalsify.org/vise.git/persist" + "git.defalsify.org/vise.git/resource" + "git.grassecon.net/urdt/ussd/internal/handlers/ussd" +) + +type HandlerService interface { + GetHandler() (*ussd.Handlers, error) +} + +func getParser(fp string, debug bool) (*asm.FlagParser, error) { + flagParser := asm.NewFlagParser().WithDebug() + _, err := flagParser.Load(fp) + if err != nil { + return nil, err + } + return flagParser, nil +} + +type LocalHandlerService struct { + Parser *asm.FlagParser + DbRs *resource.DbResource + Pe *persist.Persister + UserdataStore db.Db + Cfg engine.Config + Rs resource.Resource +} + +func NewLocalHandlerService(fp string, debug bool, dbResource *resource.DbResource, Pe *persist.Persister, userDataStore db.Db, cfg engine.Config, rs resource.Resource) (*LocalHandlerService, error) { + parser, err := getParser(fp, debug) + if err != nil { + return nil, err + } + return &LocalHandlerService{ + Parser: parser, + DbRs: dbResource, + Pe: Pe, + UserdataStore: userDataStore, + Cfg: cfg, + Rs: rs, + }, nil +} + +func (localHandlerService *LocalHandlerService) GetHandler() (*ussd.Handlers, error) { + ussdHandlers, err := ussd.NewHandlers(localHandlerService.Parser, localHandlerService.UserdataStore) + if err != nil { + return nil, err + } + ussdHandlers = ussdHandlers.WithPersister(localHandlerService.Pe) + localHandlerService.DbRs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) + localHandlerService.DbRs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) + localHandlerService.DbRs.AddLocalFunc("save_pin", ussdHandlers.SavePin) + localHandlerService.DbRs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) + localHandlerService.DbRs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) + localHandlerService.DbRs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) + localHandlerService.DbRs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) + localHandlerService.DbRs.AddLocalFunc("quit", ussdHandlers.Quit) + localHandlerService.DbRs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) + localHandlerService.DbRs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) + localHandlerService.DbRs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) + localHandlerService.DbRs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) + localHandlerService.DbRs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) + localHandlerService.DbRs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) + localHandlerService.DbRs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) + localHandlerService.DbRs.AddLocalFunc("get_sender", ussdHandlers.GetSender) + localHandlerService.DbRs.AddLocalFunc("get_amount", ussdHandlers.GetAmount) + localHandlerService.DbRs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) + localHandlerService.DbRs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) + localHandlerService.DbRs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) + localHandlerService.DbRs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) + localHandlerService.DbRs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) + localHandlerService.DbRs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) + localHandlerService.DbRs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) + localHandlerService.DbRs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) + localHandlerService.DbRs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized) + localHandlerService.DbRs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate) + localHandlerService.DbRs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) + localHandlerService.DbRs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) + localHandlerService.DbRs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) + localHandlerService.DbRs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) + localHandlerService.DbRs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) + localHandlerService.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) + localHandlerService.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) + localHandlerService.DbRs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) + localHandlerService.DbRs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp) + + return ussdHandlers, nil +} + +func (localHandlerService *LocalHandlerService) GetEngine() *engine.DefaultEngine { + en := engine.NewEngine(localHandlerService.Cfg, localHandlerService.Rs) + en = en.WithPersister(localHandlerService.Pe) + return en +} From 5bd51b280e47668d56be1be756fd50e767dbc24d Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 15:57:11 +0300 Subject: [PATCH 05/15] add storage service for menu --- internal/storage/storageservice.go | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 internal/storage/storageservice.go diff --git a/internal/storage/storageservice.go b/internal/storage/storageservice.go new file mode 100644 index 0000000..4306153 --- /dev/null +++ b/internal/storage/storageservice.go @@ -0,0 +1,76 @@ +package storage + +import ( + "context" + "fmt" + "os" + "path" + + "git.defalsify.org/vise.git/db" + fsdb "git.defalsify.org/vise.git/db/fs" + gdbmdb "git.defalsify.org/vise.git/db/gdbm" + "git.defalsify.org/vise.git/persist" + "git.defalsify.org/vise.git/resource" +) + +func ensureDbDir(dbDir string) error { + err := os.MkdirAll(dbDir, 0700) + if err != nil { + return fmt.Errorf("state dir create exited with error: %v\n", err) + } + return nil +} + +type StorageService interface { + GetPersister(dbDir string, ctx context.Context) (*persist.Persister, error) + GetUserdataDb(dbDir string, ctx context.Context) db.Db + GetResource(resourceDir string, ctx context.Context) (resource.Resource, error) + EnsureDbDir(dbDir string) error +} + +type MenuStorageService struct{} + +func (menuStorageService *MenuStorageService) GetPersister(dbDir string, ctx context.Context) (*persist.Persister, error) { + err := ensureDbDir(dbDir) + if err != nil { + return nil, err + } + store := gdbmdb.NewGdbmDb() + storeFile := path.Join(dbDir, "state.gdbm") + store.Connect(ctx, storeFile) + pr := persist.NewPersister(store) + return pr, nil +} + +func (menuStorageService *MenuStorageService) GetUserdataDb(dbDir string, ctx context.Context) db.Db { + store := gdbmdb.NewGdbmDb() + storeFile := path.Join(dbDir, "userdata.gdbm") + store.Connect(ctx, storeFile) + + return store +} + +func (menuStorageService *MenuStorageService) GetResource(resourceDir string, ctx context.Context) (resource.Resource, error) { + store := fsdb.NewFsDb() + err := store.Connect(ctx, resourceDir) + if err != nil { + return nil, err + } + rfs := resource.NewDbResource(store) + return rfs, nil +} + +func (menuStorageService *MenuStorageService) GetStateStore(dbDir string, ctx context.Context) (db.Db, error) { + store := gdbmdb.NewGdbmDb() + storeFile := path.Join(dbDir, "state.gdbm") + store.Connect(ctx, storeFile) + return store, nil +} + +func (menuStorageService *MenuStorageService) EnsureDbDir(dbDir string) error { + err := os.MkdirAll(dbDir, 0700) + if err != nil { + return fmt.Errorf("state dir create exited with error: %v\n", err) + } + return nil +} From 81159e77d1c8f680a051bf50024c7d48ba594d65 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 16:15:29 +0300 Subject: [PATCH 06/15] refactor code --- cmd/africastalking/main.go | 122 ++++++++----------------------------- 1 file changed, 26 insertions(+), 96 deletions(-) diff --git a/cmd/africastalking/main.go b/cmd/africastalking/main.go index 69122b7..be2ff01 100644 --- a/cmd/africastalking/main.go +++ b/cmd/africastalking/main.go @@ -13,26 +13,23 @@ import ( "syscall" "git.defalsify.org/vise.git/asm" - "git.defalsify.org/vise.git/db" - fsdb "git.defalsify.org/vise.git/db/fs" - gdbmdb "git.defalsify.org/vise.git/db/gdbm" "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" "git.grassecon.net/urdt/ussd/internal/handlers" - "git.grassecon.net/urdt/ussd/internal/handlers/ussd" httpserver "git.grassecon.net/urdt/ussd/internal/http" + "git.grassecon.net/urdt/ussd/internal/storage" ) var ( - logg = logging.NewVanilla() + logg = logging.NewVanilla() scriptDir = path.Join("services", "registration") ) -type atRequestParser struct {} +type atRequestParser struct{} -func(arp *atRequestParser) GetSessionId(rq any) (string, error) { +func (arp *atRequestParser) GetSessionId(rq any) (string, error) { rqv, ok := rq.(*http.Request) if !ok { return "", handlers.ErrInvalidRequest @@ -49,7 +46,7 @@ func(arp *atRequestParser) GetSessionId(rq any) (string, error) { return phoneNumber, nil } -func(arp *atRequestParser) GetInput(rq any) ([]byte, error) { +func (arp *atRequestParser) GetInput(rq any) ([]byte, error) { rqv, ok := rq.(*http.Request) if !ok { return nil, handlers.ErrInvalidRequest @@ -68,7 +65,6 @@ func(arp *atRequestParser) GetInput(rq any) ([]byte, error) { return []byte(parts[len(parts)-1]), nil } - func getFlags(fp string, debug bool) (*asm.FlagParser, error) { flagParser := asm.NewFlagParser().WithDebug() _, err := flagParser.Load(fp) @@ -78,86 +74,6 @@ func getFlags(fp string, debug bool) (*asm.FlagParser, error) { return flagParser, nil } -func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, userdataStore db.Db) (*ussd.Handlers, error) { - - ussdHandlers, err := ussd.NewHandlers(appFlags, userdataStore) - if err != nil { - return nil, err - } - rs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) - rs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) - rs.AddLocalFunc("save_pin", ussdHandlers.SavePin) - rs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) - rs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) - rs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) - rs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) - rs.AddLocalFunc("quit", ussdHandlers.Quit) - rs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) - rs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) - rs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) - rs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) - rs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) - rs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) - rs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) - rs.AddLocalFunc("get_sender", ussdHandlers.GetSender) - rs.AddLocalFunc("get_amount", ussdHandlers.GetAmount) - rs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) - rs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) - rs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) - rs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) - rs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) - rs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) - rs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) - rs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) - rs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized) - rs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate) - rs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) - rs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) - rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) - rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) - rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) - rs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) - rs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) - rs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) - rs.AddLocalFunc("quit_with_help",ussdHandlers.QuitWithHelp) - - return ussdHandlers, nil -} - -func ensureDbDir(dbDir string) error { - err := os.MkdirAll(dbDir, 0700) - if err != nil { - return fmt.Errorf("state dir create exited with error: %v\n", err) - } - return nil -} - -func getStateStore(dbDir string, ctx context.Context) (db.Db, error) { - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "state.gdbm") - store.Connect(ctx, storeFile) - return store, nil -} - -func getUserdataDb(dbDir string, ctx context.Context) db.Db { - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "userdata.gdbm") - store.Connect(ctx, storeFile) - - return store -} - -func getResource(resourceDir string, ctx context.Context) (resource.Resource, error) { - store := fsdb.NewFsDb() - err := store.Connect(ctx, resourceDir) - if err != nil { - return nil, err - } - rfs := resource.NewDbResource(store) - return rfs, nil -} - - func main() { var dbDir string var resourceDir string @@ -175,7 +91,7 @@ func main() { flag.UintVar(&port, "p", 7123, "http port") flag.Parse() - logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size) + logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size) ctx := context.Background() pfp := path.Join(scriptDir, "pp.csv") @@ -197,19 +113,21 @@ func main() { cfg.EngineDebug = true } - rs, err := getResource(resourceDir, ctx) + menuStorageService := storage.MenuStorageService{} + + rs, err := menuStorageService.GetResource(scriptDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - err = ensureDbDir(dbDir) + err = menuStorageService.EnsureDbDir(dbDir) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdataStore := getUserdataDb(dbDir, ctx) + userdataStore := menuStorageService.GetUserdataDb(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -220,14 +138,26 @@ func main() { if !ok { os.Exit(1) } + lhs := handlers.LocalHandlerService{ + Parser: flagParser, + DbRs: dbResource, + UserdataStore: userdataStore, + Cfg: cfg, + Rs: rs, + } - hl, err := getHandler(flagParser, dbResource, userdataStore) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - stateStore, err := getStateStore(dbDir, ctx) + hl, err := lhs.GetHandler() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + stateStore, err := menuStorageService.GetStateStore(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -238,7 +168,7 @@ func main() { bsh := handlers.NewBaseSessionHandler(cfg, rs, stateStore, userdataStore, rp, hl) sh := httpserver.NewATSessionHandler(bsh) s := &http.Server{ - Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))), + Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))), Handler: sh, } s.RegisterOnShutdown(sh.Shutdown) From 13294b42d39bf293805c73106a09bb02913b570b Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 16:16:17 +0300 Subject: [PATCH 07/15] refactor code --- cmd/http/main.go | 104 +++++++++-------------------------------------- 1 file changed, 19 insertions(+), 85 deletions(-) diff --git a/cmd/http/main.go b/cmd/http/main.go index f869291..38fd441 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -12,20 +12,17 @@ import ( "syscall" "git.defalsify.org/vise.git/asm" - "git.defalsify.org/vise.git/db" - fsdb "git.defalsify.org/vise.git/db/fs" - gdbmdb "git.defalsify.org/vise.git/db/gdbm" "git.defalsify.org/vise.git/engine" - "git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/logging" + "git.defalsify.org/vise.git/resource" - "git.grassecon.net/urdt/ussd/internal/handlers/ussd" "git.grassecon.net/urdt/ussd/internal/handlers" httpserver "git.grassecon.net/urdt/ussd/internal/http" + "git.grassecon.net/urdt/ussd/internal/storage" ) var ( - logg = logging.NewVanilla() + logg = logging.NewVanilla() scriptDir = path.Join("services", "registration") ) @@ -38,52 +35,6 @@ func getFlags(fp string, debug bool) (*asm.FlagParser, error) { return flagParser, nil } -func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, userdataStore db.Db) (*ussd.Handlers, error) { - - ussdHandlers, err := ussd.NewHandlers(appFlags, userdataStore) - if err != nil { - return nil, err - } - rs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) - rs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) - rs.AddLocalFunc("save_pin", ussdHandlers.SavePin) - rs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) - rs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) - rs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) - rs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) - rs.AddLocalFunc("quit", ussdHandlers.Quit) - rs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) - rs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) - rs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) - rs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) - rs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) - rs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) - rs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) - rs.AddLocalFunc("get_sender", ussdHandlers.GetSender) - rs.AddLocalFunc("get_amount", ussdHandlers.GetAmount) - rs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) - rs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) - rs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) - rs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) - rs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) - rs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) - rs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) - rs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) - rs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized) - rs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate) - rs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) - rs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) - rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) - rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) - rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) - rs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) - rs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) - rs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) - rs.AddLocalFunc("quit_with_help",ussdHandlers.QuitWithHelp) - - return ussdHandlers, nil -} - func ensureDbDir(dbDir string) error { err := os.MkdirAll(dbDir, 0700) if err != nil { @@ -92,32 +43,6 @@ func ensureDbDir(dbDir string) error { return nil } -func getStateStore(dbDir string, ctx context.Context) (db.Db, error) { - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "state.gdbm") - store.Connect(ctx, storeFile) - return store, nil -} - -func getUserdataDb(dbDir string, ctx context.Context) db.Db { - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "userdata.gdbm") - store.Connect(ctx, storeFile) - - return store -} - -func getResource(resourceDir string, ctx context.Context) (resource.Resource, error) { - store := fsdb.NewFsDb() - err := store.Connect(ctx, resourceDir) - if err != nil { - return nil, err - } - rfs := resource.NewDbResource(store) - return rfs, nil -} - - func main() { var dbDir string var resourceDir string @@ -135,7 +60,7 @@ func main() { flag.UintVar(&port, "p", 7123, "http port") flag.Parse() - logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size) + logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size) ctx := context.Background() pfp := path.Join(scriptDir, "pp.csv") @@ -157,19 +82,20 @@ func main() { cfg.EngineDebug = true } - rs, err := getResource(resourceDir, ctx) + menuStorageService := storage.MenuStorageService{} + rs, err := menuStorageService.GetResource(scriptDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - err = ensureDbDir(dbDir) + err = menuStorageService.EnsureDbDir(dbDir) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdataStore := getUserdataDb(dbDir, ctx) + userdataStore := menuStorageService.GetUserdataDb(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -181,13 +107,21 @@ func main() { os.Exit(1) } - hl, err := getHandler(flagParser, dbResource, userdataStore) + lhs := handlers.LocalHandlerService{ + Parser: flagParser, + DbRs: dbResource, + UserdataStore: userdataStore, + Cfg: cfg, + Rs: rs, + } + + hl, err := lhs.GetHandler() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - stateStore, err := getStateStore(dbDir, ctx) + stateStore, err := menuStorageService.GetStateStore(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -198,7 +132,7 @@ func main() { bsh := handlers.NewBaseSessionHandler(cfg, rs, stateStore, userdataStore, rp, hl) sh := httpserver.ToSessionHandler(bsh) s := &http.Server{ - Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))), + Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))), Handler: sh, } s.RegisterOnShutdown(sh.Shutdown) From ffa00ae15c1dbe2722eb65be4950e5b02b236ad2 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 16:18:21 +0300 Subject: [PATCH 08/15] refactor code --- cmd/async/main.go | 120 +++++++++------------------------------------- 1 file changed, 23 insertions(+), 97 deletions(-) diff --git a/cmd/async/main.go b/cmd/async/main.go index e194d18..5b8aa36 100644 --- a/cmd/async/main.go +++ b/cmd/async/main.go @@ -10,32 +10,29 @@ import ( "syscall" "git.defalsify.org/vise.git/asm" - "git.defalsify.org/vise.git/db" - fsdb "git.defalsify.org/vise.git/db/fs" - gdbmdb "git.defalsify.org/vise.git/db/gdbm" "git.defalsify.org/vise.git/engine" - "git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/logging" + "git.defalsify.org/vise.git/resource" - "git.grassecon.net/urdt/ussd/internal/handlers/ussd" "git.grassecon.net/urdt/ussd/internal/handlers" + "git.grassecon.net/urdt/ussd/internal/storage" ) var ( - logg = logging.NewVanilla() + logg = logging.NewVanilla() scriptDir = path.Join("services", "registration") ) type asyncRequestParser struct { sessionId string - input []byte + input []byte } -func(p *asyncRequestParser) GetSessionId(r any) (string, error) { +func (p *asyncRequestParser) GetSessionId(r any) (string, error) { return p.sessionId, nil } -func(p *asyncRequestParser) GetInput(r any) ([]byte, error) { +func (p *asyncRequestParser) GetInput(r any) ([]byte, error) { return p.input, nil } @@ -48,86 +45,6 @@ func getFlags(fp string, debug bool) (*asm.FlagParser, error) { return flagParser, nil } -func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, userdataStore db.Db) (*ussd.Handlers, error) { - - ussdHandlers, err := ussd.NewHandlers(appFlags, userdataStore) - if err != nil { - return nil, err - } - rs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) - rs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) - rs.AddLocalFunc("save_pin", ussdHandlers.SavePin) - rs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) - rs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) - rs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) - rs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) - rs.AddLocalFunc("quit", ussdHandlers.Quit) - rs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) - rs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) - rs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) - rs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) - rs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) - rs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) - rs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) - rs.AddLocalFunc("get_sender", ussdHandlers.GetSender) - rs.AddLocalFunc("get_amount", ussdHandlers.GetAmount) - rs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) - rs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) - rs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) - rs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) - rs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) - rs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) - rs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) - rs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) - rs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized) - rs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate) - rs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) - rs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) - rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) - rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) - rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) - rs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) - rs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) - rs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) - rs.AddLocalFunc("quit_with_help",ussdHandlers.QuitWithHelp) - - return ussdHandlers, nil -} - -func ensureDbDir(dbDir string) error { - err := os.MkdirAll(dbDir, 0700) - if err != nil { - return fmt.Errorf("state dir create exited with error: %v\n", err) - } - return nil -} - -func getStateStore(dbDir string, ctx context.Context) (db.Db, error) { - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "state.gdbm") - store.Connect(ctx, storeFile) - return store, nil -} - -func getUserdataDb(dbDir string, ctx context.Context) db.Db { - store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "userdata.gdbm") - store.Connect(ctx, storeFile) - - return store -} - -func getResource(resourceDir string, ctx context.Context) (resource.Resource, error) { - store := fsdb.NewFsDb() - err := store.Connect(ctx, resourceDir) - if err != nil { - return nil, err - } - rfs := resource.NewDbResource(store) - return rfs, nil -} - - func main() { var sessionId string var dbDir string @@ -147,7 +64,7 @@ func main() { flag.UintVar(&port, "p", 7123, "http port") flag.Parse() - logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId) + logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId) ctx := context.Background() pfp := path.Join(scriptDir, "pp.csv") @@ -169,19 +86,20 @@ func main() { cfg.EngineDebug = true } - rs, err := getResource(resourceDir, ctx) + menuStorageService := storage.MenuStorageService{} + rs, err := menuStorageService.GetResource(scriptDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - err = ensureDbDir(dbDir) + err = menuStorageService.EnsureDbDir(dbDir) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdataStore := getUserdataDb(dbDir, ctx) + userdataStore := menuStorageService.GetUserdataDb(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -193,13 +111,21 @@ func main() { os.Exit(1) } - hl, err := getHandler(flagParser, dbResource, userdataStore) + lhs := handlers.LocalHandlerService{ + Parser: flagParser, + DbRs: dbResource, + UserdataStore: userdataStore, + Cfg: cfg, + Rs: rs, + } + + hl, err := lhs.GetHandler() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - stateStore, err := getStateStore(dbDir, ctx) + stateStore, err := menuStorageService.GetStateStore(dbDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -212,7 +138,7 @@ func main() { sh := handlers.NewBaseSessionHandler(cfg, rs, stateStore, userdataStore, rp, hl) cfg.SessionId = sessionId rqs := handlers.RequestSession{ - Ctx: ctx, + Ctx: ctx, Writer: os.Stdout, Config: cfg, } @@ -248,7 +174,7 @@ func main() { fmt.Println("") _, err = fmt.Scanln(&rqs.Input) if err != nil { - fmt.Errorf("error in input: %v", err) + fmt.Errorf("error in input: %v", err) os.Exit(1) } } From bc9dfe4f65f5586a2edd929f4f021700a670ec3a Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 17:01:23 +0300 Subject: [PATCH 09/15] remove redundant code --- cmd/main.go | 6 ++++++ internal/storage/storageservice.go | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 7e5bc0d..ab36f30 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -45,6 +45,12 @@ func main() { menuStorageService := storage.MenuStorageService{} + err := menuStorageService.EnsureDbDir(dbDir) + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + rs, err := menuStorageService.GetResource(scriptDir, ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) diff --git a/internal/storage/storageservice.go b/internal/storage/storageservice.go index 4306153..b31b67d 100644 --- a/internal/storage/storageservice.go +++ b/internal/storage/storageservice.go @@ -31,10 +31,6 @@ type StorageService interface { type MenuStorageService struct{} func (menuStorageService *MenuStorageService) GetPersister(dbDir string, ctx context.Context) (*persist.Persister, error) { - err := ensureDbDir(dbDir) - if err != nil { - return nil, err - } store := gdbmdb.NewGdbmDb() storeFile := path.Join(dbDir, "state.gdbm") store.Connect(ctx, storeFile) From 96358959b4444c13374ba2c8defcafc764389188 Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 17:04:08 +0300 Subject: [PATCH 10/15] remove unused code --- internal/storage/storageservice.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/internal/storage/storageservice.go b/internal/storage/storageservice.go index b31b67d..a3f50d6 100644 --- a/internal/storage/storageservice.go +++ b/internal/storage/storageservice.go @@ -13,14 +13,6 @@ import ( "git.defalsify.org/vise.git/resource" ) -func ensureDbDir(dbDir string) error { - err := os.MkdirAll(dbDir, 0700) - if err != nil { - return fmt.Errorf("state dir create exited with error: %v\n", err) - } - return nil -} - type StorageService interface { GetPersister(dbDir string, ctx context.Context) (*persist.Persister, error) GetUserdataDb(dbDir string, ctx context.Context) db.Db From e4d8bfad7b427e9915a07399c02f63eb07c19e45 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 19 Sep 2024 17:17:28 +0300 Subject: [PATCH 11/15] moved the mocks package --- internal/handlers/ussd/menuhandler_test.go | 2 +- internal/{handlers/ussd => }/mocks/dbmock.go | 0 internal/{handlers/ussd => }/mocks/servicemock.go | 0 internal/{handlers/ussd => }/mocks/userdbmock.go | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename internal/{handlers/ussd => }/mocks/dbmock.go (100%) rename internal/{handlers/ussd => }/mocks/servicemock.go (100%) rename internal/{handlers/ussd => }/mocks/userdbmock.go (100%) diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index dd24b20..d0367f0 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -11,7 +11,7 @@ import ( "git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/state" - "git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks" + "git.grassecon.net/urdt/ussd/internal/mocks" "git.grassecon.net/urdt/ussd/internal/models" "git.grassecon.net/urdt/ussd/internal/utils" "github.com/alecthomas/assert/v2" diff --git a/internal/handlers/ussd/mocks/dbmock.go b/internal/mocks/dbmock.go similarity index 100% rename from internal/handlers/ussd/mocks/dbmock.go rename to internal/mocks/dbmock.go diff --git a/internal/handlers/ussd/mocks/servicemock.go b/internal/mocks/servicemock.go similarity index 100% rename from internal/handlers/ussd/mocks/servicemock.go rename to internal/mocks/servicemock.go diff --git a/internal/handlers/ussd/mocks/userdbmock.go b/internal/mocks/userdbmock.go similarity index 100% rename from internal/handlers/ussd/mocks/userdbmock.go rename to internal/mocks/userdbmock.go From e8be64ae289870e01bf8d9d838542ff1b95a936c Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 19 Sep 2024 17:18:14 +0300 Subject: [PATCH 12/15] added http related mocks --- internal/mocks/httpmocks/enginemock.go | 30 ++++++++++++ .../mocks/httpmocks/requesthandlermock.go | 47 +++++++++++++++++++ internal/mocks/httpmocks/requestparsermock.go | 15 ++++++ internal/mocks/httpmocks/writermock.go | 25 ++++++++++ 4 files changed, 117 insertions(+) create mode 100644 internal/mocks/httpmocks/enginemock.go create mode 100644 internal/mocks/httpmocks/requesthandlermock.go create mode 100644 internal/mocks/httpmocks/requestparsermock.go create mode 100644 internal/mocks/httpmocks/writermock.go diff --git a/internal/mocks/httpmocks/enginemock.go b/internal/mocks/httpmocks/enginemock.go new file mode 100644 index 0000000..d5c6b20 --- /dev/null +++ b/internal/mocks/httpmocks/enginemock.go @@ -0,0 +1,30 @@ +package httpmocks + +import ( + "context" + "io" +) + +// MockEngine implements the engine.Engine interface for testing +type MockEngine struct { + InitFunc func(context.Context) (bool, error) + ExecFunc func(context.Context, []byte) (bool, error) + WriteResultFunc func(context.Context, io.Writer) (int, error) + FinishFunc func() error +} + +func (m *MockEngine) Init(ctx context.Context) (bool, error) { + return m.InitFunc(ctx) +} + +func (m *MockEngine) Exec(ctx context.Context, input []byte) (bool, error) { + return m.ExecFunc(ctx, input) +} + +func (m *MockEngine) WriteResult(ctx context.Context, w io.Writer) (int, error) { + return m.WriteResultFunc(ctx, w) +} + +func (m *MockEngine) Finish() error { + return m.FinishFunc() +} diff --git a/internal/mocks/httpmocks/requesthandlermock.go b/internal/mocks/httpmocks/requesthandlermock.go new file mode 100644 index 0000000..f17abce --- /dev/null +++ b/internal/mocks/httpmocks/requesthandlermock.go @@ -0,0 +1,47 @@ +package httpmocks + +import ( + "git.defalsify.org/vise.git/engine" + "git.defalsify.org/vise.git/persist" + "git.defalsify.org/vise.git/resource" + "git.grassecon.net/urdt/ussd/internal/handlers" +) + +// MockRequestHandler implements handlers.RequestHandler interface for testing +type MockRequestHandler struct { + ProcessFunc func(handlers.RequestSession) (handlers.RequestSession, error) + GetConfigFunc func() engine.Config + GetEngineFunc func(cfg engine.Config, rs resource.Resource, pe *persist.Persister) engine.Engine + OutputFunc func(rs handlers.RequestSession) (handlers.RequestSession, error) + ResetFunc func(rs handlers.RequestSession) (handlers.RequestSession, error) + ShutdownFunc func() + GetRequestParserFunc func() handlers.RequestParser +} + +func (m *MockRequestHandler) Process(rqs handlers.RequestSession) (handlers.RequestSession, error) { + return m.ProcessFunc(rqs) +} + +func (m *MockRequestHandler) GetConfig() engine.Config { + return m.GetConfigFunc() +} + +func (m *MockRequestHandler) GetEngine(cfg engine.Config, rs resource.Resource, pe *persist.Persister) engine.Engine { + return m.GetEngineFunc(cfg, rs, pe) +} + +func (m *MockRequestHandler) Output(rs handlers.RequestSession) (handlers.RequestSession, error) { + return m.OutputFunc(rs) +} + +func (m *MockRequestHandler) Reset(rs handlers.RequestSession) (handlers.RequestSession, error) { + return m.ResetFunc(rs) +} + +func (m *MockRequestHandler) Shutdown() { + m.ShutdownFunc() +} + +func (m *MockRequestHandler) GetRequestParser() handlers.RequestParser { + return m.GetRequestParserFunc() +} diff --git a/internal/mocks/httpmocks/requestparsermock.go b/internal/mocks/httpmocks/requestparsermock.go new file mode 100644 index 0000000..54b16bf --- /dev/null +++ b/internal/mocks/httpmocks/requestparsermock.go @@ -0,0 +1,15 @@ +package httpmocks + +// MockRequestParser implements the handlers.RequestParser interface for testing +type MockRequestParser struct { + GetSessionIdFunc func(any) (string, error) + GetInputFunc func(any) ([]byte, error) +} + +func (m *MockRequestParser) GetSessionId(rq any) (string, error) { + return m.GetSessionIdFunc(rq) +} + +func (m *MockRequestParser) GetInput(rq any) ([]byte, error) { + return m.GetInputFunc(rq) +} diff --git a/internal/mocks/httpmocks/writermock.go b/internal/mocks/httpmocks/writermock.go new file mode 100644 index 0000000..0d171d2 --- /dev/null +++ b/internal/mocks/httpmocks/writermock.go @@ -0,0 +1,25 @@ +package httpmocks + +import "net/http" + +// MockWriter implements a mock io.Writer for testing +type MockWriter struct { + WriteStringCalled bool + WrittenString string +} + +func (m *MockWriter) Write(p []byte) (n int, err error) { + return len(p), nil +} + +func (m *MockWriter) WriteString(s string) (n int, err error) { + m.WriteStringCalled = true + m.WrittenString = s + return len(s), nil +} + +func (m *MockWriter) Header() http.Header { + return http.Header{} +} + +func (m *MockWriter) WriteHeader(statusCode int) {} \ No newline at end of file From f6979868e5c45703f766410fa5f43b9e0bb3e4e2 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 19 Sep 2024 17:19:09 +0300 Subject: [PATCH 13/15] added at_session_handler tests --- internal/http/at_session_handler_test.go | 232 +++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 internal/http/at_session_handler_test.go diff --git a/internal/http/at_session_handler_test.go b/internal/http/at_session_handler_test.go new file mode 100644 index 0000000..c99cee7 --- /dev/null +++ b/internal/http/at_session_handler_test.go @@ -0,0 +1,232 @@ +package http + +import ( + "context" + "errors" + "io" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "testing" + + "git.defalsify.org/vise.git/engine" + "git.grassecon.net/urdt/ussd/internal/handlers" + "git.grassecon.net/urdt/ussd/internal/mocks/httpmocks" +) + +func TestNewATSessionHandler(t *testing.T) { + mockHandler := &httpmocks.MockRequestHandler{} + ash := NewATSessionHandler(mockHandler) + + if ash == nil { + t.Fatal("NewATSessionHandler returned nil") + } + + if ash.SessionHandler == nil { + t.Fatal("SessionHandler is nil") + } +} + +func TestATSessionHandler_ServeHTTP(t *testing.T) { + tests := []struct { + name string + setupMocks func(*httpmocks.MockRequestHandler, *httpmocks.MockRequestParser, *httpmocks.MockEngine) + formData url.Values + expectedStatus int + expectedBody string + }{ + { + name: "Successful request", + setupMocks: func(mh *httpmocks.MockRequestHandler, mrp *httpmocks.MockRequestParser, me *httpmocks.MockEngine) { + mrp.GetSessionIdFunc = func(rq any) (string, error) { + req := rq.(*http.Request) + return req.FormValue("phoneNumber"), nil + } + mrp.GetInputFunc = func(rq any) ([]byte, error) { + req := rq.(*http.Request) + text := req.FormValue("text") + parts := strings.Split(text, "*") + return []byte(parts[len(parts)-1]), nil + } + mh.ProcessFunc = func(rqs handlers.RequestSession) (handlers.RequestSession, error) { + rqs.Continue = true + rqs.Engine = me + return rqs, nil + } + mh.GetConfigFunc = func() engine.Config { return engine.Config{} } + mh.GetRequestParserFunc = func() handlers.RequestParser { return mrp } + mh.OutputFunc = func(rs handlers.RequestSession) (handlers.RequestSession, error) { return rs, nil } + mh.ResetFunc = func(rs handlers.RequestSession) (handlers.RequestSession, error) { return rs, nil } + me.WriteResultFunc = func(context.Context, io.Writer) (int, error) { return 0, nil } + }, + formData: url.Values{ + "phoneNumber": []string{"+1234567890"}, + "text": []string{"1*2*3"}, + }, + expectedStatus: http.StatusOK, + expectedBody: "CON ", + }, + { + name: "GetSessionId error", + setupMocks: func(mh *httpmocks.MockRequestHandler, mrp *httpmocks.MockRequestParser, me *httpmocks.MockEngine) { + mrp.GetSessionIdFunc = func(rq any) (string, error) { + return "", errors.New("no phone number found") + } + mh.GetConfigFunc = func() engine.Config { return engine.Config{} } + mh.GetRequestParserFunc = func() handlers.RequestParser { return mrp } + }, + formData: url.Values{ + "text": []string{"1*2*3"}, + }, + expectedStatus: http.StatusBadRequest, + expectedBody: "", + }, + { + name: "GetInput error", + setupMocks: func(mh *httpmocks.MockRequestHandler, mrp *httpmocks.MockRequestParser, me *httpmocks.MockEngine) { + mrp.GetSessionIdFunc = func(rq any) (string, error) { + req := rq.(*http.Request) + return req.FormValue("phoneNumber"), nil + } + mrp.GetInputFunc = func(rq any) ([]byte, error) { + return nil, errors.New("no input found") + } + mh.GetConfigFunc = func() engine.Config { return engine.Config{} } + mh.GetRequestParserFunc = func() handlers.RequestParser { return mrp } + }, + formData: url.Values{ + "phoneNumber": []string{"+1234567890"}, + }, + expectedStatus: http.StatusBadRequest, + expectedBody: "", + }, + { + name: "Process error", + setupMocks: func(mh *httpmocks.MockRequestHandler, mrp *httpmocks.MockRequestParser, me *httpmocks.MockEngine) { + mrp.GetSessionIdFunc = func(rq any) (string, error) { + req := rq.(*http.Request) + return req.FormValue("phoneNumber"), nil + } + mrp.GetInputFunc = func(rq any) ([]byte, error) { + req := rq.(*http.Request) + text := req.FormValue("text") + parts := strings.Split(text, "*") + return []byte(parts[len(parts)-1]), nil + } + mh.ProcessFunc = func(rqs handlers.RequestSession) (handlers.RequestSession, error) { + return rqs, handlers.ErrStorage + } + mh.GetConfigFunc = func() engine.Config { return engine.Config{} } + mh.GetRequestParserFunc = func() handlers.RequestParser { return mrp } + }, + formData: url.Values{ + "phoneNumber": []string{"+1234567890"}, + "text": []string{"1*2*3"}, + }, + expectedStatus: http.StatusInternalServerError, + expectedBody: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockHandler := &httpmocks.MockRequestHandler{} + mockRequestParser := &httpmocks.MockRequestParser{} + mockEngine := &httpmocks.MockEngine{} + tt.setupMocks(mockHandler, mockRequestParser, mockEngine) + + ash := NewATSessionHandler(mockHandler) + + req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(tt.formData.Encode())) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + w := httptest.NewRecorder() + + ash.ServeHTTP(w, req) + + if w.Code != tt.expectedStatus { + t.Errorf("Expected status %d, got %d", tt.expectedStatus, w.Code) + } + + if tt.expectedBody != "" && w.Body.String() != tt.expectedBody { + t.Errorf("Expected body %q, got %q", tt.expectedBody, w.Body.String()) + } + }) + } +} + +func TestATSessionHandler_Output(t *testing.T) { + tests := []struct { + name string + input handlers.RequestSession + expectedPrefix string + expectedError bool + }{ + { + name: "Continue true", + input: handlers.RequestSession{ + Continue: true, + Engine: &httpmocks.MockEngine{ + WriteResultFunc: func(context.Context, io.Writer) (int, error) { + return 0, nil + }, + }, + Writer: &httpmocks.MockWriter{}, + }, + expectedPrefix: "CON ", + expectedError: false, + }, + { + name: "Continue false", + input: handlers.RequestSession{ + Continue: false, + Engine: &httpmocks.MockEngine{ + WriteResultFunc: func(context.Context, io.Writer) (int, error) { + return 0, nil + }, + }, + Writer: &httpmocks.MockWriter{}, + }, + expectedPrefix: "END ", + expectedError: false, + }, + { + name: "WriteResult error", + input: handlers.RequestSession{ + Continue: true, + Engine: &httpmocks.MockEngine{ + WriteResultFunc: func(context.Context, io.Writer) (int, error) { + return 0, errors.New("write error") + }, + }, + Writer: &httpmocks.MockWriter{}, + }, + expectedPrefix: "CON ", + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ash := &ATSessionHandler{} + _, err := ash.Output(tt.input) + + if tt.expectedError && err == nil { + t.Error("Expected an error, but got nil") + } + + if !tt.expectedError && err != nil { + t.Errorf("Unexpected error: %v", err) + } + + mw := tt.input.Writer.(*httpmocks.MockWriter) + if !mw.WriteStringCalled { + t.Error("WriteString was not called") + } + + if mw.WrittenString != tt.expectedPrefix { + t.Errorf("Expected prefix %q, got %q", tt.expectedPrefix, mw.WrittenString) + } + }) + } +} From 3fe66466c50c98ee493336251f1a8a0619e2f160 Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 19 Sep 2024 18:52:13 +0300 Subject: [PATCH 14/15] renamed test file and added server.go tests --- ...t_session_handler_test.go => http_test.go} | 219 +++++++++++++++++- 1 file changed, 218 insertions(+), 1 deletion(-) rename internal/http/{at_session_handler_test.go => http_test.go} (54%) diff --git a/internal/http/at_session_handler_test.go b/internal/http/http_test.go similarity index 54% rename from internal/http/at_session_handler_test.go rename to internal/http/http_test.go index c99cee7..48d04ca 100644 --- a/internal/http/at_session_handler_test.go +++ b/internal/http/http_test.go @@ -1,6 +1,7 @@ package http import ( + "bytes" "context" "errors" "io" @@ -15,6 +16,16 @@ import ( "git.grassecon.net/urdt/ussd/internal/mocks/httpmocks" ) +// invalidRequestType is a custom type to test invalid request scenarios +type invalidRequestType struct{} + +// errorReader is a helper type that always returns an error when Read is called +type errorReader struct{} + +func (e *errorReader) Read(p []byte) (n int, err error) { + return 0, errors.New("read error") +} + func TestNewATSessionHandler(t *testing.T) { mockHandler := &httpmocks.MockRequestHandler{} ash := NewATSessionHandler(mockHandler) @@ -90,7 +101,7 @@ func TestATSessionHandler_ServeHTTP(t *testing.T) { return req.FormValue("phoneNumber"), nil } mrp.GetInputFunc = func(rq any) ([]byte, error) { - return nil, errors.New("no input found") + return nil, errors.New("no input found") } mh.GetConfigFunc = func() engine.Config { return engine.Config{} } mh.GetRequestParserFunc = func() handlers.RequestParser { return mrp } @@ -230,3 +241,209 @@ func TestATSessionHandler_Output(t *testing.T) { }) } } + +func TestSessionHandler_ServeHTTP(t *testing.T) { + tests := []struct { + name string + sessionID string + input []byte + parserErr error + processErr error + outputErr error + resetErr error + expectedStatus int + }{ + { + name: "Success", + sessionID: "123", + input: []byte("test input"), + expectedStatus: http.StatusOK, + }, + { + name: "Missing Session ID", + sessionID: "", + parserErr: handlers.ErrSessionMissing, + expectedStatus: http.StatusBadRequest, + }, + { + name: "Process Error", + sessionID: "123", + input: []byte("test input"), + processErr: handlers.ErrStorage, + expectedStatus: http.StatusInternalServerError, + }, + { + name: "Output Error", + sessionID: "123", + input: []byte("test input"), + outputErr: errors.New("output error"), + expectedStatus: http.StatusOK, + }, + { + name: "Reset Error", + sessionID: "123", + input: []byte("test input"), + resetErr: errors.New("reset error"), + expectedStatus: http.StatusOK, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockRequestParser := &httpmocks.MockRequestParser{ + GetSessionIdFunc: func(any) (string, error) { + return tt.sessionID, tt.parserErr + }, + GetInputFunc: func(any) ([]byte, error) { + return tt.input, nil + }, + } + + mockRequestHandler := &httpmocks.MockRequestHandler{ + ProcessFunc: func(rs handlers.RequestSession) (handlers.RequestSession, error) { + return rs, tt.processErr + }, + OutputFunc: func(rs handlers.RequestSession) (handlers.RequestSession, error) { + return rs, tt.outputErr + }, + ResetFunc: func(rs handlers.RequestSession) (handlers.RequestSession, error) { + return rs, tt.resetErr + }, + GetRequestParserFunc: func() handlers.RequestParser { + return mockRequestParser + }, + GetConfigFunc: func() engine.Config { + return engine.Config{} + }, + } + + sessionHandler := ToSessionHandler(mockRequestHandler) + + req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(tt.input)) + req.Header.Set("X-Vise-Session", tt.sessionID) + + rr := httptest.NewRecorder() + + sessionHandler.ServeHTTP(rr, req) + + if status := rr.Code; status != tt.expectedStatus { + t.Errorf("handler returned wrong status code: got %v want %v", + status, tt.expectedStatus) + } + }) + } +} + +func TestSessionHandler_writeError(t *testing.T) { + handler := &SessionHandler{} + mockWriter := &httpmocks.MockWriter{} + err := errors.New("test error") + + handler.writeError(mockWriter, http.StatusBadRequest, err) + + if mockWriter.WrittenString != "" { + t.Errorf("Expected empty body, got %s", mockWriter.WrittenString) + } +} + +func TestDefaultRequestParser_GetSessionId(t *testing.T) { + tests := []struct { + name string + request any + expectedID string + expectedError error + }{ + { + name: "Valid Session ID", + request: func() *http.Request { + req := httptest.NewRequest(http.MethodPost, "/", nil) + req.Header.Set("X-Vise-Session", "123456") + return req + }(), + expectedID: "123456", + expectedError: nil, + }, + { + name: "Missing Session ID", + request: httptest.NewRequest(http.MethodPost, "/", nil), + expectedID: "", + expectedError: handlers.ErrSessionMissing, + }, + { + name: "Invalid Request Type", + request: invalidRequestType{}, + expectedID: "", + expectedError: handlers.ErrInvalidRequest, + }, + } + + parser := &DefaultRequestParser{} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + id, err := parser.GetSessionId(tt.request) + + if id != tt.expectedID { + t.Errorf("Expected session ID %s, got %s", tt.expectedID, id) + } + + if err != tt.expectedError { + t.Errorf("Expected error %v, got %v", tt.expectedError, err) + } + }) + } +} + +func TestDefaultRequestParser_GetInput(t *testing.T) { + tests := []struct { + name string + request any + expectedInput []byte + expectedError error + }{ + { + name: "Valid Input", + request: func() *http.Request { + return httptest.NewRequest(http.MethodPost, "/", bytes.NewBufferString("test input")) + }(), + expectedInput: []byte("test input"), + expectedError: nil, + }, + { + name: "Empty Input", + request: httptest.NewRequest(http.MethodPost, "/", nil), + expectedInput: []byte{}, + expectedError: nil, + }, + { + name: "Invalid Request Type", + request: invalidRequestType{}, + expectedInput: nil, + expectedError: handlers.ErrInvalidRequest, + }, + { + name: "Read Error", + request: func() *http.Request { + return httptest.NewRequest(http.MethodPost, "/", &errorReader{}) + }(), + expectedInput: nil, + expectedError: errors.New("read error"), + }, + } + + parser := &DefaultRequestParser{} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + input, err := parser.GetInput(tt.request) + + if !bytes.Equal(input, tt.expectedInput) { + t.Errorf("Expected input %s, got %s", tt.expectedInput, input) + } + + if err != tt.expectedError && (err == nil || err.Error() != tt.expectedError.Error()) { + t.Errorf("Expected error %v, got %v", tt.expectedError, err) + } + }) + } +} From e581a1ad2f71c89be521d7a792cb988bed3df53f Mon Sep 17 00:00:00 2001 From: Carlosokumu Date: Thu, 19 Sep 2024 21:04:09 +0300 Subject: [PATCH 15/15] factor out getflag --- cmd/africastalking/main.go | 25 +++------------------ cmd/async/main.go | 24 ++------------------ cmd/http/main.go | 35 +++++------------------------ cmd/main.go | 4 +++- internal/handlers/handlerservice.go | 24 ++++++++++++-------- 5 files changed, 29 insertions(+), 83 deletions(-) diff --git a/cmd/africastalking/main.go b/cmd/africastalking/main.go index be2ff01..c0db723 100644 --- a/cmd/africastalking/main.go +++ b/cmd/africastalking/main.go @@ -12,7 +12,6 @@ import ( "strings" "syscall" - "git.defalsify.org/vise.git/asm" "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" @@ -65,15 +64,6 @@ func (arp *atRequestParser) GetInput(rq any) ([]byte, error) { return []byte(parts[len(parts)-1]), nil } -func getFlags(fp string, debug bool) (*asm.FlagParser, error) { - flagParser := asm.NewFlagParser().WithDebug() - _, err := flagParser.Load(fp) - if err != nil { - return nil, err - } - return flagParser, nil -} - func main() { var dbDir string var resourceDir string @@ -95,11 +85,6 @@ func main() { ctx := context.Background() pfp := path.Join(scriptDir, "pp.csv") - flagParser, err := getFlags(pfp, true) - - if err != nil { - os.Exit(1) - } cfg := engine.Config{ Root: "root", @@ -138,13 +123,9 @@ func main() { if !ok { os.Exit(1) } - lhs := handlers.LocalHandlerService{ - Parser: flagParser, - DbRs: dbResource, - UserdataStore: userdataStore, - Cfg: cfg, - Rs: rs, - } + + lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, cfg, rs) + lhs.WithDataStore(&userdataStore) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) diff --git a/cmd/async/main.go b/cmd/async/main.go index 5b8aa36..2ff0d1e 100644 --- a/cmd/async/main.go +++ b/cmd/async/main.go @@ -9,7 +9,6 @@ import ( "path" "syscall" - "git.defalsify.org/vise.git/asm" "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" @@ -36,15 +35,6 @@ func (p *asyncRequestParser) GetInput(r any) ([]byte, error) { return p.input, nil } -func getFlags(fp string, debug bool) (*asm.FlagParser, error) { - flagParser := asm.NewFlagParser().WithDebug() - _, err := flagParser.Load(fp) - if err != nil { - return nil, err - } - return flagParser, nil -} - func main() { var sessionId string var dbDir string @@ -68,11 +58,6 @@ func main() { ctx := context.Background() pfp := path.Join(scriptDir, "pp.csv") - flagParser, err := getFlags(pfp, true) - - if err != nil { - os.Exit(1) - } cfg := engine.Config{ Root: "root", @@ -111,13 +96,8 @@ func main() { os.Exit(1) } - lhs := handlers.LocalHandlerService{ - Parser: flagParser, - DbRs: dbResource, - UserdataStore: userdataStore, - Cfg: cfg, - Rs: rs, - } + lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, cfg, rs) + lhs.WithDataStore(&userdataStore) hl, err := lhs.GetHandler() if err != nil { diff --git a/cmd/http/main.go b/cmd/http/main.go index 38fd441..7b74e19 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -11,7 +11,6 @@ import ( "strconv" "syscall" - "git.defalsify.org/vise.git/asm" "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" @@ -26,23 +25,6 @@ var ( scriptDir = path.Join("services", "registration") ) -func getFlags(fp string, debug bool) (*asm.FlagParser, error) { - flagParser := asm.NewFlagParser().WithDebug() - _, err := flagParser.Load(fp) - if err != nil { - return nil, err - } - return flagParser, nil -} - -func ensureDbDir(dbDir string) error { - err := os.MkdirAll(dbDir, 0700) - if err != nil { - return fmt.Errorf("state dir create exited with error: %v\n", err) - } - return nil -} - func main() { var dbDir string var resourceDir string @@ -64,11 +46,6 @@ func main() { ctx := context.Background() pfp := path.Join(scriptDir, "pp.csv") - flagParser, err := getFlags(pfp, true) - - if err != nil { - os.Exit(1) - } cfg := engine.Config{ Root: "root", @@ -107,12 +84,12 @@ func main() { os.Exit(1) } - lhs := handlers.LocalHandlerService{ - Parser: flagParser, - DbRs: dbResource, - UserdataStore: userdataStore, - Cfg: cfg, - Rs: rs, + lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, cfg, rs) + lhs.WithDataStore(&userdataStore) + + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) } hl, err := lhs.GetHandler() diff --git a/cmd/main.go b/cmd/main.go index ab36f30..7176bd3 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -75,7 +75,9 @@ func main() { os.Exit(1) } - lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, pe, userdatastore, cfg, rs) + lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, cfg, rs) + lhs.WithDataStore(&userdatastore) + lhs.WithPersister(pe) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) diff --git a/internal/handlers/handlerservice.go b/internal/handlers/handlerservice.go index e6d4fb6..93c5a10 100644 --- a/internal/handlers/handlerservice.go +++ b/internal/handlers/handlerservice.go @@ -26,28 +26,34 @@ type LocalHandlerService struct { Parser *asm.FlagParser DbRs *resource.DbResource Pe *persist.Persister - UserdataStore db.Db + UserdataStore *db.Db Cfg engine.Config Rs resource.Resource } -func NewLocalHandlerService(fp string, debug bool, dbResource *resource.DbResource, Pe *persist.Persister, userDataStore db.Db, cfg engine.Config, rs resource.Resource) (*LocalHandlerService, error) { +func NewLocalHandlerService(fp string, debug bool, dbResource *resource.DbResource, cfg engine.Config, rs resource.Resource) (*LocalHandlerService, error) { parser, err := getParser(fp, debug) if err != nil { return nil, err } return &LocalHandlerService{ - Parser: parser, - DbRs: dbResource, - Pe: Pe, - UserdataStore: userDataStore, - Cfg: cfg, - Rs: rs, + Parser: parser, + DbRs: dbResource, + Cfg: cfg, + Rs: rs, }, nil } +func (localHandlerService *LocalHandlerService) WithPersister(Pe *persist.Persister) { + localHandlerService.Pe = Pe +} + +func (localHandlerService *LocalHandlerService) WithDataStore(db *db.Db) { + localHandlerService.UserdataStore = db +} + func (localHandlerService *LocalHandlerService) GetHandler() (*ussd.Handlers, error) { - ussdHandlers, err := ussd.NewHandlers(localHandlerService.Parser, localHandlerService.UserdataStore) + ussdHandlers, err := ussd.NewHandlers(localHandlerService.Parser, *localHandlerService.UserdataStore) if err != nil { return nil, err }