refactor: Update ARR body parsing logic

The code changes in `pattern_test.go` update the ARR body parsing logic. The message body parsing now correctly handles ARR bodies with a different pattern format. This ensures accurate extraction of data based on patterns and improves the overall functionality of the code.
This commit is contained in:
windyboy
2024-07-23 16:45:03 +08:00
parent 12a9da1ca1
commit 6d1364df7e
7 changed files with 187 additions and 74 deletions
+31 -11
View File
@@ -19,6 +19,7 @@ var (
categoryRegex = regexp.MustCompile(`\((?P<category>[A-Z]+)-`)
emptyLineRemove = regexp.MustCompile(`(?m)^\s*$`)
bodyOnly = regexp.MustCompile(`(.|\n)?(ZCZC(.|\n)*)NNNN(.|\n)?$`)
originator = regexp.MustCompile(`(?P<originatorDateTime>[0-9]+)\s(?P<originator>[A-Z]+)`)
)
type BodyParser struct {
@@ -41,14 +42,14 @@ 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) {
func (bp *BodyParser) Parse(body string) (string, interface{}, error) {
// log := utils.Logger
body = strings.TrimSpace(body)
// log.Info("Parsing body text", body)
category := findCategory(body)
if category == "" {
// log.Error("No category found in body text")
return nil, fmt.Errorf("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])
@@ -63,13 +64,14 @@ func (bp *BodyParser) Parse(body string) (interface{}, error) {
if match != nil {
// log.Infof("Matched: %v\n", match)
data := extractData(match, re)
return createBodyData(data)
}
// log.Infof("No match for pattern %s\n", p.Comments)
}
}
return nil, fmt.Errorf(" no matching pattern found for body: %s", body)
return "", nil, fmt.Errorf(" no matching pattern found for body: %s", body)
}
func findCategory(body string) string {
@@ -98,10 +100,11 @@ func extractData(match []string, re *regexp.Regexp) map[string]string {
}
// createBodyData creates the appropriate domain object based on the type of message.
func createBodyData(data map[string]string) (interface{}, error) {
func createBodyData(data map[string]string) (string, interface{}, error) {
category := data["category"]
switch data["category"] {
case "ARR":
return &domain.ARR{
return category, &domain.ARR{
Category: data["category"],
AircraftID: data["number"],
SSRModeAndCode: data["ssr"],
@@ -110,7 +113,7 @@ func createBodyData(data map[string]string) (interface{}, error) {
ArrivalTime: data["time"],
}, nil
case "DEP":
return &domain.DEP{
return category, &domain.DEP{
Category: data["category"],
AircraftID: data["number"],
SSRModeAndCode: data["ssr"],
@@ -119,7 +122,7 @@ func createBodyData(data map[string]string) (interface{}, error) {
Destination: data["arrival"],
}, nil
case "FPL":
return &domain.FPL{
return category, &domain.FPL{
Category: data["category"],
FlightNumber: data["number"],
ReferenceData: data["reference_data"],
@@ -145,7 +148,7 @@ func createBodyData(data map[string]string) (interface{}, error) {
Remarks: data["remark"],
}, nil
default:
return nil, fmt.Errorf("invalid message type: %s", data["category"])
return category, nil, fmt.Errorf("invalid message type: %s", category)
}
}
@@ -162,10 +165,13 @@ func Parse(rawText string) (*domain.ParsedMessage, error) {
bodyParser := NewBodyParser()
// Parse the body and footer of the message
bodyData, err := bodyParser.Parse(message.BodyAndFooter)
category, bodyData, err := bodyParser.Parse(message.BodyAndFooter)
message.Category = category
if err != nil {
// Return the message with the parsed header and the error
// message.ParsedAt = time.Now()
message.ParsedAt = time.Now()
return &message, err
}
@@ -279,10 +285,24 @@ func parseRemainingLines(lines []string) ([]string, string, string, string) {
}
bodyAndFooter.WriteString(line + "\n")
default:
secondaryAddresses = append(secondaryAddresses, line)
if o1, o2 := getOriginator(line); o1 != "" {
originatorDateTime = o1
originator = o2
} else {
secondaryAddresses = append(secondaryAddresses, line)
}
}
}
}
return secondaryAddresses, originator, originatorDateTime, bodyAndFooter.String()
}
func getOriginator(line string) (string, string) {
match := originator.FindStringSubmatch(line)
if len(match) >= 3 {
return match[1], match[2]
}
return "", ""
}
+93 -13
View File
@@ -115,9 +115,10 @@ NNNN`
body := "(ARR-CES5470-ZBTJ-ZSHC1614)"
parser := NewBodyParser()
It("should parse the body correctly", func() {
parsedBody, err := parser.Parse(body)
category, parsedBody, err := parser.Parse(body)
Expect(err).ToNot(HaveOccurred())
Expect(parsedBody).ToNot(BeNil())
Expect(category).To(Equal("ARR"))
Expect(parsedBody).To(BeAssignableToTypeOf(&domain.ARR{}))
arrMessage := parsedBody.(*domain.ARR)
Expect(arrMessage.Category).To(Equal("ARR"))
@@ -131,32 +132,34 @@ NNNN`
Context("with ARR body", func() {
parser := NewBodyParser()
It("should parse the body (ARR-AB123-SSR1234-KJFK-KLAX1234) correctly", func() {
body := " (ARR-AB123-SSR1234-KJFK-KLAX1234)"
parsedBody, err := parser.Parse(body)
It("should parse the body (ARR-AB123/A1234-KJFK-KLAX1234) correctly", func() {
body := " (ARR-AB123/A1234-KJFK-KLAX1234)"
category, parsedBody, err := parser.Parse(body)
Expect(err).ToNot(HaveOccurred())
Expect(parsedBody).ToNot(BeNil())
Expect(category).To(Equal("ARR"))
Expect(parsedBody).To(BeAssignableToTypeOf(&domain.ARR{}))
arrMessage := parsedBody.(*domain.ARR)
Expect(arrMessage.Category).To(Equal("ARR"))
Expect(arrMessage.AircraftID).To(Equal("AB123"))
Expect(arrMessage.SSRModeAndCode).To(Equal("SSR1234"))
Expect(arrMessage.SSRModeAndCode).To(Equal("A1234"))
Expect(arrMessage.DepartureAirport).To(Equal("KJFK"))
Expect(arrMessage.ArrivalAirport).To(Equal("KLAX"))
})
It("should parse the body (ARR-JAE7433/A0132-RKSI-ZBTJ1604) correctly", func() {
body := " (ARR-JAE7433/A0132-RKSI-ZBTJ1604)"
parsedBody, err := parser.Parse(body)
category, parsedBody, err := parser.Parse(body)
Expect(err).ToNot(HaveOccurred())
Expect(parsedBody).ToNot(BeNil())
Expect(category).To(Equal("ARR"))
Expect(parsedBody).To(BeAssignableToTypeOf(&domain.ARR{}))
arrMessage := parsedBody.(*domain.ARR)
Expect(arrMessage.Category).To(Equal("ARR"))
Expect(arrMessage.AircraftID).To(Equal("AB123"))
Expect(arrMessage.SSRModeAndCode).To(Equal("SSR1234"))
Expect(arrMessage.DepartureAirport).To(Equal("KJFK"))
Expect(arrMessage.ArrivalAirport).To(Equal("KLAX"))
Expect(arrMessage.AircraftID).To(Equal("JAE7433"))
Expect(arrMessage.SSRModeAndCode).To(Equal("A0132"))
Expect(arrMessage.DepartureAirport).To(Equal("RKSI"))
Expect(arrMessage.ArrivalAirport).To(Equal("ZBTJ"))
})
})
@@ -165,9 +168,10 @@ NNNN`
parser := NewBodyParser()
It("should parse the body (DEP-CYZ9017/A5633-ZBTJ1638-ZSPD) correctly", func() {
body := "(DEP-CYZ9017/A5633-ZBTJ1638-ZSPD)"
parsedBody, err := parser.Parse(body)
category, parsedBody, err := parser.Parse(body)
Expect(err).ToNot(HaveOccurred())
Expect(parsedBody).ToNot(BeNil())
Expect(category).To(Equal("DEP"))
Expect(parsedBody).To(BeAssignableToTypeOf(&domain.DEP{}))
depMessage := parsedBody.(*domain.DEP)
Expect(depMessage.Category).To(Equal("DEP"))
@@ -189,9 +193,10 @@ NNNN`
-K0859S1040 PIAKS G330 PIMOL A539 BTO W82 DOGAR
-ZBAA0153 ZBYN
-PBN/A1B2B3B4B5D1L1 NAV/ABAS REG/B6513 EET/ZBPE0112 SEL/KMAL PER/C RIF/FRT N640 ZBYN RMK/TCAS EQUIPPED)`
parsedBody, err := parser.Parse(body)
category, parsedBody, err := parser.Parse(body)
Expect(err).ToNot(HaveOccurred())
Expect(parsedBody).ToNot(BeNil())
Expect(category).To(Equal("FPL"))
Expect(parsedBody).To(BeAssignableToTypeOf(&domain.FPL{}))
fplMessage := parsedBody.(*domain.FPL)
Expect(fplMessage.FlightNumber).To(Equal("CCA1532"))
@@ -246,7 +251,10 @@ NNNN
Expect(parsedMessage.MessageID).To(Equal("TMQ2526"))
Expect(parsedMessage.DateTime).To(Equal("141605"))
Expect(parsedMessage.PrimaryAddress).To(Equal("ZBTJZPZX"))
Expect(parsedMessage.SecondaryAddresses).To(Equal([]string{"141604 ZBACZQZX"}))
Expect(parsedMessage.SecondaryAddresses).To(BeNil())
Expect(parsedMessage.PriorityIndicator).To(Equal("FF"))
Expect(parsedMessage.OriginatorDateTime).To(Equal("141604"))
Expect(parsedMessage.Originator).To(Equal("ZBACZQZX"))
arrmsg := parsedMessage.BodyData.(*domain.ARR)
Expect(arrmsg.Category).To(Equal("ARR"))
@@ -257,5 +265,77 @@ NNNN
Expect(arrmsg.ArrivalTime).To(Equal("1604"))
})
})
Context("real fpl", func() {
message := `ZCZC TMQ2544 141652
FF ZBTJZXZX
141652 ZBTJZPZX
(FPL-JAE7433-IS
-B744/H-SXIRPZJWY/S
-ZBTJ1755
-K0926S0920 CG A326 VYK W80 HUR B339 GM A575 MANSA/K0919S0980 A575
INTIK/K0917S0960 A575 UDA DCT BULAG A200 HATGA/K0900S1060 A308
LARNA DCT RATKO A307 KUMOD R497 TODES B228 ZJ R22 KTL R30 SPB
B141 RANVA/N0485F360 UP863 DEREX UP739 KOLJA UN746 GORPI UZ80
TILAV UL87 TADUV T173 GED GED2W
-EDDF0948 EDDK
-EET/ZMUB0100 UNKL0236 UNWW0332 UNNT0332 USRR0447 USHH0507
USSS0535 UUYY0602 ULKK0634 ULWW0653 ULLL0720 EETT0748 EVRR0815
ESAA0821 EPWW0848 EDUU0900
REG/B2422 SEL/JLAD OPR/JADE CARGO DAT/S RVR/200
NAV/RNAV1 RNAV5 RNP4
RMK/AGCS EQUIPPED
ACARS EQUIPPED/TCAS EQUIPPED/FOREIGN PILOT
E/1148 P/TBN R/UV S/M J/LF D/1 15 C YELLOW
A/WHITE GREEN)
NNNN
`
It("should parse the whole message correctly", func() {
parsedMessage, err := Parse(message)
Expect(err).ToNot(HaveOccurred())
Expect(parsedMessage).ToNot(BeNil())
})
})
})
})
+2 -2
View File
@@ -24,12 +24,12 @@ var _ = Describe("Pattern Parser", func() {
Describe("ParseBody", func() {
It("should parse the message body and extract data based on patterns", func() {
message := "(ARR-AB123-SSR1234-KJFK-KLAX1234)"
message := "(ARR-AB123/A1234-KJFK-KLAX1234)"
parsedData := ParseBody(message)
Expect(parsedData).NotTo(BeNil())
Expect(parsedData["category"]).To(Equal("ARR"))
Expect(parsedData["number"]).To(Equal("AB123"))
Expect(parsedData["ssr"]).To(Equal("SSR1234"))
Expect(parsedData["ssr"]).To(Equal("A1234"))
Expect(parsedData["departure"]).To(Equal("KJFK"))
Expect(parsedData["arrival"]).To(Equal("KLAX"))
})