-
Notifications
You must be signed in to change notification settings - Fork 0
Deployment associations silently dropped despite advertising conf/deployment: deployedSystems@link, deployment@link, and deployment-scoped endpoints #1
Description
Summary
OSH advertises the CSAPI Part 1 deployment and subdeployment conformance classes and Part 2 datastream class, but three deployment-association mechanisms specified by those classes are non-functional:
| # | Mechanism | Spec Reference | Behavior |
|---|---|---|---|
| 1 | deployedSystems@link on Deployment |
OGC 23-001 §8.5 Table 10 (required) | POST/PUT accepted → field silently dropped on GET |
| 2 | deployment@link on DataStream |
OGC 23-002 §7.3.2 (optional, but should persist if submitted) | PUT returns 204 → field silently dropped on GET |
| 3 | /deployments/{id}/datastreams endpoint |
OGC 23-002 Annex A.2 Req 8–9 | HTTP 400 "Invalid resource name: 'datastreams'" |
The core issue is that fields are accepted without error but silently discarded. The server returns success codes (201/204) while not persisting the data, which makes the failure invisible to clients until they read it back.
What does work
For context, these related mechanisms do work correctly:
| Mechanism | Status |
|---|---|
platform@link on Deployment |
✅ Persists and returns correctly |
Subdeployment hierarchy (/deployments/{id}/subdeployments) |
✅ Works |
| Deployment CRUD (create, read, update, delete) | ✅ Works |
deployedSystemUIDs as custom string property |
✅ Persists (but this is a workaround, not the spec-defined link format) |
Environment
- Server: OSH (OpenSensorHub) CSAPI instance on Oracle Cloud
- API root:
https://os4csapi-osh.duckdns.org/sensorhub/api - Date tested: 2026-03-02
- Encodings tested: GeoJSON (
application/geo+json) and SensorML-JSON (application/sml+json) - Client tooling: Python
urllib(raw HTTP, no SDK)
Advertised Conformance Classes
GET /conformance returns (deployment/datastream relevant subset):
http://www.opengis.net/spec/ogcapi-connectedsystems-1/1.0/conf/deployment
http://www.opengis.net/spec/ogcapi-connectedsystems-1/1.0/conf/subdeployment
http://www.opengis.net/spec/ogcapi-connectedsystems-1/1.0/conf/create-replace-delete
http://www.opengis.net/spec/ogcapi-connectedsystems-2/1.0/conf/datastream
http://www.opengis.net/spec/ogcapi-connectedsystems-2/1.0/conf/create-replace-delete
The server claims conf/deployment — the class that requires deployedSystems association support per OGC 23-001 §8.5 Table 10.
Reproduction: Issue 1 — deployedSystems@link silently dropped
Request
POST /sensorhub/api/deployments HTTP/1.1
Content-Type: application/geo+json
Authorization: Basic ****
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [-110.25, 31.64] },
"properties": {
"featureType": "sosa:Deployment",
"uid": "urn:test:probe:deployed-systems-conformance:001",
"name": "PROBE: deployedSystems conformance test",
"validTime": ["2026-03-01T00:00:00Z", ".."],
"deployedSystems@link": [
{
"href": "/sensorhub/api/systems/040g",
"uid": "urn:os4csapi:system:set:ft-huachuca:001",
"type": "application/geo+json"
},
{
"href": "/sensorhub/api/systems/0410",
"uid": "urn:os4csapi:system:monitoring-site-node:ft-huachuca:001",
"type": "application/geo+json"
},
{
"href": "/sensorhub/api/systems/041g",
"uid": "urn:os4csapi:system:relay:vhf-repeater:ft-huachuca:001",
"type": "application/geo+json"
}
]
}
}Response to POST
HTTP 201 Created
Location: .../deployments/043g
Read-back
GET /sensorhub/api/deployments/043g HTTP/1.1
Accept: application/geo+json{
"type": "Feature",
"id": "043g",
"geometry": { "type": "Point", "coordinates": [-110.25, 31.64] },
"properties": {
"uid": "urn:test:probe:deployed-systems-conformance:001",
"featureType": "sosa:Deployment",
"name": "PROBE: deployedSystems conformance test",
"validTime": ["2026-03-01T00:00:00Z", ".."]
},
"links": [...]
}deployedSystems@link is completely absent from the response. The 3-system array was silently discarded.
Also tested
GET /sensorhub/api/deployments/043g/deployedSystems → 400 "Invalid resource name: 'deployedSystems'"
GET /sensorhub/api/deployments/043g/systems → 400 "Invalid resource name: 'systems'"Reproduction: Issue 2 — deployment@link silently dropped on DataStream
Request
PUT /sensorhub/api/systems/0420/datastreams/0430 HTTP/1.1
Content-Type: application/json
Authorization: Basic ****
{
"name": "AZ-MA-1 Classification Probabilities",
"...(original fields)...": "...",
"schema": { "...(required by OSH for PUT)..." },
"deployment@link": {
"href": "/sensorhub/api/deployments/043g",
"title": "PROBE-TEST-MARKER",
"uid": "urn:os4csapi:deployment:node:ft-huachuca:alpha:001",
"type": "application/geo+json"
}
}Response to PUT
HTTP 204 No Content
Read-back
GET /sensorhub/api/systems/0420/datastreams/0430 HTTP/1.1
Accept: application/jsonResponse contains no deployment@link field. The field was accepted (204) but not persisted.
Reproduction: Issue 3 — Deployment-scoped endpoints return 400
GET /sensorhub/api/deployments/0420/datastreams HTTP/1.1
→ 400 {"status": 400, "message": "Invalid resource name: 'datastreams'"}
GET /sensorhub/api/deployments/0420/systems HTTP/1.1
→ 400 {"status": 400, "message": "Invalid resource name: 'systems'"}
GET /sensorhub/api/deployments/043g/datastreams HTTP/1.1
→ 400 {"status": 400, "message": "Invalid resource name: 'datastreams'"}Tested on multiple deployment IDs (0420 = SNET with subdeployments, 043g = leaf node). Same result.
Observed pattern
OSH persists @link fields that follow its internal parent→child hierarchy:
| Field | Direction | Persists? |
|---|---|---|
platform@link on Deployment |
Deployment → System (bridge) | ✅ Yes |
system@link on DataStream |
DataStream → System (parent) | ✅ Yes (read-only) |
deployedSystems@link on Deployment |
Deployment → Systems (cross-cutting) | ❌ Dropped |
deployment@link on DataStream |
DataStream → Deployment (cross-cutting) | ❌ Dropped |
This suggests OSH treats deployments and systems as separate, non-intersecting trees with platform@link as the sole bridge — and does not yet implement the cross-cutting associations the spec defines.
Impact
This blocks the "deployment-first" operational workflow that CSAPI was designed to enable:
Spec-intended workflow (broken):
GET /deployments/{nodeId}/datastreams → node's datastreams directly
Current workaround (functional but indirect):
GET /deployments/{nodeId} → read platform@link
GET /systems/{systemId}/datastreams → all system's datastreams (no deployment scoping)
For an acoustic sensor network with 3 nodes × 7 datastreams × N observations, the inability to scope by deployment means:
- No per-node data filtering via API
- No temporal deployment window scoping (when a sensor moves between nodes)
- Clients must do N+1 API calls + client-side join instead of one deployment-scoped query
Questions for maintainers
- Does OSH currently intend to implement the
deployedSystemsassociation and deployment-scoped endpoints? Is this a known roadmap item? - If not yet intended:
- Could
/conformancebe updated to not advertiseconf/deploymentif the requireddeployedSystemsassociation isn't supported? - Could unsupported
@linkfields be rejected with a 4xx error rather than silently dropped? The silent-acceptance pattern makes the gap invisible to clients.
- Could
Suggested resolution
Option A — Implement the missing associations:
- Persist
deployedSystems@link(array) on Deployment resources - Persist
deployment@linkon DataStream resources - Implement
/deployments/{id}/datastreamsand/deployments/{id}/systemsendpoints
Option B — Accurately document current capabilities:
- Remove
conf/deploymentfrom/conformanceifdeployedSystemswon't be supported (or add a note) - Reject unsupported
@linkfields with HTTP 422 instead of silently accepting them
Either option resolves the immediate pain point (silent data loss on write).
Evidence
Detailed probe reports with full HTTP transcripts:
OSH_DeployedSystems_Conformance_Probe.md—deployedSystems@linkprobe methodology and resultsOSH_Deployment_Link_Persistence_Gap.md—deployment@linkprobe + cumulative three-mechanism failure analysis