Skip to content

Commit 3da9d4a

Browse files
Merge pull request #122 from OneBusAway/multiple-agencies
Adds support for multiple agencies to docker image
2 parents b4f7600 + d32d070 commit 3da9d4a

File tree

6 files changed

+120
-11
lines changed

6 files changed

+120
-11
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ You can find the latest published Docker images on Docker Hub:
101101
* `TRIP_UPDATES_URL` - Trip Updates URL for GTFS-RT.
102102
* `VEHICLE_POSITIONS_URL` - Vehicle Positions URL for GTFS-RT.
103103
* `REFRESH_INTERVAL` - Refresh interval in seconds. Usually 10-30.
104-
* `AGENCY_ID` - Your GTFS-RT agency ID. Ostensibly the same as your GTFS agency ID.
104+
* Specify one or the other:
105+
* `AGENCY_ID_LIST` - Your GTFS-RT agency IDs. These should match the IDs in your agency.txt file. Format: abxoxo
106+
* `AGENCY_ID` - Optional: Your GTFS-RT agency ID. Ostensibly the same as your GTFS agency ID.
105107
* Authentication (Optional)
106108
* Example: Specifying `FEED_API_KEY` = `X-API-KEY` and `FEED_API_VALUE` = `12345` will result in `X-API-KEY: 12345` being passed on every call to your GTFS-RT URLs.
107109
* `FEED_API_KEY` - If your GTFS-RT API requires you to pass an authentication header, you can represent the key portion of it by specifying this value.

bin/validate.sh

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/bin/bash
22

3-
output=$(curl -s "http://localhost:8080/api/where/current-time.json?key=test" | jq '.data.entry.time')
3+
# Timeout for curl requests in seconds
4+
CURL_TIMEOUT=120
5+
6+
output=$(curl -s --max-time $CURL_TIMEOUT "http://localhost:8080/api/where/current-time.json?key=test" | jq '.data.entry.time')
47

58
if [[ ! -z "$output" && "$output" =~ ^[0-9]+$ ]]; then
69
echo "current-time.json endpoint works."
@@ -10,7 +13,20 @@ else
1013
fi
1114

