This document describes the technical design and runtime behavior of the standalone
simulator/ application.
The simulator consists of three containers:
| Service | Tech | Responsibility | Port |
|---|---|---|---|
sim-frontend |
React + Framer Motion | UI, interaction, visual workflow rendering | 3000 |
sim-backend |
Node.js + Express | API, persistence orchestration, policy checks, state machine | 3001 |
sim-fuseki |
Apache Jena Fuseki | RDF graph storage, SPARQL queries | 3030 |
High-level data flow:
- Frontend triggers backend APIs.
- Backend persists operational state in SQLite.
- Backend maps metadata to RDF and writes/queries Fuseki.
- Frontend visualizes process states (discovery, catalog fan-out, negotiation, transfer).
Main HTTP API and orchestration layer.
Responsibilities:
- node, asset, policy, catalog endpoints
- semantic search endpoint (
/api/semantic/search) - negotiation/transfer endpoints
- reset and housekeeping endpoints
SQLite schema and data access layer (better-sqlite3).
Core tables:
nodesassetspoliciesnegotiationstransfersreceived_data
Notes:
- Uses
WALjournal mode. - Includes schema migration helper (
ensureColumn) for additive columns.
Fuseki integration and SPARQL logic.
Responsibilities:
- map published assets to RDF/DCAT triples
- upsert/delete datasets in Fuseki
- execute semantic search query with filter composition
- support optional Fuseki Basic Auth via env vars
Policy evaluation against participant claims.
Used in:
- catalog visibility filtering
- negotiation acceptance/denial
Negotiation and transfer lifecycle.
Negotiation states:
REQUESTED -> OFFERED -> AGREEDTERMINATEDon denial/error
Transfer states:
STARTED -> COMPLETEDTERMINATEDon failure
Root visualization surface:
- nodes/connector positioning
- beams and pulses for control/data plane
- node assets loading and local updates
Participant interaction UI:
- browse dataspace
- semantic search popup
- negotiation/transfer hooks
- data storage section
Asset publish form with:
- file upload (
JSON,CSV,TXT) - policy selection and constraint values
- dynamic DCAT field selection
Canvas pan/zoom logic.
Implementation detail:
- middle-mouse pan uses immediate x/y updates for direct control
- zoom remains eased
Base URL: http://localhost:3001/api
GET /nodesGET /nodes/:idPOST /nodesPATCH /nodes/:idPATCH /nodes/:id/positionDELETE /nodes/:id
GET /assets?nodeId=<id>GET /assets/:idPOST /assetsDELETE /assets/:id
POST /assets stores:
- name/description
- file metadata
- payload content (
content) - policy reference
- DCAT fields
GET /policiesPOST /policiesDELETE /policies/:id
GET /catalog?consumerNodeId=<id>&providerNodeId=<id>
Behavior:
- applies policy visibility filtering for consumer
- optional provider-scoping for fan-out simulation
POST /semantic/search
Request body fields:
searchText(optional)consumerNodeId(optional but recommended)dcatFieldFilters: [{ key, value }](optional)limit
POST /negotiateGET /negotiate/:idPOST /transfer
Operational state and payload persistence:
- published assets and payload content
- policy definitions
- negotiation/transfer records
- received-data entries for consumers
Semantic metadata persistence:
- RDF/DCAT graph data
- named graph grouping by publisher/session
- queried by SPARQL for semantic refinement
The semantic endpoint is catalog-first:
- Load all assets from SQLite.
- Apply policy visibility against
consumerNodeIdclaims. - Build visible dataset ID set.
- Execute SPARQL limited to visible IDs.
- Return enriched semantic result list.
This prevents semantic search from exposing non-visible datasets.
Free text may target title/description/keywords/themes.
Structured field filters are mapped to predicates including:
dcat:keyworddcat:themedct:spatialdct:temporaldct:languagedct:formatdct:licensedct:creatordct:conformsTodct:accrualPeriodicitydcat:landingPagedcat:contactPoint
Policy constraints are evaluated against node claims in metadata.
Example claim keys used in simulator flows:
industryorgRole- participant identifier / DID-like values
Policy effects:
- catalog inclusion/exclusion
- negotiation acceptance/termination
Sequence (auto mode):
- Consumer sends
POST /negotiate. - Backend creates negotiation and advances state asynchronously.
- Frontend polls
GET /negotiate/:id. - On
AGREED, frontend triggersPOST /transfer. - Backend records transfer and copies payload to consumer received store.
- Frontend updates consumer storage view.
Semantic-result action path:
Request Contractcan run with auto-transfer option.
Publish accepts JSON, CSV, TXT.
Behavior:
JSON: parsed if valid, otherwise treated as textCSV/TXT: stored as text payload
Payload is persisted in:
assets.asset_contentreceived_data.asset_content(after transfer)
Relevant environment variables:
PORT(backend)DB_PATHFUSEKI_URLFUSEKI_DATASETFUSEKI_USERNAMEFUSEKI_PASSWORDAUTO_ACCEPT_NEGOTIATIONS
- single local deployment simulates multiple participants
- no full DSP/EDC connector runtime path
- simplified transfer semantics vs. production data plane
- no cryptographic identity/trust infrastructure
Start:
docker compose up -d --buildRebuild frontend only:
docker compose build sim-frontend && docker compose up -d sim-frontendRebuild backend only:
docker compose build sim-backend && docker compose up -d sim-backendTail backend logs:
docker compose logs -f sim-backendWhen citing this artifact in a paper, position it as:
- an executable reference implementation of policy-constrained semantic discovery,
- a controlled experimentation environment,
- and a communication tool for complex dataspace workflows.