Skip to content

Deployment associations silently dropped: deployedSystems@link, deployment@link not persisted; deployment-scoped endpoints return 400 #337

@Sam-Bolling

Description

@Sam-Bolling

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

Environment

  • Server: OSH deployed on Oracle Cloud (latest master branch as of 2026-03)
  • 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

{
  "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.

Nested endpoints also fail

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/{sysId}/datastreams/{dsId} HTTP/1.1
Content-Type: application/json

{
  "name": "AZ-MA-1 Classification Probabilities",
  "...(original fields)...": "...",
  "schema": { "...(required 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

HTTP 204 No Content

Read-back

Subsequent GET contains no deployment@link field. Accepted but not persisted.


Reproduction: Issue 3 — Deployment-scoped endpoints return 400

GET /sensorhub/api/deployments/{depId}/datastreams HTTP/1.1
→ 400 {"status": 400, "message": "Invalid resource name: 'datastreams'"}

GET /sensorhub/api/deployments/{depId}/systems HTTP/1.1
→ 400 {"status": 400, "message": "Invalid resource name: 'systems'"}

Tested on multiple deployment IDs (parent with subdeployments, and leaf nodes). Same result on all.


Observed pattern

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
deployment@link on DataStream DataStream → Deployment (cross-cutting) ❌ Dropped

Impact

This blocks the "deployment-first" operational workflow that CSAPI was designed to enable:

Spec-intended (broken):
  GET /deployments/{nodeId}/datastreams → node's datastreams directly

Current workaround (functional but indirect):
  GET /deployments/{nodeId}            → read platform@link href
  GET /systems/{systemId}/datastreams  → returns all system datastreams (no deployment scoping)

For sensor networks with multiple deployment nodes, this means:

  • No per-deployment data filtering via the API
  • No temporal deployment window scoping (when sensors move between deployments)
  • Clients must follow platform@link chains and aggregate manually

Questions

  1. Is deployment-scoped data access (/deployments/{id}/datastreams, deployedSystems@link) on the roadmap? Is this a known gap?
  2. If these features aren't yet planned, could:
    • /conformance be updated to reflect which deployment associations are actually supported?
    • Unsupported @link fields 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 missing associations:

  1. Persist deployedSystems@link (array) on Deployment resources
  2. Persist deployment@link on DataStream resources
  3. Implement /deployments/{id}/datastreams and /deployments/{id}/systems endpoints

Option B — Accurately reflect current capabilities:

  1. Update /conformance to clarify which deployment association features are supported
  2. Reject unsupported @link fields with HTTP 422 instead of silently accepting them

Either option resolves the immediate pain point (silent data loss on write).


Detailed probe reports

Cross-reference: OS4CSAPI/osh-core#1 (same issue on our fork)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions