Compare commits

..

4 Commits

Author SHA1 Message Date
lash
c3cbe1cd92
Add connstr to last executable 2025-01-04 09:41:24 +00:00
lash
418080d093 Merge branch 'lash/purify' into lash/purify-more 2025-01-04 09:38:23 +00:00
lash
2e30739ec9
Implement connstr 2025-01-04 09:37:12 +00:00
d5a2680500
make context accessible 2025-01-04 12:02:45 +03:00
12 changed files with 249 additions and 76 deletions

View File

@ -8,6 +8,7 @@ import (
"os"
"os/signal"
"path"
"path/filepath"
"strconv"
"syscall"
@ -15,11 +16,10 @@ import (
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/common"
"git.grassecon.net/urdt/ussd/config"
"git.grassecon.net/urdt/ussd/initializers"
"git.grassecon.net/urdt/ussd/internal/handlers"
httpserver "git.grassecon.net/urdt/ussd/internal/http/at"
"git.grassecon.net/urdt/ussd/internal/http/at"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/remote"
)
@ -37,23 +37,32 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
var err error
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
flag.Parse()
logg.Infof("start command", "build", build, "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "build", build, "dbdir", connStr, "resourcedir", resourceDir, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -70,14 +79,14 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
rs, err := menuStorageService.GetResource(ctx)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
@ -122,10 +131,10 @@ func main() {
defer stateStore.Close()
rp := &at.ATRequestParser{
context: ctx,
Context: ctx,
}
bsh := handlers.NewBaseSessionHandler(cfg, rs, stateStore, userdataStore, rp, hl)
sh := httpserver.NewATSessionHandler(bsh)
sh := at.NewATSessionHandler(bsh)
mux := http.NewServeMux()
mux.Handle(initializers.GetEnv("AT_ENDPOINT", "/"), sh)

View File

@ -7,6 +7,7 @@ import (
"os"
"os/signal"
"path"
"path/filepath"
"syscall"
"git.defalsify.org/vise.git/engine"
@ -47,24 +48,33 @@ func main() {
config.LoadConfig()
var sessionId string
var dbDir string
var connStr string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId)
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -81,18 +91,19 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
userdataStore, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -8,6 +8,7 @@ import (
"os"
"os/signal"
"path"
"path/filepath"
"strconv"
"syscall"
@ -36,23 +37,32 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
var err error
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr, "resourcedir", resourceDir, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -69,14 +79,14 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
rs, err := menuStorageService.GetResource(ctx)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/logging"
@ -30,19 +31,28 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var size uint
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "outputsize", size)
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
@ -58,9 +68,9 @@ func main() {
}
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err := menuStorageService.EnsureDbDir()
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)

View File

@ -23,17 +23,19 @@ type StorageServices interface {
GetPersister(ctx context.Context) (*persist.Persister, error)
GetUserdataDb(ctx context.Context) (db.Db, error)
GetResource(ctx context.Context) (resource.Resource, error)
EnsureDbDir() error
SetConn(connStr string) error
}
type StorageService struct {
svc *storage.MenuStorageService
}
func NewStorageService(dbDir string) *StorageService {
return &StorageService{
svc: storage.NewMenuStorageService(dbDir, ""),
func NewStorageService(connStr string) (*StorageService, error) {
svc := &StorageService{
svc: storage.NewMenuStorageService(""),
}
err := svc.SetConn(connStr)
return svc, err
}
func(ss *StorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
@ -48,6 +50,6 @@ func(ss *StorageService) GetResource(ctx context.Context) (resource.Resource, er
return nil, errors.New("not implemented")
}
func(ss *StorageService) EnsureDbDir() error {
return ss.svc.EnsureDbDir()
func(ss *StorageService) SetConn(connStr string) error {
return ss.svc.SetConn(connStr)
}

View File

@ -7,6 +7,7 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/urdt/ussd/config"
@ -28,23 +29,38 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", ".", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.Parse()
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
logg.Infof("start command", "connstr", connStr)
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", database)
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connection string error: %v", err)
os.Exit(1)
}
store, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"git.grassecon.net/urdt/ussd/config"
"git.grassecon.net/urdt/ussd/initializers"
@ -28,23 +29,36 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", ".state", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.Parse()
if connStr == "." {
connStr, err = filepath.Abs(".state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, "auto connstr generate error: %v", err)
os.Exit(1)
}
}
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", database)
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err = menuStorageService.SetConn(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connection string error: %v", err)
os.Exit(1)
}
store, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -15,7 +15,7 @@ import (
)
type ATRequestParser struct {
context context.Context
Context context.Context
}
func (arp *ATRequestParser) GetSessionId(rq any) (string, error) {
@ -43,7 +43,7 @@ func (arp *ATRequestParser) GetSessionId(rq any) (string, error) {
decodedStr := string(logBytes)
sessionId, err := extractATSessionId(decodedStr)
if err != nil {
context.WithValue(arp.context, "at-session-id", sessionId)
context.WithValue(arp.Context, "at-session-id", sessionId)
}
logg.Debugf("Received request:", decodedStr)
}

View File

@ -1,5 +1,11 @@
package storage
import (
"fmt"
"net/url"
"path"
)
const (
DBTYPE_MEM = iota
DBTYPE_GDBM
@ -11,11 +17,56 @@ type connData struct {
str string
}
func toConnData(s string) connData {
func (cd *connData) DbType() int {
return cd.typ
}
func (cd *connData) String() string {
return cd.str
}
func probePostgres(s string) (string, bool) {
v, err := url.Parse(s)
if err != nil {
return "", false
}
if v.Scheme != "postgres" {
return "", false
}
return s, true
}
func probeGdbm(s string) (string, bool) {
if !path.IsAbs(s) {
return "", false
}
if path.Ext(s) != ".gdbm" {
return "", false
}
s = path.Clean(s)
return s, true
}
func toConnData(connStr string) (connData, error) {
var o connData
if s == "" {
return o
if connStr == "" {
return o, nil
}
return o
v, ok := probePostgres(connStr)
if ok {
o.typ = DBTYPE_POSTGRES
o.str = v
return o, nil
}
v, ok = probeGdbm(connStr)
if ok {
o.typ = DBTYPE_GDBM
o.str = v
return o, nil
}
return o, fmt.Errorf("invalid connection string: %s", connStr)
}

View File

@ -0,0 +1,37 @@
package storage
import (
"testing"
)
func TestParseConnStr(t *testing.T) {
svc := NewMenuStorageService("")
err := svc.SetConn("postgres://foo:bar@localhost:5432/baz")
if err != nil {
t.Fatal(err)
}
err = svc.SetConn("/foo/bar/baz.gdbm")
if err != nil {
t.Fatal(err)
}
err = svc.SetConn("foo/bar/baz.gdbm")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("http://foo/bar")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("foo/bar/baz.txt")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("/foo/bar")
if err == nil {
t.Fatalf("expected error")
}
err = svc.SetConn("foo/bar")
if err == nil {
t.Fatalf("expected error")
}
}

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"path"
"git.defalsify.org/vise.git/db"
fsdb "git.defalsify.org/vise.git/db/fs"
@ -24,11 +23,12 @@ type StorageService interface {
GetPersister(ctx context.Context) (*persist.Persister, error)
GetUserdataDb(ctx context.Context) db.Db
GetResource(ctx context.Context) (resource.Resource, error)
EnsureDbDir() error
SetConn(connStr string) error
}
type MenuStorageService struct {
dbDir string
//dbDir string
conn connData
resourceDir string
resourceStore db.Db
stateStore db.Db
@ -51,36 +51,47 @@ func buildConnStr() string {
return connString
}
func NewMenuStorageService(dbDir string, resourceDir string) *MenuStorageService {
func NewMenuStorageService(resourceDir string) *MenuStorageService {
return &MenuStorageService{
dbDir: dbDir,
resourceDir: resourceDir,
}
}
func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, fileName string) (db.Db, error) {
database, ok := ctx.Value("Database").(string)
if !ok {
return nil, fmt.Errorf("failed to select the database")
func (ms *MenuStorageService) SetConn(connStr string) error {
o, err := toConnData(connStr)
if err != nil {
return err
}
ms.conn = o
return nil
}
func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, fileName string) (db.Db, error) {
var newDb db.Db
var err error
// database, ok := ctx.Value("Database").(string)
// if !ok {
// return nil, fmt.Errorf("failed to select the database")
// }
if existingDb != nil {
return existingDb, nil
}
var newDb db.Db
var err error
if database == "postgres" {
dbTyp := ms.conn.DbType()
if dbTyp == DBTYPE_POSTGRES {
newDb = postgres.NewPgDb()
connStr := buildConnStr()
err = newDb.Connect(ctx, connStr)
} else {
} else if dbTyp == DBTYPE_GDBM {
err = ms.ensureDbDir()
if err != nil {
return nil, err
}
newDb = gdbmstorage.NewThreadGdbmDb()
storeFile := path.Join(ms.dbDir, fileName)
err = newDb.Connect(ctx, storeFile)
} else {
return nil, fmt.Errorf("unsupported connection string: %s", ms.conn.String())
}
err = newDb.Connect(ctx, ms.conn.String())
if err != nil {
return nil, err
}
@ -137,8 +148,8 @@ func (ms *MenuStorageService) GetStateStore(ctx context.Context) (db.Db, error)
return ms.stateStore, nil
}
func (ms *MenuStorageService) EnsureDbDir() error {
err := os.MkdirAll(ms.dbDir, 0700)
func (ms *MenuStorageService) ensureDbDir() error {
err := os.MkdirAll(ms.conn.String(), 0700)
if err != nil {
return fmt.Errorf("state dir create exited with error: %v\n", err)
}

View File

@ -41,9 +41,11 @@ func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
dbDir := ".test_state"
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
//menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(resourceDir)
err := menuStorageService.EnsureDbDir()
//err := menuStorageService.EnsureDbDir()
err := menuStorageService.SetConn(dbDir)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)