Skip to content

About

TEC.Messaging: mensageria com outbox/inbox (Azure Service Bus, AWS SQS/SNS, RabbitMQ) para .NET 10

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TEC

📮 TEC.Messaging

Mensageria corporativa de alto desempenho: Outbox transacional, Inbox idempotente, sanitização de PII (LGPD), contratos versionados e suporte agnóstico a RabbitMQ, Azure Service Bus e AWS SQS/SNS.

CI .NET AOT Versão Licença: Apache 2.0

Início rápido · Documentação · Changelog


📑 Sumário


✨ Por que usar

Sem o TEC.Messaging Com o TEC.Messaging
Publica no broker dentro do caso de uso: commit falha, evento já saiu (ou o contrário) Outbox transacional: o evento é gravado na mesma transação do agregado e publicado depois
Um relay trava a fila inteira numa mensagem com defeito Falha isolada: backoff exponencial por mensagem e status Dead depois de N tentativas
Publicação dentro de transação longa, com travas no banco Reserva (lease) em transação curta e publicação fora da transação
Evento de domínio serializado direto para outros serviços Contratos de integração com nome e versão estáveis ([IntegrationEvent]) e mapeadores
Reentrega processa duas vezes Inbox: registro da mensagem processada na mesma transação do efeito
Retry com Thread.Sleep e mensagens perdidas RabbitMQ com publisher confirms, filas de espera, DLQ, pausa e administração da DLQ
Trace e correlação quebrados entre serviços Correlação, causa e traceparent propagados; métricas e spans TEC.Messaging

📦 Pacotes

Pacote Para que serve Quando instalar Depende de
TEC.Messaging Envelope, contratos, mapeadores, Outbox/Inbox (abstrações), sanitizador LGPD de PII, relay, correlação, métricas Sempre TEC.Core
TEC.Messaging.SqlServer Outbox e Inbox no SQL Server com EF Core, interceptor de eventos de domínio, administração Persistência em SQL Server com EF Core TEC.Messaging, EF Core
TEC.Messaging.PostgreSql Outbox e Inbox no PostgreSQL com EF Core (FOR UPDATE SKIP LOCKED, RETURNING), interceptor Persistência em PostgreSQL com EF Core TEC.Messaging, EF Core, Npgsql
TEC.Messaging.RabbitMQ Publicador com confirms, consumidores com concorrência paralela, retry escalonado, DLQ, pausa, health check Broker RabbitMQ 3.13+/4.x TEC.Messaging, TEC.Vault, RabbitMQ.Client 7, Polly.Core
TEC.Messaging.AzureServiceBus Publicador e consumidor para filas e tópicos do Azure Service Bus, confirms, reenvio agendado com espera crescente, DLQ, concorrência, rotação de credencial, health check Nuvem Microsoft Azure TEC.Messaging, TEC.Vault, Azure.Messaging.ServiceBus
TEC.Messaging.Aws Publicador e consumidor para filas Amazon SQS e tópicos SNS, long polling com renovação de visibilidade, concorrência, DLQ, rotação de credencial, health check Nuvem Amazon Web Services (AWS) TEC.Messaging, TEC.Vault, AWSSDK (SQS/SNS)

Os seis pacotes têm a mesma versão e saem juntos.


🧬 Ecossistema TEC

flowchart BT
    Core["🧰 TEC.Core<br/><sub>Result, erros, domínio</sub>"]
    Vault["🔐 TEC.Vault<br/><sub>segredos, chaves, certificados</sub>"]
    Cqrs["🧭 TEC.Cqrs<br/><sub>commands, queries, pipeline</sub>"]
    Sec["🛡️ TEC.Security<br/><sub>autenticação, autorização</sub>"]
    Obs["📡 TEC.Observability<br/><sub>traces, métricas, logs</sub>"]
    Orm["🗄️ TEC.ORM<br/><sub>persistência</sub>"]
    Msg["📮 TEC.Messaging<br/><sub>Outbox, Inbox, brokers</sub>"]
    Vault --> Core
    Cqrs --> Core
    Sec --> Core
    Sec --> Vault
    Orm --> Core
    Orm --> Cqrs
    Orm --> Vault
    Msg --> Core
    Msg --> Vault
    style Msg fill:#1f6feb,color:#fff
Loading

O TEC.Messaging não depende do TEC.Cqrs nem do TEC.ORM: funciona de forma autônoma com qualquer DbContext. Traces, logs e métricas TEC.Messaging são assinados automaticamente pelo TEC.Observability e exportáveis para qualquer coletor OpenTelemetry (Grafana, Datadog, Zabbix, Azure Monitor, etc.).


📥 Instalação

Feed do GitHub Packages (PAT com read:packages):

dotnet nuget add source https://nuget.pkg.github.com/tudoemcodigo/index.json -n tec-interno -u <usuario-github> -p <PAT>

# Núcleo e persistência
dotnet add package TEC.Messaging
dotnet add package TEC.Messaging.SqlServer    # ou TEC.Messaging.PostgreSql

