cml04-l2-rsm-in/internal/server/server.go

225 lines
6.9 KiB
Go
Raw Normal View History

2024-08-20 10:08:32 +02:00
package server
import (
"bytes"
"context"
"encoding/binary"
"net"
"time"
"git.espin.casa/albert/cml04-gdm-int/pkg/api"
"git.espin.casa/albert/cml04-l2-rsm-in/internal/helpers"
"git.espin.casa/albert/cml04-l2-rsm-in/internal/service"
"git.espin.casa/albert/cml04-l2-rsm-in/internal/types"
"git.espin.casa/albert/logger"
)
type Server struct {
address string
svc service.IService
log logger.LoggerAdapter
}
type Client struct {
conn net.Conn
svc service.IService
log logger.LoggerAdapter
}
func (client *Client) handleRequest() {
// telegram bytes buffer holder 4096 maximun telegram size defined by SMS
telegramBytes := bytes.NewBuffer(make([]byte, 4096))
for {
_, err := client.conn.Read(telegramBytes.Bytes())
if err != nil {
client.log.Error("reading telegram failed", err, logger.LogFields{})
return
}
// interpret first 24 bytes as header
header := &types.TelegramHeader{}
headerReader := bytes.NewReader(telegramBytes.Bytes()[:24])
if err := binary.Read(headerReader, binary.LittleEndian, header); err != nil {
client.log.Error("interpreting telegram header failed", err, logger.LogFields{})
return
}
// switch telegram id
switch header.TelegramID {
// handle telegram data
case types.BdReqTelegramID:
// read telegram data
telegramData := &types.BdRequestTelegram{}
if err := binary.Read(telegramBytes, binary.LittleEndian, telegramData); err != nil {
client.log.Error("reading telegram content failed", err, logger.LogFields{})
return
}
// clean roll set id
id := helpers.CleanString(string(telegramData.BdRollSetId[:]))
// api request roll
req := &api.BdRollDataReq{
Sender: "cml04-l2-rsm",
RollId: id,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}
// create context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// handle telegram data
res, err := client.handleBdDataRequest(ctx, req)
if err != nil {
client.log.Error("processing telegram failed", err, logger.LogFields{})
return
}
// publish response
if err := client.handlePublishBdRollData(ctx, res); err != nil {
client.log.Error("publishing BD roll data failed", err, logger.LogFields{})
return
}
case types.UrReqTelegramID:
// read telegram data
telegramData := &types.UrRequestTelegram{}
if err := binary.Read(telegramBytes, binary.LittleEndian, telegramData); err != nil {
client.log.Error("reading telegram content failed", err, logger.LogFields{})
return
}
// clean roll set id
id := helpers.CleanString(string(telegramData.UrRollSetId[:]))
// api request roll
req := &api.UrRollDataReq{
Sender: "cml04-l2-rsm",
RollId: id,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}
// handle telegram data
res, err := client.handleUrReqTelegram(context.Background(), req)
if err != nil {
client.log.Error("processing telegram failed", err, logger.LogFields{})
return
}
// publish response
if err := client.handlePublishUrRollData(context.Background(), res); err != nil {
client.log.Error("publishing UR roll data failed", err, logger.LogFields{})
return
}
case types.EdReqTelegramID:
// read telegram data
telegramData := &types.EdRequestTelegram{}
if err := binary.Read(telegramBytes, binary.LittleEndian, telegramData); err != nil {
client.log.Error("reading telegram content failed", err, logger.LogFields{})
return
}
// clean roll set id
id := helpers.CleanString(string(telegramData.EdRollSetId[:]))
// api request roll
req := &api.EdRollDataReq{
Sender: "cml04-l2-rsm",
RollId: id,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}
// handle telegram data
res, err := client.handleEdReqTelegram(context.Background(), req)
if err != nil {
client.log.Error("processing telegram failed", err, logger.LogFields{})
return
}
// publish response
if err := client.handlePublishEdRollData(context.Background(), res); err != nil {
client.log.Error("publishing ED roll data failed", err, logger.LogFields{})
return
}
case types.UfReqTelegramID:
// read telegram data
telegramData := &types.UfRequestTelegram{}
if err := binary.Read(telegramBytes, binary.LittleEndian, telegramData); err != nil {
client.log.Error("reading telegram content failed", err, logger.LogFields{})
return
}
// clean roll set id
id := helpers.CleanString(string(telegramData.UfRollSetId[:]))
// api request roll
req := &api.UfRollDataReq{
Sender: "cml04-l2-rsm",
RollId: id,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}
// handle telegram data
res, err := client.handleUfReqTelegram(context.Background(), req)
if err != nil {
client.log.Error("processing telegram failed", err, logger.LogFields{})
return
}
// publish response
if err := client.handlePublishUfRollData(context.Background(), res); err != nil {
client.log.Error("publishing UF roll data failed", err, logger.LogFields{})
return
}
}
}
}
func (client *Client) handlePublishBdRollData(ctx context.Context, data *api.BdRollDataRes) error {
return client.svc.PublishBdRollData(ctx, data.GetRollData())
}
func (client *Client) handlePublishUrRollData(ctx context.Context, data *api.UrRollDataRes) error {
return client.svc.PublishUrRollData(ctx, data.GetRollData())
}
func (client *Client) handlePublishEdRollData(ctx context.Context, data *api.EdRollDataRes) error {
return client.svc.PublishEdRollData(ctx, data.GetRollData())
}
func (client *Client) handlePublishUfRollData(ctx context.Context, data *api.UfRollDataRes) error {
return client.svc.PublishUfRollData(ctx, data.GetRollData())
}
func (client *Client) handleBdDataRequest(ctx context.Context, req *api.BdRollDataReq) (*api.BdRollDataRes, error) {
return client.svc.BdReqTelegram(ctx, req)
}
func (client *Client) handleUrReqTelegram(ctx context.Context, req *api.UrRollDataReq) (*api.UrRollDataRes, error) {
return client.svc.UrReqTelegram(ctx, req)
}
func (client *Client) handleEdReqTelegram(ctx context.Context, req *api.EdRollDataReq) (*api.EdRollDataRes, error) {
return client.svc.EdReqTelegram(ctx, req)
}
func (client *Client) handleUfReqTelegram(ctx context.Context, telegramData *api.UfRollDataReq) (*api.UfRollDataRes, error) {
return client.svc.UfReqTelegram(ctx, telegramData)
}
func (server *Server) Run() error {
// create tcp listener
listener, err := net.Listen("tcp", server.address)
if err != nil {
return err
}
// close on exit
defer listener.Close()
// accept incoming connections
for {
// accept connection
conn, err := listener.Accept()
if err != nil {
return err
}
// create new client
client := &Client{
conn: conn,
svc: server.svc,
log: server.log,
}
// handle client
go client.handleRequest()
}
}
func NewServer(address string, log logger.LoggerAdapter, svc service.IService) *Server {
return &Server{
address: address,
svc: svc,
log: log,
}
}