-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Summary
OSH accepts samplingFeature@link on Observation POST (HTTP 201) but silently discards the field — it is absent from subsequent GET responses. This follows the same "silent-accept / silent-discard" pattern reported in #337 for deployedSystems@link and deployment@link.
SamplingFeature CRUD itself works correctly — the feature can be created, read, updated, and deleted. Only the association from Observation → SamplingFeature via samplingFeature@link is dropped.
| Mechanism | Spec Reference | Behavior |
|---|---|---|
samplingFeature@link on Observation |
OGC 23-002 §7.2.2 | POST accepted (201) → field silently dropped on GET |
Environment
- Server: OSH deployed on Oracle Cloud (latest
masterbranch as of 2026-03) - Date tested: 2026-03-05
- Encoding tested: JSON (
application/json) - Client tooling:
curl(raw HTTP)
Advertised Conformance Classes
GET /conformance returns (observation-relevant subset):
http://www.opengis.net/spec/ogcapi-connectedsystems-2/1.0/conf/observation
http://www.opengis.net/spec/ogcapi-connectedsystems-2/1.0/conf/create-replace-delete
http://www.opengis.net/spec/ogcapi-connectedsystems-1/1.0/conf/sampling-feature
The server claims both conf/observation and conf/sampling-feature.
Reproduction: Step 1 — Create SamplingFeature (works)
Request
POST /sensorhub/api/samplingFeatures HTTP/1.1
Content-Type: application/geo+json
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [-110.35, 31.63] },
"properties": {
"featureType": "sosa:Sample",
"uid": "urn:os4csapi:foi:uas-track-001",
"name": "UAS-Track-001",
"description": "Track for UAS target observed by LOB intersection",
"validTime": ["2026-03-05T00:00:00Z", ".."]
}
}Response
HTTP 201 Created
Location: .../samplingFeatures/040g
Read-back
GET /sensorhub/api/samplingFeatures/040g HTTP/1.1
Accept: application/geo+jsonReturns the full feature with all fields intact. SamplingFeature CRUD works correctly. ✅
Reproduction: Step 2 — POST Observation with samplingFeature@link (accepted but dropped)
Request
POST /sensorhub/api/datastreams/{dsId}/observations HTTP/1.1
Content-Type: application/json
{
"phenomenonTime": "2026-03-05T20:00:00Z",
"resultTime": "2026-03-05T20:00:00Z",
"samplingFeature@link": {
"href": "/sensorhub/api/samplingFeatures/040g",
"uid": "urn:os4csapi:foi:uas-track-001",
"type": "application/geo+json"
},
"result": {
"bearing": 45.0,
"signal_strength": -60
}
}Response
HTTP 201 Created
Location: .../observations/{obsId}
Read-back
GET /sensorhub/api/datastreams/{dsId}/observations?resultTime=latest&limit=1 HTTP/1.1
Accept: application/json{
"phenomenonTime": "2026-03-05T20:00:00Z",
"resultTime": "2026-03-05T20:00:00Z",
"result": {
"bearing": 45.0,
"signal_strength": -60
}
}samplingFeature@link is completely absent from the response. The association was silently discarded.
Observed pattern (cumulative with #337)
OSH persists @link fields that follow its internal parent→child hierarchy but drops cross-cutting associations:
| 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 (#337) |
deployment@link on DataStream |
DataStream → Deployment (cross-cutting) | ❌ Dropped (#337) |
samplingFeature@link on Observation |
Observation → SamplingFeature (cross-cutting) | ❌ Dropped (this issue) |
This is the third instance of the silent-accept / silent-discard pattern for cross-cutting @link fields.
Impact
samplingFeature@link enables grouping observations by the real-world feature they describe (e.g., a UAS track, a weather station, a water body). Without it:
- Clients cannot query observations by sampling feature via the API
/samplingFeatures/{id}/observationsscoped queries are not possible- Track-level or target-level data grouping must be done entirely client-side
- SamplingFeatures can be created but never meaningfully associated with data
Questions
- Is
samplingFeature@linkpersistence on the roadmap? Is this a known gap? - As with Deployment associations silently dropped: deployedSystems@link, deployment@link not persisted; deployment-scoped endpoints return 400 #337, could unsupported
@linkfields be rejected with a 4xx rather than silently accepted? The silent-drop pattern makes the gap invisible to clients.
Suggested resolution
Option A — Implement the association:
Persist samplingFeature@link on Observation resources so the Observation → SamplingFeature relationship round-trips correctly.
Option B — Accurately reflect current capabilities:
Reject samplingFeature@link with HTTP 422 instead of silently accepting it, so clients discover the limitation at write time rather than on read-back.
Either option resolves the immediate pain point (silent data loss on write).
Detailed probe report
OSH_SamplingFeature_Link_Persistence_Gap.md— full HTTP transcripts and analysis
Cross-reference: OS4CSAPI/osh-core#2 (same issue on our fork), #337 (deployment association gaps — same pattern)