From 5203fb8543d31ec66d39663543af22512106ccfa Mon Sep 17 00:00:00 2001 From: Adrian Zuercher Date: Sun, 4 May 2025 22:21:12 +0200 Subject: [PATCH] new json_data model --- dbm/db.go | 5 +++-- dbm/get.go | 16 +++++++++------- dbm/json_data.go | 14 ++++++++------ dbm/set.go | 8 +++++--- dbm/subscribe.go | 32 +++++++++++++++++++------------- dbm/webSocket.go | 12 ++++++------ go.mod | 2 +- go.sum | 4 ++-- main.go | 8 +++++--- models/datapoint.go | 2 +- server/models/connections.go | 5 ++++- server/server.go | 5 +++++ utils/convert.go | 11 +++++++++++ 13 files changed, 79 insertions(+), 45 deletions(-) diff --git a/dbm/db.go b/dbm/db.go index 6bd40ff..bd27cdb 100644 --- a/dbm/db.go +++ b/dbm/db.go @@ -13,14 +13,15 @@ func (d *DBMHandler) SaveData(c *gin.Context) { s := time.Now() if err := d.SaveDb(); err != nil { r := json_dataModels.NewResponse() - r.SendError(err.Error()) + r.SetError() + r.SetMessage(err.Error()) c.JSON(http.StatusBadRequest, r) return } r := json_dataModels.NewResponse() - r.SendMessage(fmt.Sprintf("DBM %d datapoints saved in: %v", d.GetNumbersOfDatapoints(), time.Since(s))) + r.SetMessage(fmt.Sprintf("DBM %d datapoints saved in: %v", d.GetNumbersOfDatapoints(), time.Since(s))) d.Log.Info("db.SaveData", fmt.Sprintf("DBM %d datapoints saved in: %v", d.GetNumbersOfDatapoints(), time.Since(s))) c.JSON(http.StatusOK, r) } diff --git a/dbm/get.go b/dbm/get.go index 7ae1f66..5aa4933 100644 --- a/dbm/get.go +++ b/dbm/get.go @@ -5,23 +5,25 @@ import ( json_dataModels "github.com/tecamino/tecamino-json_data/models" ) -func (d *DBMHandler) Get(gets []json_dataModels.Get, id, id2 string) { - if gets == nil { +func (d *DBMHandler) Get(req *json_dataModels.Request, id string) { + if req == nil { + return + } else if len(req.Get) == 0 { return } d.RLock() defer d.RUnlock() - r := json_data.NewResponse() - r.Id = id2 - for _, get := range gets { + resp := json_data.NewResponse() + resp.Id = req.Id + for _, get := range req.Get { var depth uint = 1 if get.Query != nil { depth = get.Query.Depth } for _, dp := range d.DB.QueryDatapoints(depth, get.Path) { - r.AddGet(json_dataModels.Get{ + resp.AddGet(json_dataModels.Get{ Uuid: dp.Uuid, Path: dp.Path, Type: dp.Type, @@ -31,7 +33,7 @@ func (d *DBMHandler) Get(gets []json_dataModels.Get, id, id2 string) { } } - if err := d.Conns.SendResponse(id, r); err != nil { + if err := d.Conns.SendResponse(id, resp); err != nil { d.Log.Error("get.Get", err.Error()) } } diff --git a/dbm/json_data.go b/dbm/json_data.go index 2f6daab..1169d62 100644 --- a/dbm/json_data.go +++ b/dbm/json_data.go @@ -13,7 +13,8 @@ func (d *DBMHandler) Json_Data(c *gin.Context) { payload, err := json_data.ParseRequest(c.Request.Body) if err != nil { r := json_data.NewResponse() - r.SendError(err.Error()) + r.SetError() + r.SetMessage(err.Error()) c.JSON(http.StatusBadRequest, r) return } @@ -44,14 +45,14 @@ func (d *DBMHandler) Json_Data(c *gin.Context) { respond.Set, err = d.CreateDatapoints(payload.Set...) if err != nil { r := json_data.NewResponse() - r.SendError(err.Error()) + r.SetError() + r.SetMessage(err.Error()) c.JSON(http.StatusBadRequest, r) return } } c.JSON(200, respond) - return } func (d *DBMHandler) Delete(c *gin.Context) { @@ -59,7 +60,8 @@ func (d *DBMHandler) Delete(c *gin.Context) { payload, err := json_data.ParseRequest(c.Request.Body) if err != nil { r := json_data.NewResponse() - r.SendError(err.Error()) + r.SetError() + r.SetMessage(err.Error()) c.JSON(http.StatusBadRequest, r) return } @@ -71,12 +73,12 @@ func (d *DBMHandler) Delete(c *gin.Context) { response.Set, err = d.RemoveDatapoint(payload.Set...) if err != nil { r := json_data.NewResponse() - r.SendError(err.Error()) + r.SetError() + r.SetMessage(err.Error()) c.JSON(http.StatusBadRequest, r) return } } c.JSON(200, response) - return } diff --git a/dbm/set.go b/dbm/set.go index 867c41a..9d70396 100644 --- a/dbm/set.go +++ b/dbm/set.go @@ -4,14 +4,16 @@ import ( json_dataModels "github.com/tecamino/tecamino-json_data/models" ) -func (d *DBMHandler) Set(sets []json_dataModels.Set) { - if sets == nil { +func (d *DBMHandler) Set(req *json_dataModels.Request) { + if req == nil { + return + } else if len(req.Set) == 0 { return } d.RLock() defer d.RUnlock() - for _, set := range sets { + for _, set := range req.Set { for _, dp := range d.DB.QueryDatapoints(1, set.Path) { dp.UpdateValue(d.Conns, set.Value) } diff --git a/dbm/subscribe.go b/dbm/subscribe.go index 6695b72..2bd2d43 100644 --- a/dbm/subscribe.go +++ b/dbm/subscribe.go @@ -4,17 +4,20 @@ import ( json_dataModels "github.com/tecamino/tecamino-json_data/models" ) -func (d *DBMHandler) Subscribe(subs []json_dataModels.Subscribe, id, id2 string) { - if subs == nil { +func (d *DBMHandler) Subscribe(req *json_dataModels.Request, id string) { + if req == nil { + return + } + if len(req.Subscribe) == 0 { return } d.RLock() defer d.RUnlock() - r := json_dataModels.NewResponse() - r.Id = id2 + resp := json_dataModels.NewResponse() + resp.Id = req.Id - for _, sub := range subs { + for _, sub := range req.Subscribe { for _, dp := range d.DB.QueryDatapoints(sub.Depth, sub.Path) { if sub.Driver != "" { if dp.Drivers == nil || dp.Drivers[sub.Driver] == nil { @@ -22,7 +25,7 @@ func (d *DBMHandler) Subscribe(subs []json_dataModels.Subscribe, id, id2 string) } } dp.AddSubscribtion(id, sub) - r.AddSubscription(json_dataModels.Subscribe{ + resp.AddSubscription(json_dataModels.Subscription{ Uuid: dp.Uuid, Path: dp.Path, Value: dp.Value, @@ -32,34 +35,37 @@ func (d *DBMHandler) Subscribe(subs []json_dataModels.Subscribe, id, id2 string) } } - if err := d.Conns.SendResponse(id, r); err != nil { + if err := d.Conns.SendResponse(id, resp); err != nil { d.Log.Error("subscribe.Subscribe", err.Error()) } } -func (d *DBMHandler) Unsubscribe(subs []json_dataModels.Subscribe, id string) { - if subs == nil { +func (d *DBMHandler) Unsubscribe(req *json_dataModels.Request, id string) { + if req == nil { + return + } + if len(req.Unsubscribe) == 0 { return } d.RLock() defer d.RUnlock() - r := json_dataModels.NewResponse() + resp := json_dataModels.NewResponse() - for _, sub := range subs { + for _, sub := range req.Unsubscribe { for _, dp := range d.DB.QueryDatapoints(sub.Depth, sub.Path) { if _, ok := dp.Subscriptions[id]; !ok { continue } dp.RemoveSubscribtion(id) - r.AddUnsubscription(json_dataModels.Subscribe{ + resp.AddUnsubscription(json_dataModels.Subscription{ Uuid: dp.Uuid, Path: dp.Path, }) } } - if err := d.Conns.SendResponse(id, r); err != nil { + if err := d.Conns.SendResponse(id, resp); err != nil { d.Log.Error("subscribe.Unsubscribe", err.Error()) } } diff --git a/dbm/webSocket.go b/dbm/webSocket.go index 5420841..5080052 100644 --- a/dbm/webSocket.go +++ b/dbm/webSocket.go @@ -45,20 +45,20 @@ func (d *DBMHandler) WebSocket(c *gin.Context) { // Sets - d.Get(request.Get, id, request.Id) + d.Get(request, id) // Sets - d.Set(request.Set) + d.Set(request) // Subscribe - d.Subscribe(request.Subscribe, id, request.Id) + d.Subscribe(request, id) // Unsubscribe - d.Unsubscribe(request.Unsubscribe, id) + d.Unsubscribe(request, id) request.Get = make([]json_dataModels.Get, 0) request.Set = make([]json_dataModels.Set, 0) - request.Subscribe = make([]json_dataModels.Subscribe, 0) - request.Unsubscribe = make([]json_dataModels.Subscribe, 0) + request.Subscribe = make([]json_dataModels.Subscription, 0) + request.Unsubscribe = make([]json_dataModels.Subscription, 0) request = nil } } diff --git a/go.mod b/go.mod index 89cd914..3ee5b24 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/coder/websocket v1.8.13 github.com/gin-gonic/gin v1.10.0 github.com/google/uuid v1.6.0 - github.com/tecamino/tecamino-json_data v0.0.10 + github.com/tecamino/tecamino-json_data v0.0.12 github.com/tecamino/tecamino-logger v0.2.0 ) diff --git a/go.sum b/go.sum index 5dc0e0e..06142fb 100644 --- a/go.sum +++ b/go.sum @@ -63,8 +63,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tecamino/tecamino-json_data v0.0.10 h1:I5xvJ8eRxX0QbMTuSHlAA16FQ8uE49OiCSsQ7Xjircc= -github.com/tecamino/tecamino-json_data v0.0.10/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY= +github.com/tecamino/tecamino-json_data v0.0.12 h1:S4Y+WcfQNrin7P73ZI+4eJWh62IwJVhriRsPGGM8N34= +github.com/tecamino/tecamino-json_data v0.0.12/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY= github.com/tecamino/tecamino-logger v0.2.0 h1:NPH/Gg9qRhmVoW8b39i1eXu/LEftHc74nyISpcRG+XU= github.com/tecamino/tecamino-logger v0.2.0/go.mod h1:0M1E9Uei/qw3e3WA1x3lBo1eP3H5oeYE7GjYrMahnj8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/main.go b/main.go index 914b049..fc79a7d 100644 --- a/main.go +++ b/main.go @@ -10,13 +10,15 @@ import ( ) func main() { - //cli arguments + // cli arguments a := args.Init() + // initiate new database manger dbmHandler, err := dbm.NewDbmHandler(a) if err != nil { panic(err) } + //save database after exeutabe ends defer dbmHandler.SaveDb() //initialize new server @@ -29,20 +31,20 @@ func main() { s.Routes.GET("/saveData", dbmHandler.SaveData) s.Routes.POST("/json_data", dbmHandler.Json_Data) s.Routes.DELETE("/json_data", dbmHandler.Delete) - s.Routes.GET("/", func(c *gin.Context) { c.String(200, "DBM WebSocket Server is running!") }) + // start http server go func() { dbmHandler.Log.Info("main", fmt.Sprintf("http listen on %d", a.Port.Http)) - // start http server if err := s.ServeHttp(a.Port.Http); err != nil { dbmHandler.Log.Error("main", "error http server "+err.Error()) panic(err) } }() + // start https server dbmHandler.Log.Info("main", fmt.Sprintf("https listen on %d", a.Port.Https)) if err := s.ServeHttps(a.Port.Https, a.Cert); err != nil { dbmHandler.Log.Error("main", "error http server "+err.Error()) diff --git a/models/datapoint.go b/models/datapoint.go index 896ea3a..636650a 100644 --- a/models/datapoint.go +++ b/models/datapoint.go @@ -340,7 +340,7 @@ func (d *Datapoint) QueryDatapoints(depth uint, path string) (dps Datapoints) { return } -func (d *Datapoint) AddSubscribtion(id string, sub json_dataModels.Subscribe) { +func (d *Datapoint) AddSubscribtion(id string, sub json_dataModels.Subscription) { if d.Subscriptions == nil { return } diff --git a/server/models/connections.go b/server/models/connections.go index db38f1c..5a9eb51 100644 --- a/server/models/connections.go +++ b/server/models/connections.go @@ -12,11 +12,13 @@ import ( json_dataModels "github.com/tecamino/tecamino-json_data/models" ) +// serves as connection handler of websocket type Connections struct { sync.RWMutex Clients Clients } +// initaiates new conections with client map func NewConnections() *Connections { return &Connections{ Clients: NewClients(), @@ -36,10 +38,11 @@ func (c *Connections) DisconnectWsConnection(id string, code websocket.StatusCod c.Clients.DisconnectWsConnection(id, code, reason) } +// sends json response to client func (c *Connections) SendResponse(id string, r *json_dataModels.Response) error { client, ok := c.Clients[id] if !ok { - return fmt.Errorf("client not found for id " + id) + return fmt.Errorf("client not found for id %s", id) } b, err := json.Marshal(r) diff --git a/server/server.go b/server/server.go index 798b0b0..03cc1e3 100644 --- a/server/server.go +++ b/server/server.go @@ -9,23 +9,28 @@ import ( "github.com/tecamino/tecamino-logger/logging" ) +// server model for database manager websocket type Server struct { Routes *gin.Engine sync.RWMutex Logger *logging.Logger } +// initalizes new dbm server func NewServer() *Server { return &Server{ Routes: gin.Default(), } } +// serve dbm as http func (s *Server) ServeHttp(port uint) error { return s.Routes.Run(fmt.Sprintf(":%d", port)) } +// serve dbm as http func (s *Server) ServeHttps(port uint, cert cert.Cert) error { + // generate self signed tls certificate if err := cert.GenerateSelfSignedCert(); err != nil { return err } diff --git a/utils/convert.go b/utils/convert.go index 4970f9a..261fcd0 100644 --- a/utils/convert.go +++ b/utils/convert.go @@ -5,6 +5,7 @@ import ( "strings" ) +// return any input type to float32 func Float32From(v any) float32 { switch val := v.(type) { case bool: @@ -44,6 +45,7 @@ func Float32From(v any) float32 { } } +// return any input type to float64 func Float64From(v any) float64 { switch val := v.(type) { case bool: @@ -83,6 +85,7 @@ func Float64From(v any) float64 { } } +// return any input type to int8 func Int8From(v any) int8 { switch val := v.(type) { case bool: @@ -122,6 +125,7 @@ func Int8From(v any) int8 { } } +// return any input type to int16 func Int16From(v any) int16 { switch val := v.(type) { case bool: @@ -161,6 +165,7 @@ func Int16From(v any) int16 { } } +// return any input type to int32 func Int32From(v any) int32 { switch val := v.(type) { case bool: @@ -200,6 +205,7 @@ func Int32From(v any) int32 { } } +// return any input type to int64 func Int64From(v any) int64 { switch val := v.(type) { case bool: @@ -239,6 +245,7 @@ func Int64From(v any) int64 { } } +// return any input type to int func Uint8From(v any) uint8 { switch val := v.(type) { case bool: @@ -278,6 +285,7 @@ func Uint8From(v any) uint8 { } } +// return any input type to uint16 func Uint16From(v any) uint16 { switch val := v.(type) { case bool: @@ -317,6 +325,7 @@ func Uint16From(v any) uint16 { } } +// return any input type to uint32 func Uint32From(v any) uint32 { switch val := v.(type) { case bool: @@ -356,6 +365,7 @@ func Uint32From(v any) uint32 { } } +// return any input type to uint64 func Uint64From(v any) uint64 { switch val := v.(type) { case bool: @@ -395,6 +405,7 @@ func Uint64From(v any) uint64 { } } +// return any input type to bool func BoolFrom(v any) bool { switch val := v.(type) { case bool: