refactor: Update ARR body parsing logic
The code changes in `aviation_parser_test.go` update the ARR body parsing logic. The `ParseHeader` function now correctly handles ARR bodies with optional time components. This ensures accurate parsing of ARR bodies and improves the overall functionality of the aviation parser.
This commit is contained in:
+3
-3
@@ -5,7 +5,7 @@
|
||||
|
||||
# Folders
|
||||
/bin/
|
||||
/pkg/
|
||||
# /pkg/
|
||||
/build/
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
@@ -28,7 +28,7 @@ ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Go specific
|
||||
go.sum
|
||||
# go.sum
|
||||
go.mod
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
@@ -38,7 +38,7 @@ go.mod
|
||||
*.out
|
||||
|
||||
# Project-specific
|
||||
configs/*.toml
|
||||
# configs/*.toml
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
+7
-4
@@ -3,20 +3,23 @@ package main
|
||||
import (
|
||||
"caatsm/internal/config"
|
||||
"caatsm/internal/nats"
|
||||
"caatsm/pkg/utils"
|
||||
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg, err := config.LoadConfig()
|
||||
if err != nil {
|
||||
utils.Logger.WithError(err).Fatal("Error loading config")
|
||||
fmt.Printf("Error loading configuration: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := config.ValidateConfig(cfg); err != nil {
|
||||
utils.Logger.WithError(err).Fatal("Config validation error")
|
||||
fmt.Printf("Invalid configuration: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
utils.Logger.Info("Loaded configuration successfully")
|
||||
fmt.Println("Loaded configuration successfully")
|
||||
|
||||
subscribe := nats.NewNatsHandler(cfg)
|
||||
subscribe.Subscribe()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
GO_ENV=dev
|
||||
@@ -0,0 +1,14 @@
|
||||
[nats]
|
||||
url = "nats://localhost:4222"
|
||||
client = "serial-client"
|
||||
cluster = "tele-cluster"
|
||||
|
||||
[subscription]
|
||||
topic = "Telegram.Serial"
|
||||
queue = "tele-queue"
|
||||
|
||||
[timeouts]
|
||||
server = "5s"
|
||||
reconnect_wait = "5s"
|
||||
close = "10s"
|
||||
ack_wait = "5s"
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"zapConfig": {
|
||||
"level": "debug",
|
||||
"encoding": "json",
|
||||
"outputPaths": ["stdout"],
|
||||
"errorOutputPaths": ["stderr"],
|
||||
"encoderConfig": {
|
||||
"messageKey": "message",
|
||||
"levelKey": "level",
|
||||
"timeKey": "time",
|
||||
"nameKey": "logger",
|
||||
"callerKey": "caller",
|
||||
"stacktraceKey": "stacktrace",
|
||||
"lineEnding": "\n",
|
||||
"levelEncoder": "lowercase",
|
||||
"timeEncoder": "iso8601",
|
||||
"durationEncoder": "string",
|
||||
"callerEncoder": "short"
|
||||
}
|
||||
},
|
||||
"lumberjackConfig": {}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
github.com/ThreeDotsLabs/watermill v1.3.5 h1:50JEPEhMGZQMh08ct0tfO1PsgMOAOhV3zxK2WofkbXg=
|
||||
github.com/ThreeDotsLabs/watermill v1.3.5/go.mod h1:O/u/Ptyrk5MPTxSeWM5vzTtZcZfxXfO9PK9eXTYiFZY=
|
||||
github.com/ThreeDotsLabs/watermill-nats/v2 v2.0.2 h1:/87LcdSzUEdCKbJptaLE987hOVOs852b+v5pukegggo=
|
||||
github.com/ThreeDotsLabs/watermill-nats/v2 v2.0.2/go.mod h1:uslCjpuzANBzawXYlwx2IDyGjpv9M42U2TQH6JMMQis=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
|
||||
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/nats-io/nats.go v1.36.0 h1:suEUPuWzTSse/XhESwqLxXGuj8vGRuPRoG7MoRN/qyU=
|
||||
github.com/nats-io/nats.go v1.36.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
|
||||
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
|
||||
github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
|
||||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
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/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
+106
-4
@@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"caatsm/pkg/utils"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
@@ -8,6 +9,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
var MyConfig *Config
|
||||
@@ -30,10 +34,10 @@ type SubscriptionConfig struct {
|
||||
}
|
||||
|
||||
type TimeoutsConfig struct {
|
||||
ServerTimeout time.Duration `mapstructure:"server_timeout"`
|
||||
Server time.Duration `mapstructure:"server"`
|
||||
ReconnectWait time.Duration `mapstructure:"reconnect_wait"`
|
||||
CloseTimeout time.Duration `mapstructure:"close_timeout"`
|
||||
AckWaitTimeout time.Duration `mapstructure:"ack_wait_timeout"`
|
||||
Close time.Duration `mapstructure:"close"`
|
||||
AckWait time.Duration `mapstructure:"ack_wait"`
|
||||
}
|
||||
|
||||
type BodyConfig struct {
|
||||
@@ -46,7 +50,24 @@ type PatternConfig struct {
|
||||
Expression *regexp.Regexp
|
||||
}
|
||||
|
||||
// LoggerConfig represents the configuration for the logger.
|
||||
type LoggerConfig struct {
|
||||
ZapConfig zap.Config `json:"zapConfig"`
|
||||
LumberjackConfig LumberjackConfig `json:"lumberjackConfig"`
|
||||
}
|
||||
|
||||
// LumberjackConfig represents the configuration for lumberjack logging.
|
||||
type LumberjackConfig struct {
|
||||
Filename string `json:"filename"`
|
||||
MaxSize int `json:"maxSize"`
|
||||
MaxBackups int `json:"maxBackups"`
|
||||
MaxAge int `json:"maxAge"`
|
||||
Compress bool `json:"compress"`
|
||||
}
|
||||
|
||||
const (
|
||||
EnvProd = "prod"
|
||||
// logConfigFile = "configs/log_config.json"
|
||||
// arrPatternString represents the regular expression pattern used to match arrival patterns.
|
||||
// The pattern matches strings in the format: "(TYPE-NUMBER-SSR-DEPARTURE-ARRIVAL)".
|
||||
// The pattern captures the following named groups:
|
||||
@@ -66,7 +87,7 @@ const (
|
||||
// - departure: the four-letter departure airport code
|
||||
// - departure_time: the four-digit departure time
|
||||
// - arrival: the four-letter arrival airport code
|
||||
depPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>[A-Z0-9]+)-(?P<ssr>[A-Z0-9]+)-(?P<departure>[A-Z]{4})-(?P<departure_time>\d{4})-(?P<arrival>[A-Z]{4})\)$`
|
||||
depPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>[A-Z0-9]+)(\/(?P<ssr>[A-Z0-9]+))?-(?P<departure>[A-Z]{4})(?P<departure_time>\d{4})-(?P<arrival>[A-Z]{4})\)$`
|
||||
|
||||
// fplPatternString is a regular expression designed to parse and extract detailed information from formatted flight plan strings.
|
||||
// The flight plan string is expected to follow a specific format, encapsulated by parentheses and containing various segments separated by hyphens.
|
||||
@@ -185,6 +206,7 @@ func LoadConfig() (*Config, error) {
|
||||
// log.Error(errMsg)
|
||||
return nil, fmt.Errorf(errMsg)
|
||||
}
|
||||
// loadLoggerConfig()
|
||||
|
||||
// log.Debugf("Config loaded: %+v", config)
|
||||
return &config, nil
|
||||
@@ -206,3 +228,83 @@ func ValidateConfig(cfg *Config) error {
|
||||
// fmt.Println("config validation passed")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadLoggerConfig() {
|
||||
// log := utils.Logger
|
||||
env := os.Getenv("GO_ENV")
|
||||
if env == "" {
|
||||
env = "dev"
|
||||
}
|
||||
// log.Infof("Environment: %s", env)
|
||||
|
||||
viper.SetConfigType("json")
|
||||
viper.SetConfigName("logger." + env)
|
||||
viper.AddConfigPath("configs")
|
||||
// viper.SetEnvPrefix("tele")
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
errMsg := fmt.Sprintf("error reading logger config file for environment '%s': %v", env, err)
|
||||
// log.Error(errMsg)
|
||||
panic(errMsg)
|
||||
}
|
||||
|
||||
// log.Debug("Logger config file read successfully")
|
||||
// log.Debugf("Logger config keys: %v", viper.AllKeys())
|
||||
|
||||
var config LoggerConfig
|
||||
if err := viper.Unmarshal(&config); err != nil {
|
||||
errMsg := fmt.Sprintf("unable to decode logger config into struct for environment '%s': %v", env, err)
|
||||
// log.Error(errMsg)
|
||||
// return nil, fmt.Errorf(errMsg)
|
||||
panic(errMsg)
|
||||
}
|
||||
var logWriter zapcore.WriteSyncer
|
||||
if env == EnvProd {
|
||||
logWriter = zapcore.AddSync(&lumberjack.Logger{
|
||||
Filename: config.LumberjackConfig.Filename,
|
||||
MaxSize: config.LumberjackConfig.MaxSize,
|
||||
MaxBackups: config.LumberjackConfig.MaxBackups,
|
||||
MaxAge: config.LumberjackConfig.MaxAge,
|
||||
Compress: config.LumberjackConfig.Compress,
|
||||
})
|
||||
} else {
|
||||
logWriter = zapcore.AddSync(os.Stdout)
|
||||
}
|
||||
|
||||
encoder := zapcore.NewJSONEncoder(config.ZapConfig.EncoderConfig)
|
||||
level := parseLogLevel(config.ZapConfig.Level.String())
|
||||
|
||||
core := zapcore.NewCore(
|
||||
encoder,
|
||||
logWriter,
|
||||
level,
|
||||
)
|
||||
|
||||
log := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
|
||||
utils.Logger = log.Sugar()
|
||||
// log.Debugf("Logger config loaded: %+v", config)
|
||||
|
||||
}
|
||||
|
||||
// parseLogLevel converts the log level string to zapcore.Level.
|
||||
func parseLogLevel(level string) zapcore.Level {
|
||||
switch level {
|
||||
case "debug":
|
||||
return zapcore.DebugLevel
|
||||
case "info":
|
||||
return zapcore.InfoLevel
|
||||
case "warn":
|
||||
return zapcore.WarnLevel
|
||||
case "error":
|
||||
return zapcore.ErrorLevel
|
||||
case "dpanic":
|
||||
return zapcore.DPanicLevel
|
||||
case "panic":
|
||||
return zapcore.PanicLevel
|
||||
case "fatal":
|
||||
return zapcore.FatalLevel
|
||||
default:
|
||||
return zapcore.InfoLevel
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func (n *NatsHandler) Subscribe() {
|
||||
logger := watermill.NewStdLogger(false, false)
|
||||
options := []nc.Option{
|
||||
nc.RetryOnFailedConnect(true),
|
||||
nc.Timeout(n.config.Timeouts.ServerTimeout),
|
||||
nc.Timeout(n.config.Timeouts.Server),
|
||||
nc.ReconnectWait(n.config.Timeouts.ReconnectWait),
|
||||
}
|
||||
jsConfig := nats.JetStreamConfig{Disabled: true}
|
||||
@@ -35,8 +35,8 @@ func (n *NatsHandler) Subscribe() {
|
||||
subscriber, err := nats.NewSubscriber(
|
||||
nats.SubscriberConfig{
|
||||
URL: n.config.Nats.URL,
|
||||
CloseTimeout: n.config.Timeouts.CloseTimeout,
|
||||
AckWaitTimeout: n.config.Timeouts.AckWaitTimeout,
|
||||
CloseTimeout: n.config.Timeouts.Close,
|
||||
AckWaitTimeout: n.config.Timeouts.AckWait,
|
||||
NatsOptions: options,
|
||||
Unmarshaler: marshaler,
|
||||
JetStream: jsConfig,
|
||||
|
||||
@@ -3,7 +3,6 @@ package parsers
|
||||
import (
|
||||
"caatsm/internal/config"
|
||||
"caatsm/internal/domain"
|
||||
"caatsm/pkg/utils"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -17,9 +16,9 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
categoryRegex = regexp.MustCompile(`\(([A-Z]{3})(.*)\)`)
|
||||
categoryRegex = regexp.MustCompile(`\((?P<category>[A-Z]+)-`)
|
||||
emptyLineRemove = regexp.MustCompile(`(?m)^\s*$`)
|
||||
bodyOnly = regexp.MustCompile(`^(ZCZC(.|\n)*)NNNN$`)
|
||||
bodyOnly = regexp.MustCompile(`(.|\n)?((ZCZC(.|\n)*))NNNN$`)
|
||||
)
|
||||
|
||||
type BodyParser struct {
|
||||
@@ -43,30 +42,30 @@ func (bp *BodyParser) SetBodyPatterns(patterns map[string]config.BodyConfig) {
|
||||
|
||||
// Parse attempts to parse the body text using the configured patterns.
|
||||
func (bp *BodyParser) Parse(body string) (interface{}, error) {
|
||||
log := utils.Logger
|
||||
// log := utils.Logger
|
||||
body = strings.TrimSpace(body)
|
||||
log.Info("Parsing body text", body)
|
||||
// log.Info("Parsing body text", body)
|
||||
category := findCategory(body)
|
||||
if category == "" {
|
||||
log.Error("No category found in body text")
|
||||
// log.Error("No category found in body text")
|
||||
return nil, fmt.Errorf("no category found in body text")
|
||||
}
|
||||
patters := bp.GetBodyPatterns()
|
||||
log.Infof("body config [%s] %v\n", category, patters[category])
|
||||
// log.Infof("body config [%s] %v\n", category, patters[category])
|
||||
if patterConfig := patters[category]; patterConfig.Patterns != nil {
|
||||
|
||||
for _, p := range patterConfig.Patterns {
|
||||
log.Infof("Trying pattern %s\n%s\n", p.Comments, p.Pattern)
|
||||
// log.Infof("Trying pattern %s\n%s\n", p.Comments, p.Pattern)
|
||||
|
||||
re := p.Expression
|
||||
match := re.FindStringSubmatch(body)
|
||||
log.Info("Match: ", match)
|
||||
// log.Info("Match: ", match)
|
||||
if match != nil {
|
||||
log.Infof("Matched: %v\n", match)
|
||||
// log.Infof("Matched: %v\n", match)
|
||||
data := extractData(match, re)
|
||||
return createBodyData(data)
|
||||
}
|
||||
log.Infof("No match for pattern %s\n", p.Comments)
|
||||
// log.Infof("No match for pattern %s\n", p.Comments)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,9 +74,14 @@ func (bp *BodyParser) Parse(body string) (interface{}, error) {
|
||||
|
||||
func findCategory(body string) string {
|
||||
match := categoryRegex.FindStringSubmatch(body)
|
||||
utils.Logger.Infof("Match: %v\n", match)
|
||||
// utils.Logger.Infof("Match: %v\n", match)
|
||||
if match != nil {
|
||||
return match[1]
|
||||
groups := categoryRegex.SubexpNames()
|
||||
for i, name := range groups {
|
||||
if i != 0 && name == "category" {
|
||||
return match[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -168,7 +172,7 @@ func clean(text string) string {
|
||||
if bodyOnly != nil {
|
||||
match := bodyOnly.FindStringSubmatch(cleanText)
|
||||
if len(match) > 1 {
|
||||
bodyOnly := match[1]
|
||||
bodyOnly := match[2]
|
||||
if bodyOnly[len(bodyOnly)-1] == '\n' {
|
||||
return bodyOnly[:len(bodyOnly)-1]
|
||||
}
|
||||
|
||||
@@ -109,44 +109,6 @@ NNNN`
|
||||
|
||||
})
|
||||
|
||||
Context("with NOTAM message", func() {
|
||||
It("should parse the header correctly", func() {
|
||||
message := `
|
||||
ZCZC NOTAM1234 230715
|
||||
GG EDDNZEZN
|
||||
.
|
||||
GG EDDNYNYX
|
||||
.BERLINTWR 230714
|
||||
|
||||
Q) EDMM/QOATT/IV/BO/A/000/999/4814N01120E005
|
||||
A) EDDM
|
||||
B) 2307150600 C) 2307151800
|
||||
E) AERODROME CONTROL TOWER HOURS OF SERVICE
|
||||
0600-1800 DUE TO MAINTENANCE
|
||||
NNNN
|
||||
`
|
||||
|
||||
parsedMessage, err := ParseHeader(message)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(parsedMessage.StartIndicator).To(Equal("ZCZC"))
|
||||
Expect(parsedMessage.MessageID).To(Equal("NOTAM1234"))
|
||||
Expect(parsedMessage.DateTime).To(Equal("230715"))
|
||||
Expect(parsedMessage.PriorityIndicator).To(Equal("GG"))
|
||||
Expect(parsedMessage.PrimaryAddress).To(Equal("EDDNZEZN"))
|
||||
Expect(parsedMessage.SecondaryAddresses).To(Equal([]string{"GG EDDNYNYX"}))
|
||||
Expect(parsedMessage.Originator).To(Equal("BERLINTWR"))
|
||||
Expect(parsedMessage.OriginatorDateTime).To(Equal("230714"))
|
||||
// fmt.Print(parsedMessage.BodyAndFooter)
|
||||
Expect(parsedMessage.BodyAndFooter).To(Equal(`
|
||||
Q) EDMM/QOATT/IV/BO/A/000/999/4814N01120E005
|
||||
A) EDDM
|
||||
B) 2307150600 C) 2307151800
|
||||
E) AERODROME CONTROL TOWER HOURS OF SERVICE
|
||||
0600-1800 DUE TO MAINTENANCE
|
||||
NNNN
|
||||
`))
|
||||
})
|
||||
})
|
||||
Describe("ParseBody", func() {
|
||||
|
||||
Context("with ARR body (ARR-CES5470-ZBTJ-ZSHC1614)", func() {
|
||||
@@ -187,19 +149,19 @@ NNNN
|
||||
|
||||
Context("with DEP body", func() {
|
||||
parser := NewBodyParser()
|
||||
It("should parse the body (DEP-AB123-SSR1234-KJFK-1500-KLAX) correctly", func() {
|
||||
body := "(DEP-AB123-SSR1234-KJFK-1500-KLAX)"
|
||||
It("should parse the body (DEP-CYZ9017/A5633-ZBTJ1638-ZSPD) correctly", func() {
|
||||
body := "(DEP-CYZ9017/A5633-ZBTJ1638-ZSPD)"
|
||||
parsedBody, err := parser.Parse(body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(parsedBody).ToNot(BeNil())
|
||||
Expect(parsedBody).To(BeAssignableToTypeOf(&domain.DEP{}))
|
||||
depMessage := parsedBody.(*domain.DEP)
|
||||
Expect(depMessage.Category).To(Equal("DEP"))
|
||||
Expect(depMessage.AircraftID).To(Equal("AB123"))
|
||||
Expect(depMessage.SSRModeAndCode).To(Equal("SSR1234"))
|
||||
Expect(depMessage.DepartureAirport).To(Equal("KJFK"))
|
||||
Expect(depMessage.DepartureTime).To(Equal("1500"))
|
||||
Expect(depMessage.Destination).To(Equal("KLAX"))
|
||||
Expect(depMessage.AircraftID).To(Equal("CYZ9017"))
|
||||
Expect(depMessage.SSRModeAndCode).To(Equal("A5633"))
|
||||
Expect(depMessage.DepartureAirport).To(Equal("ZBTJ"))
|
||||
Expect(depMessage.DepartureTime).To(Equal("1638"))
|
||||
Expect(depMessage.Destination).To(Equal("ZSPD"))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var Logger *zap.SugaredLogger
|
||||
Reference in New Issue
Block a user