# sartrebrasil/sftp-jms-bridge-v3 architecture

> Architecture diagram of the GitHub repository sartrebrasil/sftp-jms-bridge-v3, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sartrebrasil/sftp-jms-bridge-v3
- Repository: https://github.com/sartrebrasil/sftp-jms-bridge-v3

## Overview

sftp-jms-bridge is a Spring Integration service that streams tenant documents from remote SFTP into JMS without local-file staging. The documented path claims each file at ingress, reads and enriches its bytes, then publishes either a single-document or grouped JSON envelope. After JMS commit it marks claims processed and moves remote files; a scheduled reconciler retries orphaned moves. The README documents these relationships, but no source excerpts were provided, so implementation-level call ownership and optional details are not independently verified.

Main entry points: [`src/main/java/com/example/sftpjms/service/JmsPublicationService.java`](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/JmsPublicationService.java) (JMS publication), [`src/main/java/com/example/sftpjms/service/DocumentFactory.java`](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/DocumentFactory.java) (Document factory), [`src/main/java/com/example/sftpjms/idempotency/IdempotencyService.java`](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/IdempotencyService.java) (Idempotency service), [`src/main/java/com/example/sftpjms/idempotency/ingress/IngressClaimGateway.java`](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/ingress/IngressClaimGateway.java) (Ingress claim)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ingress["SFTP ingress"]
  node_inbound["Streaming poller"]
  node_async["Worker channel<br/>[AsyncConfig.java]"]
  node_claim["Ingress claim"]
end

subgraph group_processing["Document processing"]
  node_factory["Document factory"]
  node_contenttype["Content type"]
  node_document["Document model<br/>[Document.java]"]
  node_router["Mode routing"]
  node_grouping["Document grouping"]
end

subgraph group_delivery["JMS delivery"]
  node_publication["JMS publication"]
  node_envelope["JSON envelope"]
  node_serializer["Envelope serializer"]
  node_encoder["Gzip Base64"]
end

subgraph group_reliability["Reliability and tenancy"]
  node_tenant["Tenant routing"]
  node_idempotency["Idempotency service"]
  node_store[("Idempotency store")]
  node_lifecycle["SFTP lifecycle"]
  node_reconcile["Move reconciler"]
  node_error["Lease error handler"]
end

node_sftp(("SFTP server"))
node_broker(("JMS broker"))
node_redis[("Redis")]

node_sftp -->|"streams files"| node_inbound
node_inbound -->|"dispatches work"| node_async
node_async -->|"dispatches"| node_claim
node_claim -->|"claims lease"| node_idempotency
node_claim -->|"forwards stream"| node_factory
node_factory -->|"resolves type"| node_contenttype
node_factory -->|"creates"| node_document
node_factory -->|"forwards document"| node_router
node_tenant -->|"configures tenant polls"| node_inbound
node_router -->|"routes single"| node_publication
node_router -->|"routes grouped"| node_grouping
node_grouping -->|"releases group"| node_publication
node_publication -->|"creates envelope"| node_envelope
node_envelope -->|"serializes"| node_serializer
node_serializer -->|"encodes content"| node_encoder
node_publication -->|"publishes transactionally"| node_broker
node_publication -->|"promotes after commit"| node_idempotency
node_idempotency -->|"uses store"| node_store
node_store -->|"persists claims"| node_redis
node_publication -->|"registers post-commit move"| node_lifecycle
node_lifecycle -->|"moves processed files"| node_sftp
node_reconcile -->|"retries orphan moves"| node_sftp
node_error -->|"releases lease"| node_idempotency

