Skip to content

Commit e5ddf24

Browse files
committed
Refactor journey_pattern_ref-matching logic in import feature to improve
error messages. Use separate error messages in cases where (1) the journey pattern reference cannot be found by matching the stop point labels or (2) the journey pattern reference cannot be found by matching the timing place codes.
1 parent 6a2ccfa commit e5ddf24

6 files changed

Lines changed: 90 additions & 15 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package fi.hsl.jore4.hastus.service.importing
2+
3+
import fi.hsl.jore4.hastus.data.format.RouteLabelAndDirection
4+
import fi.hsl.jore4.hastus.service.exporting.ConversionsToHastus
5+
import org.springframework.http.HttpStatus
6+
import org.springframework.web.server.ResponseStatusException
7+
8+
class CannotFindJourneyPatternRefByStopPointLabelsException(
9+
message: String
10+
) : ResponseStatusException(
11+
HttpStatus.BAD_REQUEST,
12+
message
13+
) {
14+
15+
constructor(
16+
routeIdentifier: RouteLabelAndDirection,
17+
stopLabels: List<String>
18+
) : this(
19+
"""
20+
Could not find matching journey pattern reference whose stop points correspond to the Hastus trip.
21+
22+
Trip label: ${routeIdentifier.routeLabel},
23+
Trip direction: ${
24+
// This is safe to call here. Possible exceptions in conversions have already taken place.
25+
ConversionsToHastus.convertRouteDirection(routeIdentifier.direction)
26+
},
27+
Stop points: $stopLabels
28+
""".trimIndent()
29+
)
30+
}

src/main/kotlin/fi/hsl/jore4/hastus/service/importing/CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException.kt renamed to src/main/kotlin/fi/hsl/jore4/hastus/service/importing/CannotFindJourneyPatternRefByTimingPlaceLabelsException.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import fi.hsl.jore4.hastus.service.exporting.ConversionsToHastus
55
import org.springframework.http.HttpStatus
66
import org.springframework.web.server.ResponseStatusException
77

8-
class CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException(
8+
class CannotFindJourneyPatternRefByTimingPlaceLabelsException(
99
message: String
1010
) : ResponseStatusException(
1111
HttpStatus.BAD_REQUEST,
@@ -18,7 +18,7 @@ class CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException(
1818
placeCodes: List<String?>
1919
) : this(
2020
"""
21-
No journey pattern reference was found whose stop points correspond to the Hastus trip.
21+
Could not find matching journey pattern reference whose timing place labels correspond to the Hastus trip.
2222
2323
Trip label: ${routeIdentifier.routeLabel},
2424
Trip direction: ${

src/main/kotlin/fi/hsl/jore4/hastus/service/importing/ConversionsFromHastus.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ object ConversionsFromHastus {
201201
unknownStopLabels.joinToString(prefix = "'", separator = ",", postfix = "'")
202202
}"
203203
LOGGER.error(errorMessage)
204-
throw CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException(errorMessage)
204+
throw CannotFindJourneyPatternRefByStopPointLabelsException(errorMessage)
205205
}
206206
}
207207

src/main/kotlin/fi/hsl/jore4/hastus/service/importing/ImportService.kt

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,39 @@ class ImportService(private val graphQLServiceFactory: GraphQLServiceFactory) {
113113
val hastusStopLabels: List<String> = hastusStopAndTimingPlaces.map { it.first }
114114
val hastusTimingPlaceLabels: List<String?> = hastusStopAndTimingPlaces.map { it.second }
115115

116-
val firstMatchingJourneyPatternRef: JoreJourneyPatternRef =
116+
val journeyPatternRefsMatchedByStopLabels: List<JoreJourneyPatternRef> =
117117
journeyPatternRefsGroupedByRouteLabelAndDirection[hastusRouteLabelAndDirection]
118-
.orEmpty() // not really empty because of previously done label-direction matching
118+
.orEmpty() // won't really be empty because of previously done label-direction matching
119+
.filter { journeyPatternRef ->
120+
val joreStopLabels: List<String> = journeyPatternRef.stops.map { it.stopLabel }
121+
122+
joreStopLabels == hastusStopLabels
123+
}
124+
125+
if (journeyPatternRefsMatchedByStopLabels.isEmpty()) {
126+
val exception = CannotFindJourneyPatternRefByStopPointLabelsException(
127+
hastusRouteLabelAndDirection,
128+
hastusStopLabels
129+
)
130+
LOGGER.warn(exception.message)
131+
throw exception
132+
}
133+
134+
val bestJourneyPatternRefMatch: JoreJourneyPatternRef =
135+
journeyPatternRefsMatchedByStopLabels
119136
.sortedByDescending {
120137
// TODO Make sure that this is the appropriate ordering criteria when
121138
// finding JourneyPatternRef match.
122139
it.snapshotTime
123140
}
124141
.firstOrNull { journeyPatternRef ->
125-
val joreStopLabels: List<String> = journeyPatternRef.stops.map { it.stopLabel }
126142
val joreTimingPlaceLabels: List<String?> =
127143
journeyPatternRef.stops.map { it.timingPlaceCode }
128144

129-
joreStopLabels == hastusStopLabels && joreTimingPlaceLabels == hastusTimingPlaceLabels
145+
joreTimingPlaceLabels == hastusTimingPlaceLabels
130146
}
131147
?: run {
132-
val exception = CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException(
148+
val exception = CannotFindJourneyPatternRefByTimingPlaceLabelsException(
133149
hastusRouteLabelAndDirection,
134150
hastusStopLabels,
135151
hastusTimingPlaceLabels
@@ -138,7 +154,7 @@ class ImportService(private val graphQLServiceFactory: GraphQLServiceFactory) {
138154
throw exception
139155
}
140156

141-
results[hastusRouteLabelAndDirection] = firstMatchingJourneyPatternRef
157+
results[hastusRouteLabelAndDirection] = bestJourneyPatternRefMatch
142158
}
143159

144160
return results

src/test/kotlin/fi/hsl/jore4/hastus/api/ImportControllerTest.kt

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import fi.hsl.jore4.hastus.data.format.JoreRouteDirection
66
import fi.hsl.jore4.hastus.data.format.RouteLabelAndDirection
77
import fi.hsl.jore4.hastus.graphql.converter.GraphQLAuthenticationFailedException
88
import fi.hsl.jore4.hastus.service.importing.CannotFindJourneyPatternRefByRouteLabelAndDirectionException
9-
import fi.hsl.jore4.hastus.service.importing.CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException
9+
import fi.hsl.jore4.hastus.service.importing.CannotFindJourneyPatternRefByStopPointLabelsException
10+
import fi.hsl.jore4.hastus.service.importing.CannotFindJourneyPatternRefByTimingPlaceLabelsException
1011
import fi.hsl.jore4.hastus.service.importing.ImportService
1112
import fi.hsl.jore4.hastus.service.importing.InvalidHastusDataException
1213
import io.mockk.every
@@ -103,7 +104,7 @@ class ImportControllerTest @Autowired constructor(
103104
}
104105

105106
@Test
106-
fun `returns 400 when there are unmatched routes in Hastus data`() {
107+
fun `returns 400 when not able to find journey pattern reference whose route label and direction match Hastus trip`() {
107108
every {
108109
importService.importTimetablesFromCsv(any(), any())
109110
} throws CannotFindJourneyPatternRefByRouteLabelAndDirectionException(
@@ -128,10 +129,38 @@ class ImportControllerTest @Autowired constructor(
128129
}
129130

130131
@Test
131-
fun `returns 400 when no journey pattern reference matches any trip record in Hastus data`() {
132+
fun `returns 400 when not able to find journey pattern reference whose stop point labels match Hastus trip`() {
132133
every {
133134
importService.importTimetablesFromCsv(any(), any())
134-
} throws CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException(
135+
} throws CannotFindJourneyPatternRefByStopPointLabelsException(
136+
RouteLabelAndDirection("123", JoreRouteDirection.OUTBOUND),
137+
listOf("H1000", "H1001", "H1002")
138+
)
139+
140+
executeImportTimetablesRequest("<csv_content>")
141+
.andExpect(status().isBadRequest)
142+
.andExpect(
143+
constructExpectedErrorBody(
144+
"""
145+
Could not find matching journey pattern reference whose stop points correspond to the Hastus trip.
146+
147+
Trip label: 123,
148+
Trip direction: 1,
149+
Stop points: [H1000, H1001, H1002]
150+
""".trimIndent()
151+
)
152+
)
153+
154+
verify(exactly = 1) {
155+
importService.importTimetablesFromCsv(any(), any())
156+
}
157+
}
158+
159+
@Test
160+
fun `returns 400 when not able to find journey pattern reference whose timing place labels match Hastus trip`() {
161+
every {
162+
importService.importTimetablesFromCsv(any(), any())
163+
} throws CannotFindJourneyPatternRefByTimingPlaceLabelsException(
135164
RouteLabelAndDirection("123", JoreRouteDirection.OUTBOUND),
136165
listOf("H1000", "H1001", "H1002"),
137166
listOf("1PLACE", null, "2PLACE")
@@ -142,7 +171,7 @@ class ImportControllerTest @Autowired constructor(
142171
.andExpect(
143172
constructExpectedErrorBody(
144173
"""
145-
No journey pattern reference was found whose stop points correspond to the Hastus trip.
174+
Could not find matching journey pattern reference whose timing place labels correspond to the Hastus trip.
146175
147176
Trip label: 123,
148177
Trip direction: 1,

src/test/kotlin/fi/hsl/jore4/hastus/service/importing/ConversionsFromHastusTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ class ConversionsFromHastusTest {
260260
generateTripStopRecord("trip1", "stop3", "0530", "T", "")
261261
)
262262

263-
val exception = assertFailsWith<CannotFindJourneyPatternRefByStopLabelsAndTimingPointLabelsException> {
263+
val exception = assertFailsWith<CannotFindJourneyPatternRefByStopPointLabelsException> {
264264
ConversionsFromHastus.convertHastusDataToJore(
265265
hastusData,
266266
vehicleTypeIndex,

0 commit comments

Comments
 (0)