1215
# Get the first agency from agencies-with-coverage
13-
agency_response=$(curl -s "http://localhost:8080/api/where/agencies-with-coverage.json?key=test")
16+
agency_response=$(curl -s --max-time $CURL_TIMEOUT "http://localhost:8080/api/where/agencies-with-coverage.json?key=test")
17+
18+
# Debug: Show raw response if empty or small
19+
if [[ -z "$agency_response" || ${#agency_response} -lt 100 ]]; then
20+
echo "Debug: Raw agency response: '$agency_response'"
21+
fi
22+
23+
# Check if response is valid JSON
24+
if ! echo "$agency_response" | jq empty 2>/dev/null; then
25+
echo "Error: Invalid JSON response from agencies-with-coverage endpoint"
26+
echo "Response: $agency_response"
27+
exit 1
28+
fi
29+
1430
agency_count=$(echo "$agency_response" | jq '.data.list | length')
1531

1632
if [[ "$agency_count" -gt 0 ]]; then
@@ -23,7 +39,7 @@ else
2339
fi
2440

2541
# Get routes for the agency
26-
routes_response=$(curl -s "http://localhost:8080/api/where/routes-for-agency/${AGENCY_ID}.json?key=test")
42+
routes_response=$(curl -s --max-time $CURL_TIMEOUT "http://localhost:8080/api/where/routes-for-agency/${AGENCY_ID}.json?key=test")
2743
route_count=$(echo "$routes_response" | jq '.data.list | length')
2844
if [[ "$route_count" -gt 0 ]]; then
2945
echo "routes-for-agency/${AGENCY_ID}.json endpoint works (found $route_count routes)."
@@ -35,7 +51,7 @@ else
3551
fi
3652

3753
# Get stops for the route
38-
stops_response=$(curl -s "http://localhost:8080/api/where/stops-for-route/${ROUTE_ID}.json?key=test")
54+
stops_response=$(curl -s --max-time $CURL_TIMEOUT "http://localhost:8080/api/where/stops-for-route/${ROUTE_ID}.json?key=test")
3955
route_id_check=$(echo "$stops_response" | jq -r '.data.entry.routeId')
4056
if [[ ! -z "$route_id_check" && "$route_id_check" == "$ROUTE_ID" ]]; then
4157
echo "stops-for-route/${ROUTE_ID}.json endpoint works."
@@ -47,7 +63,7 @@ else
4763
fi
4864

4965
# Get stop details
50-
stop_response=$(curl -s "http://localhost:8080/api/where/stop/${STOP_ID}.json?key=test")
66+
stop_response=$(curl -s --max-time $CURL_TIMEOUT "http://localhost:8080/api/where/stop/${STOP_ID}.json?key=test")
5167
stop_id_check=$(echo "$stop_response" | jq -r '.data.entry.id')
5268
if [[ ! -z "$stop_id_check" && "$stop_id_check" == "$STOP_ID" ]]; then
5369
echo "stop/${STOP_ID}.json endpoint works."
@@ -62,7 +78,7 @@ fi
6278

6379
# Test stops-for-location using coordinates from the stop
6480
LOCATION_URL="http://localhost:8080/api/where/stops-for-location.json?lat=${STOP_LAT}&lon=${STOP_LON}&key=test"
65-
location_response=$(curl -s "$LOCATION_URL")
81+
location_response=$(curl -s --max-time $CURL_TIMEOUT "$LOCATION_URL")
6682
out_of_range=$(echo "$location_response" | jq '.data.outOfRange')
6783
stops_found=$(echo "$location_response" | jq '.data.list | length')
6884
if [[ ! -z "$out_of_range" && "$out_of_range" == "false" && "$stops_found" -gt 0 ]]; then
@@ -75,7 +91,7 @@ else
7591
fi
7692

7793
# Test arrivals-and-departures-for-stop endpoint
78-
arrivals_response=$(curl -s "http://localhost:8080/api/where/arrivals-and-departures-for-stop/${STOP_ID}.json?key=test")
94+
arrivals_response=$(curl -s --max-time $CURL_TIMEOUT "http://localhost:8080/api/where/arrivals-and-departures-for-stop/${STOP_ID}.json?key=test")
7995
arrivals_stop_id=$(echo "$arrivals_response" | jq -r '.data.entry.stopId')
8096
arrivals_count=$(echo "$arrivals_response" | jq '.data.entry.arrivalsAndDepartures | length // 0')
8197

docker-compose.standalone.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ services:
4343
- JDBC_PASSWORD=oba_password
4444
- TEST_API_KEY=test # For test only, remove in production
4545
- TZ=America/Los_Angeles
46+
- AGENCY_ID=unitrans
4647
- GTFS_URL=https://unitrans.ucdavis.edu/media/gtfs/Unitrans_GTFS.zip
47-
- GTFS_TIDY_ARGS=v
48+
- GTFS_TIDY_ARGS=OeD
4849

4950
ports:
5051
# Access the webapp on your host machine at a path like

oba/bootstrap.sh

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,33 @@ else
4646
HAS_API_KEY=""
4747
fi
4848

49+
# Handle AGENCY_ID_LIST properly - if it's a JSON array, use it directly, otherwise treat as empty
50+
if [ -n "$AGENCY_ID_LIST" ]; then
51+
# Remove the outer quotes if they exist and use the array directly
52+
AGENCY_ID_LIST_JSON="$AGENCY_ID_LIST"
53+
else
54+
AGENCY_ID_LIST_JSON="[]"
55+
fi
56+
57+
# Build the JSON string with proper handling of AGENCY_ID_LIST
58+
JSON_CONFIG=$(cat <<EOF
59+
{
60+
"GTFS_RT_AVAILABLE": "$GTFS_RT_AVAILABLE",
61+
"TRIP_UPDATES_URL": "$TRIP_UPDATES_URL",
62+
"VEHICLE_POSITIONS_URL": "$VEHICLE_POSITIONS_URL",
63+
"ALERTS_URL": "$ALERTS_URL",
64+
"REFRESH_INTERVAL": "$REFRESH_INTERVAL",
65+
"AGENCY_ID": "$AGENCY_ID",
66+
"AGENCY_ID_LIST": $AGENCY_ID_LIST_JSON,
67+
"HAS_API_KEY": "$HAS_API_KEY",
68+
"FEED_API_KEY": "$FEED_API_KEY",
69+
"FEED_API_VALUE": "$FEED_API_VALUE"
70+
}
71+
EOF
72+
)
73+
4974
hbs_renderer -input "$FEDERATION_XML_SOURCE" \
50-
-json '{"GTFS_RT_AVAILABLE": "'$GTFS_RT_AVAILABLE'", "TRIP_UPDATES_URL": "'$TRIP_UPDATES_URL'", "VEHICLE_POSITIONS_URL": "'$VEHICLE_POSITIONS_URL'", "ALERTS_URL": "'$ALERTS_URL'", "REFRESH_INTERVAL": "'$REFRESH_INTERVAL'", "AGENCY_ID": "'$AGENCY_ID'", "HAS_API_KEY": "'$HAS_API_KEY'", "FEED_API_KEY": "'$FEED_API_KEY'", "FEED_API_VALUE": "'$FEED_API_VALUE'"}' \
75+
-json "$JSON_CONFIG" \
5176
-output "$FEDERATION_XML_DESTINATION"
5277

5378
#####

oba/config/onebusaway-transit-data-federation-webapp-data-sources.xml.hbs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,17 @@
6464
<property name="refreshInterval" value="{{ REFRESH_INTERVAL }}" />
6565
{{/if}}
6666

67-
<property name="agencyId" value="{{ AGENCY_ID }}" />
67+
{{#if AGENCY_ID_LIST.length}}
68+
<property name="agencyIds">
69+
<list>
70+
{{#each AGENCY_ID_LIST}}
71+
<value>{{ this }}</value>
72+
{{/each}}
73+
</list>
74+
</property>
75+
{{else if AGENCY_ID}}
76+
<property name="agencyId" value="{{ AGENCY_ID }}" />
77+
{{/if}}
6878

6979
{{#if HAS_API_KEY}}
7080
<property name="headersMap">

oba/config/template_renderer/main_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,61 @@ func TestRenderTemplate(t *testing.T) {
6161
}
6262
}
6363

64+
func TestRenderTemplateWithArray(t *testing.T) {
65+
// Create a temporary template file
66+
tempFile, err := os.CreateTemp("", "test-template-*.hbs")
67+
if err != nil {
68+
t.Fatalf("Failed to create temp file: %v", err)
69+
}
70+
defer os.Remove(tempFile.Name()) // clean up
71+
72+
// Write test template content
73+
templateContent := "Hello, {{name}}! Your favorite colors are {{#each colors}}{{this}} {{else}}unknown{{/each}}."
74+
if _, err := tempFile.Write([]byte(templateContent)); err != nil {
75+
t.Fatalf("Failed to write to temp file: %v", err)
76+
}
77+
if err := tempFile.Close(); err != nil {
78+
t.Fatalf("Failed to close temp file: %v", err)
79+
}
80+
81+
// Set up test cases
82+
testCases := []struct {
83+
name string
84+
jsonData string
85+
expected string
86+
}{
87+
{
88+
name: "Basic rendering",
89+
jsonData: `{"name": "Alice", "colors": ["blue", "green"]}`,
90+
expected: "Hello, Alice! Your favorite colors are blue green .",
91+
},
92+
{
93+
name: "only one item rendering",
94+
jsonData: `{"name": "Alice", "colors": ["green"]}`,
95+
expected: "Hello, Alice! Your favorite colors are green .",
96+
},
97+
{
98+
name: "only one item rendering",
99+
jsonData: `{"name": "Alice", "colors": []}`,
100+
expected: "Hello, Alice! Your favorite colors are unknown.",
101+
},
102+
}
103+
104+
// Run test cases
105+
for _, tc := range testCases {
106+
t.Run(tc.name, func(t *testing.T) {
107+
result, err := renderTemplate(tempFile.Name(), tc.jsonData)
108+
if err != nil {
109+
t.Fatalf("renderTemplate returned an error: %v", err)
110+
}
111+
112+
if !strings.Contains(result, tc.expected) {
113+
t.Errorf("Expected output to contain %q, but got %q", tc.expected, result)
114+
}
115+
})
116+
}
117+
}
118+
64119
func TestRenderTemplateErrors(t *testing.T) {
65120
// Test with non-existent file
66121
_, err := renderTemplate("non-existent-file.hbs", "{}")

0 commit comments

Comments
 (0)