# Broker desejado
dotnet add package TEC.Messaging.RabbitMQ     # ou TEC.Messaging.AzureServiceBus ou TEC.Messaging.Aws

🚀 Início rápido

// 1. Contrato de integração (público, versionado) e o evento de domínio (interno)
[IntegrationEvent("vendas.pedido-aprovado", Version = 1)]
public sealed record PedidoAprovadoV1(Guid PedidoId, decimal Total);

public sealed record PedidoAprovado(Guid PedidoId, decimal Total, DateTimeOffset OccurredAt) : IDomainEvent;

// 2. Registro
builder.Services.AddTecMessaging()
    .AddEventType<PedidoAprovadoV1>()
    .Map<PedidoAprovado>(e => new PedidoAprovadoV1(e.PedidoId, e.Total))
    .UseSqlServer<VendasDbContext>()                                  // Outbox/Inbox no banco da aplicação
    .UseRabbitMq(o =>                                                 // URI no segredo "rabbitmq" do TEC.Vault
    {
        o.Exchange = "vendas.eventos";
        o.RoutingKeyPrefixToRemove = "vendas.";                       // routing key = tipo sem o prefixo ("pedido-aprovado")
    })
    .AddConsumer<Faturamento>()                                       // o consumidor do exemplo abaixo
    .AddOutboxRelay();

builder.Services.AddDbContext<VendasDbContext>((sp, o) => o.UseSqlServer(conexao).UseTecMessaging(sp));

// 3. No modelo: modelBuilder.AddTecMessaging("vendas");  (e gere a migration)

// 4. No caso de uso: só altere o agregado. O evento vira mensagem no mesmo SaveChanges.
pedido.Aprovar(agora);              // RaiseDomainEvent(new PedidoAprovado(...))
await db.SaveChangesAsync(ct);

Consumidor idempotente:

public sealed class Faturamento(RabbitMqConsumerDependencies deps, IServiceScopeFactory scopes) : RabbitMqConsumer(deps)
{
    protected override QueueDefinition Queue { get; } = new("financeiro.faturamento", ["pedido-aprovado"]);

    protected override async Task<ConsumeResult> HandleAsync(ReceivedMessage message, CancellationToken ct)
    {
        await using var scope = scopes.CreateAsyncScope();
        if (!await scope.ServiceProvider.GetRequiredService<IInboxStore>().TryBeginAsync(message.Envelope.MessageId, "faturamento", ct))
            return ConsumeResult.Completed;                      // reentrega: já processada
        // ... efeito ...
        await scope.ServiceProvider.GetRequiredService<FinanceiroDbContext>().SaveChangesAsync(ct);
        return ConsumeResult.Completed;
    }
}

🧩 Diagrama de arquitetura

Componentes e ligações do TEC.Messaging, gerados pelo GitDiagram a partir da main em 02/11/2026. O diagrama é gerado por IA a partir de uma amostra do código: use-o como mapa de leitura, não como contrato.

flowchart TD

subgraph group_core["Messaging core"]
  node_domain["Domain events"]
  node_contracts["Event contracts"]
  node_envelopes["Message envelopes<br/>[MessageEnvelope.cs]"]
  node_context["Correlation context<br/>[MessageContext.cs]"]
  node_relay["Outbox relay<br/>[OutboxRelay.cs]"]
  node_inbox["Inbox abstraction<br/>[IInboxStore.cs]"]
  node_sanitize["PII sanitizer"]
  node_diagnostics["Diagnostics"]
end

subgraph group_persistence["Persistence adapters"]
  node_sqloutbox[("SQL Server stores")]
  node_sqlinterceptor["SQL Server interceptor"]
  node_pgoutbox[("PostgreSQL stores")]
  node_pginterceptor["PostgreSQL interceptor"]
end

subgraph group_rabbit["RabbitMQ transport"]
  node_rabbitpub["Rabbit publisher"]
  node_rabbitconsumer["Rabbit consumer"]
  node_rabbitadmin["DLQ administration"]
end

subgraph group_azure["Azure transport"]
  node_azurepub["Azure publisher"]
  node_azureconsumer["Azure consumer"]
  node_azureconnection["Azure connection"]
end

subgraph group_aws["AWS transport"]
  node_awspub["AWS publisher"]
  node_awsconsumer["SQS consumer<br/>[AwsSqsConsumer.cs]"]
  node_awsclients["AWS clients"]
end

node_application(("Application"))