click node_inbound "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/SftpIntegrationConfig.java"
click node_async "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/AsyncConfig.java"
click node_claim "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/ingress/IngressClaimGateway.java"
click node_tenant "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/tenant/TenantIngressFlowManager.java"
click node_factory "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/DocumentFactory.java"
click node_contenttype "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/document/ContentTypeResolver.java"
click node_document "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/model/Document.java"
click node_router "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/InboundFlowConfig.java"
click node_grouping "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/RedisGroupingConfig.java"
click node_publication "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/JmsPublicationService.java"
click node_envelope "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/jms/JmsEnvelopeFactory.java"
click node_serializer "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/jms/JmsEnvelopeSerializer.java"
click node_encoder "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/jms/encoding/GzipBase64ContentEncoder.java"
click node_idempotency "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/IdempotencyService.java"
click node_store "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/RedisIdempotencyStore.java"
click node_lifecycle "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/SftpLifecycleService.java"
click node_reconcile "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/reconciliation/SftpMoveReconciliationService.java"
click node_error "https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/error/ReleaseLeaseOnErrorHandler.java"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_inbound,node_async,node_claim toneBlue
class node_factory,node_contenttype,node_document,node_router,node_grouping,node_redis toneAmber
class node_publication,node_envelope,node_serializer,node_encoder,node_sftp toneMint
class node_tenant,node_idempotency,node_store,node_lifecycle,node_reconcile,node_error toneRose
class node_broker toneIndigo
```

## Components

### SFTP ingress

- [Streaming poller](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/SftpIntegrationConfig.java): `src/main/java/com/example/sftpjms/config/SftpIntegrationConfig.java`
- [Worker channel](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/AsyncConfig.java): `src/main/java/com/example/sftpjms/config/AsyncConfig.java`
- [Ingress claim](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/ingress/IngressClaimGateway.java): `src/main/java/com/example/sftpjms/idempotency/ingress/IngressClaimGateway.java`

### Document processing

- [Document factory](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/DocumentFactory.java): `src/main/java/com/example/sftpjms/service/DocumentFactory.java`
- [Content type](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/document/ContentTypeResolver.java): `src/main/java/com/example/sftpjms/document/ContentTypeResolver.java`
- [Document model](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/model/Document.java): `src/main/java/com/example/sftpjms/model/Document.java`
- [Mode routing](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/InboundFlowConfig.java): `src/main/java/com/example/sftpjms/config/InboundFlowConfig.java`
- [Document grouping](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/config/RedisGroupingConfig.java): `src/main/java/com/example/sftpjms/config/RedisGroupingConfig.java`

### JMS delivery

- [JMS publication](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/JmsPublicationService.java): `src/main/java/com/example/sftpjms/service/JmsPublicationService.java`
- [JSON envelope](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/jms/JmsEnvelopeFactory.java): `src/main/java/com/example/sftpjms/jms/JmsEnvelopeFactory.java`
- [Envelope serializer](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/jms/JmsEnvelopeSerializer.java): `src/main/java/com/example/sftpjms/jms/JmsEnvelopeSerializer.java`
- [Gzip Base64](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/jms/encoding/GzipBase64ContentEncoder.java): `src/main/java/com/example/sftpjms/jms/encoding/GzipBase64ContentEncoder.java`

### Reliability and tenancy

- [Tenant routing](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/tenant/TenantIngressFlowManager.java): `src/main/java/com/example/sftpjms/tenant/TenantIngressFlowManager.java`
- [Idempotency service](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/IdempotencyService.java): `src/main/java/com/example/sftpjms/idempotency/IdempotencyService.java`
- [Idempotency store](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/RedisIdempotencyStore.java): `src/main/java/com/example/sftpjms/idempotency/RedisIdempotencyStore.java`
- [SFTP lifecycle](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/service/SftpLifecycleService.java): `src/main/java/com/example/sftpjms/service/SftpLifecycleService.java`
- [Move reconciler](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/reconciliation/SftpMoveReconciliationService.java): `src/main/java/com/example/sftpjms/reconciliation/SftpMoveReconciliationService.java`
- [Lease error handler](https://github.com/sartrebrasil/sftp-jms-bridge-v3/blob/master/src/main/java/com/example/sftpjms/idempotency/error/ReleaseLeaseOnErrorHandler.java): `src/main/java/com/example/sftpjms/idempotency/error/ReleaseLeaseOnErrorHandler.java`

### Other components

- **SFTP server**
- **JMS broker**
- **Redis**

## Connections

- SFTP server → Streaming poller: streams files (evidence: `README.md`)
- Streaming poller → Worker channel: dispatches work (evidence: `README.md`)
- Worker channel → Ingress claim: dispatches (evidence: `README.md`)
- Ingress claim → Idempotency service: claims lease (evidence: `README.md`)
- Ingress claim → Document factory: forwards stream (evidence: `README.md`)
- Document factory → Content type: resolves type (evidence: `README.md`)
- Document factory → Document model: creates (evidence: `README.md`)
- Document factory → Mode routing: forwards document (evidence: `README.md`)
- Tenant routing → Streaming poller: configures tenant polls (evidence: `README.md`)
- Mode routing → JMS publication: routes single (evidence: `README.md`)
- Mode routing → Document grouping: routes grouped (evidence: `README.md`)
- Document grouping → JMS publication: releases group (evidence: `README.md`)
- JMS publication → JSON envelope: creates envelope (evidence: `README.md`)
- JSON envelope → Envelope serializer: serializes (evidence: `README.md`)
- Envelope serializer → Gzip Base64: encodes content (evidence: `README.md`)
- JMS publication → JMS broker: publishes transactionally (evidence: `README.md`)
- JMS publication → Idempotency service: promotes after commit (evidence: `README.md`)
- Idempotency service → Idempotency store: uses store (evidence: `README.md`)
- Idempotency store → Redis: persists claims (evidence: `README.md`)
- JMS publication → SFTP lifecycle: registers post-commit move (evidence: `README.md`)
- SFTP lifecycle → SFTP server: moves processed files (evidence: `README.md`)
- Move reconciler → SFTP server: retries orphan moves (evidence: `README.md`)
- Lease error handler → Idempotency service: releases lease (evidence: `README.md`)
