Skip to content

Azure Service Bus — Integration Architecture

Overview

CustomsTUF integrates with third-party logistics platforms (e.g. Qargo) and downstream filing systems (e.g. Descartes) via two Azure Service Bus queues:

Queue Direction Purpose
customstuf-inbound → CustomsTUF Logistics providers push trip/dossier JSON
customstuf-outbound CustomsTUF → Generated XMLs ready for SFTP upload

Flow diagram

flowchart TD
    subgraph Third["Third-party logistics (e.g. Qargo)"]
        Q["Qargo\n(per rit / trip)"]
    end

    subgraph ASB_IN["Azure Service Bus — inbound queue\n(customstuf-inbound)"]
        MSG_IN["Message\n{ trip_id, dossiers: [...] }"]
    end

    subgraph CSTUF["CustomsTUF (Azure / Docker)"]
        BGW["Background Worker\n(IHostedService)"]
        DB["CustomsTUF Database\n(dossiers, declarations)"]
        GEN["XML Generator\n(CC015C / IE415B)"]
    end

    subgraph ASB_OUT["Azure Service Bus — outbound queue\n(customstuf-outbound)"]
        MSG_OUT["Message\n{ dossier_id, xml_base64, filename }"]
    end

    subgraph DESC["Descartes (Azure Function / Logic App)"]
        FN["Queue trigger\nfunction"]
        SFTP["SFTP Upload\n(customs authority)"]
    end

    Q -->|"POST JSON per rit\n(1 msg = 1 trip)"| MSG_IN
    MSG_IN -->|"peek-lock / complete"| BGW
    BGW -->|"create/update dossiers\nper trip"| DB
    DB -->|"trigger generation\n(manual or auto)"| GEN
    GEN -->|"put XML message"| MSG_OUT
    MSG_OUT -->|"triggers"| FN
    FN -->|"uploads XML file"| SFTP

Message formats (draft)

Inbound — Qargo trip message

{
  "trip_id": "QARGO-2026-001234",
  "dossiers": [
    {
      "ucr": "TUF/2026/001",
      "regime": "T1",
      "shipper": { "name": "...", "country": "BE" },
      "consignee": { "name": "...", "country": "CH" },
      "goods": [
        { "hs_code": "84713000", "description": "...", "gross_weight": 125.5 }
      ]
    }
  ]
}

Outbound — XML ready for SFTP

{
  "dossier_id": 42,
  "ucr": "TUF/2026/001",
  "message_type": "CC015C",
  "filename": "SMF_NCTS_CC015C_TUF2026001_20260518.xml",
  "xml_base64": "<base64-encoded XML>"
}

Processing logic (background worker)

sequenceDiagram
    participant SB as Service Bus<br/>(inbound)
    participant BG as Background Worker
    participant DB as Database
    participant GEN as XML Generator
    participant SB2 as Service Bus<br/>(outbound)

    BG->>SB: PeekLock message (trip)
    SB-->>BG: Message (trip JSON)
    loop for each dossier in trip
        BG->>DB: Upsert dossier + lines
    end
    BG->>SB: Complete message
    alt auto-generate XML enabled
        BG->>GEN: Generate CC015C / IE415B
        GEN->>DB: Store generated XML reference
        GEN->>SB2: Publish outbound message
    end
    SB2-->>Descartes: Queue trigger fires
    Descartes->>SFTP: Upload XML to customs authority

Notes

  • One message = one trip (rit). A trip may contain multiple dossiers; the worker creates one CustomsTUF dossier per entry.
  • Peek-lock is used on the inbound queue so that a crash before Complete() re-queues the message automatically.
  • XML generation can be manual (user clicks Generate on the dossier page) or automatic (background worker publishes to outbound queue immediately after dossier creation).
  • The outbound queue decouples CustomsTUF from Descartes — Descartes can be unavailable without blocking the filing workflow.