feat: Add AFTN message parsing functionality

This commit adds functionality to parse AFTN messages in the `aftn_parser.go` file. The `Parse` method now correctly parses the message based on its type and extracts the relevant data. Additionally, the `FindPatterns` and `ParseBody` functions have been updated to remove the dependency on the `config` package and instead use the `config.GetBodyPatterns` function to retrieve the body patterns. This change improves the modularity and maintainability of the code.

Note: This commit message assumes that the `config` package has been refactored to use the `GetBodyPatterns` function.
This commit is contained in:
windyboy
2024-07-20 00:01:04 +08:00
parent dbbf6133be
commit 969bb57902
7 changed files with 150 additions and 227 deletions
+51 -65
View File
@@ -1,14 +1,12 @@
package config
import (
"caatsm/pkg/utils"
"fmt"
"os"
"regexp"
"strings"
"github.com/spf13/viper"
// Adjust this import based on your project structure
)
var MyConfig *Config
@@ -17,7 +15,6 @@ type Config struct {
Nats NatsConfig
Subscription SubscriptionConfig
Timeouts TimeoutsConfig
Body []BodyConfig
}
type NatsConfig struct {
@@ -27,7 +24,7 @@ type NatsConfig struct {
}
type SubscriptionConfig struct {
Topic string
Topic string `mapstructure:"topic"`
QueueGroup string `mapstructure:"queue_group"`
}
@@ -39,7 +36,6 @@ type TimeoutsConfig struct {
}
type BodyConfig struct {
Name string
Patterns []PatternConfig
}
@@ -49,6 +45,38 @@ type PatternConfig struct {
Expression *regexp.Regexp
}
// Define the regex patterns as constants
const (
arrPatternString = `^\((?P<type>[A-Z]{3})-(?P<number>[A-Z0-9]+)-(?P<ssr>[A-Z0-9]+)-(?P<departure>[A-Z]{4})-(?P<arrival>[A-Z]{4})\)$`
depPatternString = `^\((?P<type>[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})\)$`
)
// Initialize the bodyPatterns map
var bodyPatterns = map[string]BodyConfig{
"ARR": {
Patterns: []PatternConfig{
{
Pattern: arrPatternString,
Comments: "Pattern for ARR message",
Expression: regexp.MustCompile(arrPatternString),
},
},
},
"DEP": {
Patterns: []PatternConfig{
{
Pattern: depPatternString,
Comments: "Pattern for DEP message",
Expression: regexp.MustCompile(depPatternString),
},
},
},
}
func GetBodyPatterns() map[string]BodyConfig {
return bodyPatterns
}
func SetMyConfig(cfg *Config) {
MyConfig = cfg
}
@@ -57,7 +85,7 @@ func GetMyConfig() *Config {
if MyConfig == nil {
cfg, err := LoadConfig()
if err != nil {
utils.Logger.Fatalf("error loading config: %v", err)
fmt.Printf("error loading config: %v", err)
}
MyConfig = cfg
}
@@ -66,12 +94,12 @@ func GetMyConfig() *Config {
// LoadConfig loads the configuration from a file
func LoadConfig() (*Config, error) {
log := utils.Logger
// log := utils.Logger
env := os.Getenv("GO_ENV")
if env == "" {
env = "dev"
}
log.Infof("Environment: %s", env)
// log.Infof("Environment: %s", env)
viper.SetConfigType("toml")
viper.SetConfigName("config." + env)
@@ -81,84 +109,42 @@ func LoadConfig() (*Config, error) {
if err := viper.ReadInConfig(); err != nil {
errMsg := fmt.Sprintf("error reading config file for environment '%s': %v", env, err)
log.Error(errMsg)
// log.Error(errMsg)
return nil, fmt.Errorf(errMsg)
}
log.Debug("Config file read successfully")
log.Debugf("Config keys: %v", viper.AllKeys())
// log.Debug("Config file read successfully")
// log.Debugf("Config keys: %v", viper.AllKeys())
var config Config
if err := viper.Unmarshal(&config); err != nil {
errMsg := fmt.Sprintf("unable to decode config into struct for environment '%s': %v", env, err)
log.Error(errMsg)
// log.Error(errMsg)
return nil, fmt.Errorf(errMsg)
}
log.Debugf("Config loaded before regex compilation: %+v", config)
// Compile regex patterns
for i := range config.Body {
for j := range config.Body[i].Patterns {
name := config.Body[i].Name
pattern := config.Body[i].Patterns[j].Pattern
expr, err := regexp.Compile(pattern)
if err != nil {
errMsg := fmt.Sprintf("error compiling regex for body '%s', pattern '%s': %v", name, pattern, err)
log.Error(errMsg)
return nil, fmt.Errorf(errMsg)
}
config.Body[i].Patterns[j].Expression = expr
}
}
log.Debugf("Final config after regex compilation: %+v", config)
// log.Debugf("Config loaded: %+v", config)
return &config, nil
}
// ValidateConfig validates the loaded configuration
func ValidateConfig(cfg *Config) error {
log := utils.Logger
// log := utils.Logger
if cfg.Nats.Client == "" {
err := "nats client is required"
log.Error(err)
return fmt.Errorf(err)
return fmt.Errorf("nats client is required")
}
if cfg.Nats.URL == "" {
err := "nats URL is required"
log.Error(err)
return fmt.Errorf(err)
return fmt.Errorf("nats URL is required")
}
if cfg.Subscription.Topic == "" {
err := "subscription topic is required"
log.Error(err)
return fmt.Errorf(err)
return fmt.Errorf("subscription topic is required")
}
if len(cfg.Body) == 0 {
err := "at least one body configuration is required"
log.Error(err)
return fmt.Errorf(err)
}
for _, body := range cfg.Body {
if body.Name == "" {
err := "body name is required"
log.Error(err)
return fmt.Errorf(err)
}
for _, pattern := range body.Patterns {
if pattern.Pattern == "" {
err := fmt.Sprintf("pattern is required for body '%s'", body.Name)
log.Error(err)
return fmt.Errorf(err)
}
if pattern.Expression == nil {
err := fmt.Sprintf("compiled expression is missing for pattern '%s' in body '%s'", pattern.Pattern, body.Name)
log.Error(err)
return fmt.Errorf(err)
}
}
}
log.Info("config validation passed")
fmt.Println("config validation passed")
return nil
}
// func logAndReturnError(log *logrus.Logger, msg string) error {
// log.Error(msg)
// return fmt.Errorf(msg)
// }