Skip to content

Commit 3e3a8a9

Browse files
committed
docs: update Go server integration report — issues Botts-Innovative-Research#7-Botts-Innovative-Research#10 filed, BuoyCAM URL fix, documents discovery
- Updated executive summary: 6→10 GitHub issues filed - Section 3.3: Added GitHub cross-references for Botts-Innovative-Research#7 (uid filter), Botts-Innovative-Research#8 (subdeployments), Botts-Innovative-Research#9 (default limit) - Section 3.3: Added new entry for Botts-Innovative-Research#10 (SensorML documents array silently dropped) - Section 3.4: Added documents row to behavioral comparison table - Section 4.6: Added BUOYCAM_CACHE_BASE_URL fix details - Section 7: Updated BuoyCAM fleet row, added §7.2 BuoyCAM Image Cache - Section 8: Added issues Botts-Innovative-Research#7-Botts-Innovative-Research#10, ogc-client-CSAPI_2 #167 - Section 10: Added §10.6 lesson on systemd env vars - Section 11: Marked issue filing as done, added documents fix and env var audit - Appendix A.1: Added BuoyCAM service env var reference
1 parent faa328b commit 3e3a8a9

1 file changed

Lines changed: 82 additions & 9 deletions

File tree

docs/research/CSAPI_Go_Server_Integration_Report_2026-04-17.md

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
OS4CSAPI has deployed a second Connected Systems API server — [connected-systems-go](https://github.com/OS4CSAPI/connected-systems-go) — alongside the existing OSH SensorHub. This report documents the integration effort: server architecture, behavioral differences discovered during live testing, workarounds applied, publishers migrated to date, and the plan to complete the remaining fleet.
1212

13-
**Final state:** 10 of 10 publishers dual-publishing on the Go server. 37 systems, 58 datastreams, 11 procedures, 58 deployments bootstrapped. All services running as systemd units with observations flowing. 6 GitHub issues filed against the Go server, plus 4 additional behavioral differences discovered during fleet-wide migration.
13+
**Final state:** 10 of 10 publishers dual-publishing on the Go server. 37 systems, 58 datastreams, 11 procedures, 58 deployments bootstrapped. All services running as systemd units with observations flowing. 10 GitHub issues filed against the Go server covering bugs, behavioral differences, and missing features. BuoyCAM image URL fix deployed (absolute URLs via `BUOYCAM_CACHE_BASE_URL` env var).
1414

1515
---
1616

@@ -57,7 +57,7 @@ The [ogc-csapi-explorer](https://github.com/OS4CSAPI/ogc-csapi-explorer) demo ap
5757

5858
## 3 Behavioral Differences Discovered
5959

60-
During live integration testing, we identified 6 differences between connected-systems-go and OSH SensorHub. These have been filed as GitHub issues on [OS4CSAPI/connected-systems-go](https://github.com/OS4CSAPI/connected-systems-go/issues).
60+
During live integration testing, we identified 10+ differences between connected-systems-go and OSH SensorHub. These have been filed as GitHub issues on [OS4CSAPI/connected-systems-go](https://github.com/OS4CSAPI/connected-systems-go/issues).
6161

6262
### 3.1 Bugs (P1–P2)
6363

@@ -131,24 +131,35 @@ During live integration testing, we identified 6 differences between connected-s
131131

132132
### 3.3 Additional Behavioral Differences (Discovered During Fleet Migration)
133133

134-
These were discovered during the full fleet migration and are not yet filed as issues.
134+
These were discovered during the full fleet migration. Key items have since been filed as GitHub issues.
135135

136136
#### Unique constraint on datastream `unique_identifier` (global scope)
137137

138138
- **Severity:** P2-Major
139139
- **Problem:** PostgreSQL `idx_datastreams_unique_identifier` enforces global uniqueness across ALL datastreams, not just within a system. Multi-station publishers initially shared one UID template (e.g., `urn:os4csapi:datastream:nws:nwsSurfaceObs:v1`) for all stations — the second station's datastream creation failed.
140140
- **Workaround:** All multi-station publishers now generate per-station UIDs: `urn:os4csapi:datastream:nws:{station_id}:nwsSurfaceObs:v1`.
141141
- **Files changed:** `bootstrap_nws.py`, `bootstrap_ndbc.py`, `bootstrap_coops.py`, `bootstrap_aviation_wx.py`, `bootstrap_usgs_water.py`, `bootstrap_usgs_nims.py`.
142+
- **Note:** Related to Issue #1 (UID handling). Not filed as a separate issue.
142143

143144
#### `?uid=` query parameter ignored
144145

146+
- **GitHub:** [OS4CSAPI/connected-systems-go#7](https://github.com/OS4CSAPI/connected-systems-go/issues/7)
145147
- **Severity:** P2-Major
146148
- **Problem:** `GET /systems?uid=urn:os4csapi:...` returns ALL systems (unfiltered) instead of the matching one. Combined with the default pagination limit of 10, `find_by_uid()` missed resources beyond the first page.
147149
- **Workaround:** `find_by_uid()` now appends `&limit=1000` to all queries and matches client-side.
148150
- **File changed:** `bootstrap_helpers.py`.
149151

152+
#### Default pagination limit too low
153+
154+
- **GitHub:** [OS4CSAPI/connected-systems-go#9](https://github.com/OS4CSAPI/connected-systems-go/issues/9)
155+
- **Severity:** P2-Major
156+
- **Problem:** Go server defaults to `limit=10` for all collection endpoints. With 37 systems, 58 datastreams, and 58 deployments, default queries miss the majority of resources. SensorHub defaults to 100.
157+
- **Workaround:** All client code appends explicit `&limit=100` or `&limit=1000` to queries.
158+
- **Impact:** Affects Explorer UI (map shows only 10 of 37 systems), bootstrap scripts, and library consumers.
159+
150160
#### `/deployments` only returns top-level deployments
151161

162+
- **GitHub:** [OS4CSAPI/connected-systems-go#8](https://github.com/OS4CSAPI/connected-systems-go/issues/8)
152163
- **Severity:** P3-Minor
153164
- **Problem:** `GET /deployments` does not include sub-deployments in results. Sub-deployments are only accessible via `GET /deployments/{parent_id}/subdeployments`.
154165
- **Workaround:** `ensure_deployment()` now searches `deployments/{parent_id}/subdeployments` when `parent_id` is provided.
@@ -160,6 +171,16 @@ These were discovered during the full fleet migration and are not yet filed as i
160171
- **Problem:** Go server validates that observation results contain ALL fields defined in the datastream schema, including `timestamp`. Publishers were popping `timestamp` from results (SensorHub auto-fills it from `phenomenonTime`), causing `result.timestamp is required by datastream schema` errors.
161172
- **Workaround:** All publishers now re-add `timestamp` from `phenomenonTime` when targeting Go server.
162173
- **Files changed:** All 8 publisher files.
174+
- **Note:** Extension of Issue #5. Not filed as a separate issue.
175+
176+
#### SensorML `documents` array silently dropped
177+
178+
- **GitHub:** [OS4CSAPI/connected-systems-go#10](https://github.com/OS4CSAPI/connected-systems-go/issues/10)
179+
- **Severity:** P2-Major
180+
- **Problem:** The Go server silently drops the `documents` array from SensorML on ingest or output. Querying `GET /systems?resultFormat=sml` returns `identifiers`, `classifiers`, `contacts`, `position` — but NO `documents`. Publishers send `documents` with photo URLs, thumbnails, and documentation links, but they are lost.
181+
- **Impact:** System thumbnails broken in the Explorer (`extractSmlMedia()` reads `sml.documents`). Any media links, datasheets, or documentation URLs attached to systems are inaccessible.
182+
- **Workaround:** None available (requires Go server code fix). Explorer shows blank thumbnails for all Go server systems.
183+
- **Verification:** `GET /systems?resultFormat=sml` on Go server — response has no `documents` field. Same query on SensorHub returns full `documents` array with photo URLs.
163184

164185
### 3.4 Full Behavioral Comparison
165186

@@ -171,10 +192,11 @@ These were discovered during the full fleet migration and are not yet filed as i
171192
| Auth requirement | Required (HTTP Basic) | None (headers tolerated) |
172193
| Datastream UID on create | Optional (auto-generated) | Effectively required (see #1) |
173194
| Datastream UID scope | Per-system | Global unique constraint |
174-
| `?uid=` filter parameter | Supported | Ignored (returns all) |
175-
| Default pagination limit | 100 | 10 |
176-
| `/deployments` listing | All (flat) | Top-level only |
195+
| `?uid=` filter parameter | Supported | Ignored (returns all) #7 |
196+
| Default pagination limit | 100 | 10 #9 |
197+
| `/deployments` listing | All (flat) | Top-level only #8 |
177198
| `result.timestamp` field | Auto-filled from phenomenonTime | Required in result body |
199+
| SensorML `documents` array | Preserved on ingest/output | Silently dropped — #10 |
178200

179201
---
180202

@@ -254,6 +276,7 @@ These were discovered during the full fleet migration and are not yet filed as i
254276
| Per-station datastream UIDs | `urn:os4csapi:datastream:ndbc:{station_id}:ndbcBuoyObs:v1` and `urn:os4csapi:datastream:ndbc:{station_id}:ndbcBuoycam:v1` |
255277
| `OSH_BASE_URL` override | Both publishers read `OSH_BASE_URL` env var |
256278
| `_is_go_server` flag | NaN→0.0, timestamp re-added from phenomenonTime |
279+
| `BUOYCAM_CACHE_BASE_URL` fix | Added `Environment=BUOYCAM_CACHE_BASE_URL=https://129-80-248-53.sslip.io/buoycam` to both `ndbc-buoycam-publisher.service` and `ndbc-buoycam-publisher-go.service`. Without this, `image_cache.py` produced relative paths (e.g., `/41009/2026/04/17/...jpg`) instead of absolute URLs. State file cleared and services restarted to force re-publish all 5 stations with correct URLs. |
257280

258281
### 4.7 CO-OPS Coastal Observations Publisher
259282

@@ -411,7 +434,7 @@ All 10 publishers are dual-publishing on both SensorHub and the Go server.
411434
| 3 | ISS | `iss-publisher` | `iss-publisher-go` | 30s | CelesTrak TLE fetch may timeout (transient) |
412435
| 4 | NWS | `nws-publisher` | `nws-publisher-go` | 3600s | 10 stations |
413436
| 5 | NDBC | `ndbc-publisher` | `ndbc-publisher-go` | 3600s | 5 buoys |
414-
| 6 | NDBC BuoyCAM | `ndbc-buoycam-publisher` | `ndbc-buoycam-publisher-go` | 900s | 5 cameras, image observations |
437+
| 6 | NDBC BuoyCAM | `ndbc-buoycam-publisher` | `ndbc-buoycam-publisher-go` | 900s | 5 cameras, `BUOYCAM_CACHE_BASE_URL` fix applied |
415438
| 7 | CO-OPS | `coops-publisher` | `coops-publisher-go` | 360s | 5 tide stations |
416439
| 8 | AviationWeather | `aviation-wx-publisher` | `aviation-wx-publisher-go` | 600s | 5 METAR stations |
417440
| 9 | USGS Water | `usgs-water-publisher` | `usgs-water-publisher-go` | 900s | 8 gages (discharge + gage height) |
@@ -439,6 +462,29 @@ Each Go publisher has its own directory under `/home/ubuntu/`:
439462

440463
Each directory contains a copy of the relevant `publishers/` subtree plus `bootstrap_helpers.py`. Staging repo clone at `/tmp/OSHConnect-Python` for updates.
441464

465+
### 7.2 BuoyCAM Image Cache
466+
467+
BuoyCAM images are cached on disk at `/var/www/buoycam/` and served by Caddy:
468+
469+
```
470+
# Caddy config
471+
handle_path /buoycam/* {
472+
root * /var/www/buoycam
473+
header Access-Control-Allow-Origin *
474+
file_server browse
475+
}
476+
```
477+
478+
The `image_cache.py` module builds image URLs using:
479+
```python
480+
CACHE_BASE_URL = os.environ.get("BUOYCAM_CACHE_BASE_URL", "")
481+
# → f"{CACHE_BASE_URL}/{station_id}/{ymd}/{ts}.jpg"
482+
```
483+
484+
Without `BUOYCAM_CACHE_BASE_URL` set, the publisher produced relative paths like `/41009/2026/04/17/20260417T150121Z.jpg` — which broke in the Explorer since images need absolute URLs. Fixed by adding `Environment=BUOYCAM_CACHE_BASE_URL=https://129-80-248-53.sslip.io/buoycam` to both BuoyCAM systemd services. State files cleared and services restarted to force re-publish all 5 stations with correct absolute URLs.
485+
486+
**Verified:** `GET /datastreams/{id}/observations?limit=1&resultTime=latest` returns `imageUrl: "https://129-80-248-53.sslip.io/buoycam/41009/2026/04/17/20260417T160348Z.jpg"` — loads correctly.
487+
442488
---
443489

444490
## 8 GitHub Issues Filed
@@ -453,8 +499,14 @@ All filed on [OS4CSAPI/connected-systems-go](https://github.com/OS4CSAPI/connect
453499
| [#4](https://github.com/OS4CSAPI/connected-systems-go/issues/4) | enhancement | Research: NaN handling for numeric observation fields |
454500
| [#5](https://github.com/OS4CSAPI/connected-systems-go/issues/5) | enhancement | Research: Strict schema validation — requiring ALL declared fields |
455501
| [#6](https://github.com/OS4CSAPI/connected-systems-go/issues/6) | enhancement | Research: Cross-resource references — `@link` objects only vs. flat `@id` strings |
502+
| [#7](https://github.com/OS4CSAPI/connected-systems-go/issues/7) | bug | `?uid=` query parameter silently ignored — returns all resources unfiltered |
503+
| [#8](https://github.com/OS4CSAPI/connected-systems-go/issues/8) | bug | Subdeployments hidden from top-level `/deployments` listing |
504+
| [#9](https://github.com/OS4CSAPI/connected-systems-go/issues/9) | bug | Default pagination limit of 10 too low — most resources hidden |
505+
| [#10](https://github.com/OS4CSAPI/connected-systems-go/issues/10) | bug | SensorML `documents` array silently dropped — system thumbnails/media links lost |
456506

457-
Related library issue: [ogc-client-CSAPI_2#166](https://github.com/OS4CSAPI/ogc-client-CSAPI_2/issues/166) — Library parsers need `@link.href` fallback.
507+
Related library issues:
508+
- [ogc-client-CSAPI_2#166](https://github.com/OS4CSAPI/ogc-client-CSAPI_2/issues/166) — Library parsers need `@link.href` fallback.
509+
- [ogc-client-CSAPI_2#167](https://github.com/OS4CSAPI/ogc-client-CSAPI_2/issues/167)`buildQueryString()` should not apply a default `limit` parameter.
458510

459511
---
460512

@@ -507,16 +559,22 @@ The Go server's `/deployments` endpoint only returns top-level deployments. Boot
507559

508560
The current file-copy deployment (staging repo → per-publisher directories) is error-prone. Multiple bootstrap failures were caused by stale code in publisher directories. A git-pull-based or symlink-based approach would be more reliable.
509561

562+
### 10.6 Environment Variables Must Be Explicitly Set in Systemd
563+
564+
The BuoyCAM image URL issue was caused by a missing `BUOYCAM_CACHE_BASE_URL` environment variable in both publisher systemd services. The `image_cache.py` module defaults to `""` for the base URL, producing relative paths that work in development but break when the images are served from a different origin. All publisher-specific env vars must be audited when deploying new services.
565+
510566
---
511567

512568
## 11 Future Work
513569

514-
- **File GitHub issues** for the 4 newly discovered Go server behaviors (§3.3)
570+
- ~~**File GitHub issues** for the 4 newly discovered Go server behaviors (§3.3)~~ — Done: #7, #8, #9 filed; #10 filed for new `documents` issue
571+
- **Go server SensorML `documents` support** — Issue #10 tracks this. System thumbnails and media links will remain broken until the Go server preserves the `documents` array on ingest/output. No client-side workaround available.
515572
- **Explorer smoke test** against Go server to verify map visualization
516573
- **Consolidate VM deployment** — replace per-directory file copies with symlinks or a deploy script
517574
- **UAS Simulator + Localizer** — evaluate Go server integration path
518575
- **Monitoring** — add health-check dashboard for Go publisher services
519576
- **CelesTrak resilience** — add retry/fallback for ISS TLE fetch timeouts
577+
- **Audit publisher env vars** — ensure all required environment variables (e.g., `BUOYCAM_CACHE_BASE_URL`) are set in every systemd service file
520578

521579
---
522580

@@ -552,3 +610,18 @@ usgs-nims-publisher-go.service
552610
# Other
553611
simulator.service
554612
```
613+
614+
### Appendix A.1 — BuoyCAM Service Environment Variables
615+
616+
Both BuoyCAM publisher services now include the image cache base URL:
617+
618+
```ini
619+
# /etc/systemd/system/ndbc-buoycam-publisher-go.service (excerpt)
620+
[Service]
621+
Environment="OSH_BASE_URL=https://129-80-248-53.sslip.io/csapi-go"
622+
Environment="BUOYCAM_CACHE_BASE_URL=https://129-80-248-53.sslip.io/buoycam"
623+
624+
# /etc/systemd/system/ndbc-buoycam-publisher.service (excerpt)
625+
[Service]
626+
Environment="BUOYCAM_CACHE_BASE_URL=https://129-80-248-53.sslip.io/buoycam"
627+
```

0 commit comments

Comments
 (0)