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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions