From da7777c78b72e1f6ff778992860861b7af891a27 Mon Sep 17 00:00:00 2001 From: albert Date: Mon, 21 Oct 2024 21:03:22 +0200 Subject: [PATCH] wip --- cmd/labeler.go | 31 ++++++++++ internal/types/label.go | 36 ++++++++++++ labeler/app/app.go | 71 +++++++++++++++++++++++ labeler/server/server.go | 56 +++++++++++++++++++ labeler/service/service.go | 112 +++++++++++++++++++++++++++++++++++++ 5 files changed, 306 insertions(+) create mode 100644 cmd/labeler.go create mode 100644 internal/types/label.go create mode 100644 labeler/app/app.go create mode 100644 labeler/server/server.go create mode 100644 labeler/service/service.go diff --git a/cmd/labeler.go b/cmd/labeler.go new file mode 100644 index 0000000..ab13941 --- /dev/null +++ b/cmd/labeler.go @@ -0,0 +1,31 @@ +/* +Copyright © 2024 NAME HERE +*/ +package cmd + +import ( + "git.espin.casa/albert/cml04-falcon-system/labeler/app" + "github.com/spf13/cobra" +) + +// labelerCmd represents the labeler command +var labelerCmd = &cobra.Command{ + Use: "labeler", + Short: "Label service", + Long: "Label servicce", + Run: app.Run, +} + +func init() { + rootCmd.AddCommand(labelerCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // labelerCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // labelerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/internal/types/label.go b/internal/types/label.go new file mode 100644 index 0000000..14fff41 --- /dev/null +++ b/internal/types/label.go @@ -0,0 +1,36 @@ +package types + +import ( + "time" + + "gorm.io/gorm" +) + +type Label struct { + ID string `gorm:"primaryKey"` + DateTime string + L2PackageId int16 + L3PackageId string + ProductionOrderNo int32 + CustomerOrderNo int32 + CustomerName string + LogoCode string + SteelGrade string + MaterialCode string + HeatId string + SectionType string + PackageDimenA float32 + PackageDimenB float32 + PackageDimenC float32 + PackageWeight float32 + SectionDimenA float32 + SectionDimenB float32 + SectionDimenC float32 + NumberSections int32 + NumberLayers int32 + NumberSectionsInLayer int32 + FreeTxtLp string + CreatedAt time.Time `gorm:"->;<-:create" json:"createdat,omitempty"` + UpdatedAt time.Time `json:"updated_at,omitempty"` + DeletedAt gorm.DeletedAt `gorm:"index"` +} diff --git a/labeler/app/app.go b/labeler/app/app.go new file mode 100644 index 0000000..3a6471a --- /dev/null +++ b/labeler/app/app.go @@ -0,0 +1,71 @@ +package app + +import ( + "os" + "os/signal" + "syscall" + + "git.espin.casa/albert/cml04-falcon-system/labeler/service" + "git.espin.casa/albert/logger" + "github.com/spf13/cobra" +) + +func Run(cmd *cobra.Command, args []string) { + // read flags + logLevel, _ := cmd.Flags().GetString("log-level") + userName, _ := cmd.Flags().GetString("db-username") + userPass, _ := cmd.Flags().GetString("db-password") + dbHost, _ := cmd.Flags().GetString("db-host") + dbPort, _ := cmd.Flags().GetInt("db-port") + dbName, _ := cmd.Flags().GetString("db-name") + natsHost, _ := cmd.Flags().GetString("nats-host") + natsPort, _ := cmd.Flags().GetInt("nats-port") + // setup logger + log := logger.New(os.Stdout, logLevel) + // log fields + logFields := logger.LogFields{ + "nats_host": natsHost, + "nats_port": natsPort, + "log_level": logLevel, + } + // create service + svc, err := service.New(&service.DBConfig{ + Username: userName, + Password: userPass, + Host: dbHost, + Port: dbPort, + Name: dbName, + }, &service.NATSconfig{ + Host: natsHost, + Port: natsPort, + }) + if err != nil { + log.Error("create service failed", err, logFields) + return + } + // info banner + log.Info("started cml04-falcon-labeler service", logFields) + // wait signal to finish + signal := WaitSignal() + log.Info("signal received", logFields.Add(logger.LogFields{ + "signal": signal, + })) +} + +// WaitSignal catching exit signal +func WaitSignal() os.Signal { + ch := make(chan os.Signal, 2) + signal.Notify( + ch, + syscall.SIGINT, + syscall.SIGQUIT, + syscall.SIGTERM, + ) + for { + sig := <-ch + switch sig { + case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM: + return sig + } + } +} diff --git a/labeler/server/server.go b/labeler/server/server.go new file mode 100644 index 0000000..e1ed3d0 --- /dev/null +++ b/labeler/server/server.go @@ -0,0 +1,56 @@ +package server + +import ( + "encoding/binary" + "io" + + "git.espin.casa/albert/cml04-falcon-system/labeler/service" +) + +type Header struct { + MessageLenght int16 + TelegramID int16 + SequenceCounter int16 + Flags int16 + TimeStamp [8]int16 +} + +type LabelData struct { + Header Header + DateTime [23]byte + L2PackageId int16 + L3PackageId [6]byte + ProductionOrderNo int32 + CustomerOrderNo int32 + CustomerName [30]byte + LogoCode [3]byte + SteelGrade [15]byte + MaterialCode [18]byte + HeatId [10]byte + SectionType [20]byte + PackageDimensions [3]float32 + PackageWeight float32 + SectionDimensions [3]float32 + NumberSections int32 + NumberLayers int32 + NumberSectionsInLayer int32 + FreeTxtLp [180]byte +} + +func (l *LabelData) FillTelegram(reader io.Reader) error { + if err := binary.Read(reader, binary.LittleEndian, &l); err != nil { + return err + } + return nil +} + +type Server struct{} + +func (s *Server) Start() error { + + return nil +} + +func New(svc service.Service) *Server { + return &Server{} +} diff --git a/labeler/service/service.go b/labeler/service/service.go new file mode 100644 index 0000000..c08b6cd --- /dev/null +++ b/labeler/service/service.go @@ -0,0 +1,112 @@ +package service + +import ( + "context" + "fmt" + "time" + + "git.espin.casa/albert/cml04-falcon-system/internal/types" + "github.com/nats-io/nats.go" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +const TimeOut time.Duration = time.Second * 2 + +type DBConfig struct { + Username string + Password string + Host string + Port int + Name string +} + +type NATSconfig struct { + Host string + Port int +} + +func Nats(conf *NATSconfig) (*nats.Conn, error) { + // NATS connect + nc, err := nats.Connect(fmt.Sprintf("nats://%s:%d", conf.Host, conf.Port)) + if err != nil { + return nil, err + } + return nc, nil +} + +func DataBase(conf *DBConfig) (*gorm.DB, error) { + // create dsn string + dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=disable TimeZone=Europe/Madrid", + conf.Host, + conf.Username, + conf.Password, + conf.Name, + conf.Port, + ) + // create open database connection + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + return nil, err + } + return db, nil +} + +type Service interface { + Close(ctx context.Context) error + StoreLabelData(ctx context.Context, data *types.Label) error + PublishNewLabelData(ctx context.Context, id string) error +} + +type service struct { + db *gorm.DB + nc *nats.Conn +} + +// Close implements Service. +func (s *service) Close(ctx context.Context) error { + if err := s.nc.Flush(); err != nil { + return err + } + s.nc.Close() + return nil +} + +// PublishNewLabelData implements Service. +func (s *service) PublishNewLabelData(ctx context.Context, id string) error { + _, err := s.nc.Request("new.label.data", []byte(id), TimeOut) + if err != nil { + return err + } + return nil +} + +// StoreLabelData implements Service. +func (s *service) StoreLabelData(ctx context.Context, data *types.Label) error { + return s.db.WithContext(ctx).Save(data).Error +} + +func AutoMigrate(db *gorm.DB) error { + return db.AutoMigrate(&types.Label{}) +} + +func New(dbConf *DBConfig, natsConf *NATSconfig) (Service, error) { + // create data base + db, err := DataBase(dbConf) + if err != nil { + return nil, err + } + // auto migrate + if err := AutoMigrate(db); err != nil { + return nil, err + } + // create nc connection + nc, err := Nats(natsConf) + if err != nil { + return nil, err + } + return &service{ + db: db, + nc: nc, + }, nil +}