node_application -->|"raises events"| node_domain
node_domain -->|"creates envelopes"| node_envelopes
node_contracts -->|"defines metadata"| node_envelopes
node_context -->|"adds correlation"| node_envelopes
node_application -->|"saves events"| node_sqlinterceptor
node_application -->|"saves events"| node_pginterceptor
node_sqlinterceptor -.->|"stores messages"| node_sqloutbox
node_pginterceptor -.->|"stores messages"| node_pgoutbox
node_sqloutbox -->|"provides messages"| node_relay
node_pgoutbox -->|"provides messages"| node_relay
node_relay -->|"publishes via"| node_rabbitpub
node_relay -->|"publishes via"| node_azurepub
node_relay -->|"publishes via"| node_awspub
node_rabbitconsumer -->|"deduplicates with"| node_inbox
node_azureconsumer -.->|"deduplicates with"| node_inbox
node_awsconsumer -.->|"deduplicates with"| node_inbox
node_rabbitconsumer -->|"supports DLQ ops"| node_rabbitadmin
node_azurepub -->|"gets sender"| node_azureconnection
node_azureconsumer -->|"gets client"| node_azureconnection
node_awspub -.->|"uses clients"| node_awsclients
node_awsconsumer -->|"uses clients"| node_awsclients
node_rabbitconsumer -->|"records activity"| node_diagnostics
node_azureconsumer -->|"sanitizes data"| node_sanitize
node_awsconsumer -->|"records activity"| node_diagnostics


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_domain,node_contracts,node_envelopes,node_context,node_relay,node_inbox,node_sanitize,node_diagnostics toneBlue
class node_sqloutbox,node_sqlinterceptor,node_pgoutbox,node_pginterceptor toneAmber
class node_rabbitpub,node_rabbitconsumer,node_rabbitadmin toneMint
class node_azurepub,node_azureconsumer,node_azureconnection toneRose
class node_awspub,node_awsconsumer,node_awsclients,node_application toneIndigo
Loading

📚 Documentação

Arquivo O que responde
📜 Contratos de integração Como nomear e versionar eventos, mapear eventos de domínio, o envelope e o registro com AOT
📤 Outbox Como o evento entra no Outbox, como o relay publica, falhas, Dead e administração
📥 Inbox Como tornar o consumidor idempotente
🗄️ SQL Server Persistência com SQL Server (esquema, índices, UPDLOCK/READPAST, interceptor)
🐘 PostgreSQL Persistência com PostgreSQL (esquema, índices, SKIP LOCKED, RETURNING)
🐇 RabbitMQ Topologia, retry, DLQ, concorrência paralela, pausa e circuit breaker
☁️ Azure Service Bus Publicador e consumidor em tópicos e filas no Azure Service Bus
🟧 AWS SQS / SNS Publicador e consumidor com Amazon SQS e SNS
📡 Telemetria Spans, métricas, logs e correlação
🛡️ Segurança e LGPD Sanitização de PII, segredos no cofre, limites de payload e riscos residuais
🧪 Testes Categorias, testes unitários, de integração, carga e benchmarks
🛠️ Desenvolvimento Build, modo local, lock files e publicação
🔍 Revisão técnica Achados de segurança, bugs e organização (2026-10-19), correções aplicadas e melhorias sugeridas
🏛️ Decisões Arquiteturais (ADRs) Registros formais das decisões de arquitetura e engenharia do TEC.Messaging

Também: 🧰 Samples · ⚙️ CI/CD · READMEs dos pacotes (SqlServer, PostgreSql, RabbitMQ, AzureServiceBus, Aws).


⚡ Compatibilidade

Item Suporte
.NET 10 (LTS)
Native AOT TEC.Messaging e TEC.Messaging.RabbitMQ (contratos com JsonTypeInfo); provedores EF Core e SDKs de nuvem marcam <IsAotCompatible>false</IsAotCompatible>
Bancos de Dados SQL Server 2016+ / Azure SQL (OUTPUT, READPAST) e PostgreSQL 12+ (SKIP LOCKED, RETURNING)
Brokers RabbitMQ 3.13+ e 4.x (filas quorum), Azure Service Bus (Standard/Premium), AWS SQS/SNS

🛡️ Segurança

Sanitização de PII (LGPD) nos erros gravados no Outbox, nos cabeçalhos e motivos de DLQ e nos resumos do relay, credenciais de brokers resolvidas via TEC.Vault, limite de payload configurável (padrão 256 KiB, até 4 MiB) e correlação sanitizada. Detalhes, riscos residuais e checklist em docs/seguranca.md.

🧪 Testes

Unitários sem dependências; integração com SQL Server e RabbitMQ em container (PostgreSQL, Azure Service Bus e AWS têm testes unitários). Detalhes em docs/testes.md.

🤝 Contribuição

PR para a main com o ci-ok verde. Veja docs/desenvolvimento.md.

🏷️ Versionamento

SemVer (em 0.x, mudanças incompatíveis podem ocorrer em versões MINOR); prévias X.Y.Z-preview.N a cada merge. Histórico no Changelog.

📄 Licença

Apache 2.0 · Criado e mantido por Roberto Oliveira, equipe Tudo em Código · github.com/tudoemcodigo

About

TEC.Messaging: mensageria com outbox/inbox (Azure Service Bus, AWS SQS/SNS, RabbitMQ) para .NET 10

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages