Skip to content
Build 9234610

Camel Topology

The cm-* Camel microservices are the middleware between storefronts, OMS, warehouses, and retailer EDI. This page shows how they wire together.

Layer Convention

Every service name ends in one of three suffixes:

Suffix Layer Role
*-exp Experience External-facing REST APIs
*-prc Processing Async business logic, ASB consumers
*-sys System Proxy/adapter to an external system (Cirro, NAV, Arena, etc.)

A typical flow: external caller hits *-exp → work gets queued to *-prc*-prc calls one or more *-sys services → *-sys talks to the external system.

Topology

Camel topology

Three columns = the Experience → Processing → System layers. Box color is the layer; red marks the retiring cm-fulfill-exp. Solid arrows are sync calls; dashed arrows are async / lower-confidence paths. Click to zoom.

This hand-drawn view runs slightly behind the prose

It still shows a cm-nav-sys box, but that service is a retired stub — its NAV order-release job moved into cm-order-prc, and NAV SOAP / page calls now run through cm-int-service-sys. The drawing also predates the shared Config Server / Key Vault / Service Bus infrastructure; for those, the layer sections below are the source of truth.

Experience Layer

cm-ext-service-exp

External-facing REST (OMS, partners). Forwards fulfillment requests onto cm-fulfill-prc via ASB.

cm-int-service-exp

Internal REST for other PopSockets services. Delegates to cm-int-service-sys. New internal endpoints land here.

cm-fulfill-exp

Legacy fulfillment REST. Retiring — use cm-int-service-exp or cm-ext-service-exp for new work.

Processing Layer

cm-edi-prc

EDI 850/940/856/945 processing. Polls SPS/PS SFTP, splits documents, dispatches 940s to Cirro (see the EDI pipeline for the full flow), publishes shipped-b2b events when B2B orders ship.

cm-order-prc

Orchestrates order lifecycle, routes fulfillment, publishes shipped events. Calls most of the *-sys services — everything except cm-product-sys, cm-printprod-sys, and cm-sfcc-sys. Also consumes the nav-order-release Service Bus queue directly (NAV → OMS release path) — that work used to live in cm-nav-sys, which no longer exists. Its scheduled poll into cm-jackyun-sys (China order fetch) is built but disabled in prod (cron -).

cm-fulfill-prc

Handles fulfillment-request-* queues from OMS (AES-encrypted payloads), decrypts, forwards to Cirro. Walkthrough: Order Export example.

cm-batching-prc

Consumes batching-update-topic and fans out to PrintStation (via cm-printprod-sys), OMS, and cm-order-prc.

cm-product-prc

Polls Arena for item/ECO events via @Scheduled, fans out to OMS/batching/Jackyun. Exposes POST /jackyun/resync for manual SKU resync.

cm-int-service-prc

Likely ADX log ingestion — confidence is low. Verify before touching.

System Layer

cm-int-service-sys

Owns the PostgreSQL edi_docs + fulfillment_tracking tables (live schema integration_int_service_sys_<env>). Also the only outbound NAV SOAP caller — packing instructions (PackagingInstructions codeunit) and item/BOM sync (qbd* pages). No separate NAV service.

cm-cirro-sys

Bearer-token proxy to Cirro. Does not modify payloads.

cm-osor-sys

Proxy to OMS (target host is per-env — resolved from the config server, not hardcoded). Handles order sync, NAV order-release acks back to OMS, and Gladly endpoints.

cm-snowflake-sys

Writes order data to Snowflake DEV.CIRRO.*.

cm-printprod-sys

Consumes batching-update-printstation, forwards to PrintStation.

cm-product-sys

Arena PLM API proxy. Shares session tokens across pods via Hazelcast.

cm-jackyun-sys

Jackyun/KH China integration. The only live path in prod is product/SKU/BOM sync — HTTP from cm-product-prc → Jackyun (verified running). The China order lane (cm-order-prc polls Jackyun/Qimen → batching → PrintStation → KH 3PL fulfillment) is built but disabled in prod (poll cron -; enabled in dev only). No OMS connection at all.

cm-sfcc-sys

Salesforce Commerce Cloud integration. Deployed in nonprod only (dev/qa/stage) — there is no prod deployment. Rarely used.

Infrastructure

These aren't cm-* business services, but every service depends on them. They don't appear on the topology map above.

Spring Cloud Config Server (cm-spring-cloud-config)

Central configuration for every cm-* service. Runs as exactly two instances:

Instance Deployed in Serves profiles Backend table External URL
nonprod int-dev (int-usw-aks-1) dev, qa, stage spring_cloud_service_nonprod.properties camelconfigserver-np.corp.popsockets.com
prod int-prod (int-usw-aks-2) prod spring_cloud_service_prod.properties camelconfigserver.corp.popsockets.com
  • Backend is JDBC, not a Git repo (Spring profiles jdbc,nonprod / jdbc,prod) — properties live in a Postgres table and are resolved live on every request.
  • Each service imports its config at startup via spring.config.import. Most have no @RefreshScope, so a config change needs a consumer pod restart to take effect. The config server itself needs no restart — it re-reads the table each request.
  • ⚠️ The nonprod Postgres also holds integration_*.properties tables. Those are repo-intent mirrors that are not served — only spring_cloud_service_* is live. Writing a mirror table changes nothing.

Azure Key Vault

Holds every secret the config server hands out — DB passwords, Service Bus connection strings, Cirro/OMS/NAV credentials, AES keys.

Vault Env
popint-cm-kv-1 nonprod (dev/qa/stage)
popint-cm-kv-2 prod
  • Only the config server reads Key Vault. Business services never touch it directly — they receive already-resolved values in their served config.
  • Properties reference secrets as ${secret-name} placeholders (e.g. ${dev-ediprc-sb-connection-edi850-topic}); the config server substitutes the vault value before serving.
  • The config server caches vault secrets and refreshes every 15 min (refresh-interval=900000). A rotated secret isn't picked up until that refresh and a consumer restart.

Azure Service Bus

The async backbone. *-prc services consume queues/topics; producers publish across service boundaries.

Namespace Env
int-nonprod-psb-1.servicebus.windows.net dev/qa/stage
int-prod-psb-1.servicebus.windows.net prod
  • Queue/topic names follow int-<env>-<name> — e.g. int-dev-edi-850-topic, int-qa-edi-940-db, int-dev-edi-shipped-b2b-topic (topic) + int-dev-edi-shipped-b2b (subscription).
  • Connection strings are per-queue and live in Key Vault, referenced from config as ${<env>-<app>-sb-connection-...}.
  • Topic subscriptions filter on an event_type message header.
  • DLQ max delivery = 1 on most queues — one processing failure dead-letters the message immediately, with no retries.

Experimental / not on the map

  • cm-sku-do and cm-thedelorean are deployed in dev only and have no module in the camel repo — treat them as experiments, not part of the standard topology.
  • cm-file-transfer has a repo module but is not deployed in any env (an SFTP-utility proof of concept).

Retired services

  • cm-nav-sys — gone. It used to be the NAV order-release worker; that job (consuming the nav-order-release Service Bus queue) now lives in cm-order-prc. Outbound NAV SOAP calls were always in cm-int-service-sys, not here. No repo module, no deployment in any env.

Gotchas

  • cm-cirro-sys does not transform payloads. It's a thin proxy. Business logic happens in cm-order-prc, cm-fulfill-prc, or cm-edi-prc before the call.
  • NAV lives in two places, and neither is cm-nav-sys. Inbound order-release is consumed directly by cm-order-prc (the nav-order-release Service Bus queue). Outbound NAV SOAP — packing instructions and qbd* item sync — goes through cm-int-service-sys. cm-nav-sys is retired (see Retired services).
  • cm-jackyun-sys's only live path is product sync. SKU/BOM upserts come in via HTTP from cm-product-prc → Jackyun (running in prod). The order path (jackyun-orders-topic from cm-order-prc) exists in code but the poll is disabled in prod — don't assume China orders flow through it.
  • cm-fulfill-exp is retiring. It's still deployed in every env, but add new fulfillment endpoints to cm-int-service-exp or cm-ext-service-exp instead.
  • cm-sfcc-sys is nonprod-only. It runs in dev/qa/stage but has no prod deployment — don't assume it's in the prod path.
  • cm-file-transfer isn't deployed. The repo module exists but nothing runs it in any env.
  • cm-int-service-prc has low-confidence data. Rarely touched — verify against the code before relying on anything this page says about it.