Saltar al contenido principal

Implementações de Integradores

O framework de integrações permite criar soluções robustas e escaláveis para conectar sistemas de forma consistente. Cada integrador encapsula a lógica de coleta, transformação e envio de dados, garantindo que o processo seja confiável, monitorado e fácil de manter.

Entre os principais benefícios para o desenvolvedor:

  • Isolamento de operações: cada execução ocorre de forma independente, evitando efeitos colaterais entre execuções.
  • Paralelismo e concorrência automática: o framework gerencia múltiplas execuções simultâneas, respeitando limites de concorrência configuráveis.
  • Integração completa com o .NET DI: você tem acesso a todos os serviços registrados, como clientes HTTP, repositórios, loggers, etc., sem precisar instanciar manualmente.
  • Execução periódica ou baseada em eventos: escolha entre polling para consultas periódicas ou processamento reativo a mensagens.
  • Métricas e tratamento de erros prontos: logging, contadores e monitoramento integrados, sem configuração adicional.
info

A estrutura do integrador ajuda a manter o código limpo e organizado, separando responsabilidades de forma clara: Query para buscar dados, Parse para transformá-los e Send para processar ou enviar. Isso torna o desenvolvimento mais seguro, testável e performático.


Integrações por Pooling

Implementação para integrações baseadas em polling, executadas periodicamente.

Exemplo de Integrador

Abaixo, um integrador baseado em polling que consulta uma API externa, transforma os dados e envia para outro sistema:

B1PoolingIntegrator.cs
public class B1PoolingIntegrator(ICustomerService customerService) : PoolingIntegrator<CustomerDto, CustomerProcessed>
{
protected override async Task<CustomerDto> Query()
{
// Consulta a API externa e retorna os dados
var customers = await customerService.getCustomers();
return customers.FirstOrDefault();
}

protected override async Task<CustomerProcessed> Parse(CustomerDto data)
{
// Transforma os dados brutos no formato necessário
return new CustomerProcessed
{
Id = data.Id,
Name = data.FullName.ToUpper(),
Email = data.Email.ToLower()
};
}

protected override async Task<CustomerProcessed> Send(CustomerProcessed parsedData)
{
// Envia os dados processados para outro sistema
await ExternalSystemClient.SendCustomerAsync(parsedData);
return parsedData;
}
}

Assinatura

public abstract class PoolingIntegrator<TInput, TOutput> : BaseIntegrator<TInput, TOutput>

Método de Execução

public Task<IntegrationResult<TOutput>> Execute()

Executa o integrador seguindo o fluxo: Query → Parse → Send.

Métodos Abstratos Obrigatórios

MétodoDescrição
Query()Obter os dados que serão processados (TInput). Ex.: consultar API, banco de dados ou arquivos.
Parse(TInput data)Transformar os dados de entrada no formato necessário (TOutput).
Send(TOutput parsedData)Enviar, processar ou persistir os dados transformados.

Integrações por messageria

Implementação para integrações baseadas em mensagens, disparadas por eventos ou filas.

Exemplo de Integrador

Abaixo, um integrador baseado em polling que consulta uma API externa, transforma os dados e envia para outro sistema:

B1MessageProcessorIntegrator
public class B1PoolingIntegrator(ICustomerService customerService) : MessageProcessorIntegrator<MessageDto, CustomerDto, CustomerProcessed>
{
protected override async Task<CustomerDto> Query(MessageDto message)
{
// Consulta a API externa e retorna os dados
var customer = await customerService.getCustomer(message.customer);
return customer;
}

protected override async Task<CustomerProcessed> Parse(CustomerDto data)
{
// Transforma os dados brutos no formato necessário
return new CustomerProcessed
{
Id = data.Id,
Name = data.FullName.ToUpper(),
Email = data.Email.ToLower()
};
}

protected override async Task<CustomerProcessed> Send(CustomerProcessed parsedData)
{
// Envia os dados processados para outro sistema
await ExternalSystemClient.SendCustomerAsync(parsedData);
return parsedData;
}
}

Assinatura

public abstract class MessageProcessorIntegrator<TMessage, TInput, TOutput> : BaseIntegrator<TInput, TOutput>

Método de Execução

public Task<IntegrationResult<TOutput>> Execute(TMessage message)

Executa a integração baseada em uma mensagem específica, seguindo o mesmo fluxo: Query → Parse → Send.

Métodos Abstratos Obrigatórios

MétodoDescrição
Query(TMessage message)Obter os dados usando informações da mensagem (TInput).
Parse(TInput data)Transformar os dados de entrada no formato necessário (TOutput).
Send(TOutput parsedData)Enviar, processar ou persistir os dados transformados.

Comparação das Implementações

CaracterísticaPoolingIntegratorMessageProcessorIntegrator
Modelo de ExecuçãoPolling / Consulta periódicaBaseado em mensagens / eventos
Método ExecuteExecute()Execute(TMessage message)
QuerySem parâmetrosRecebe message como parâmetro
Uso TípicoSincronização periódica, jobs agendadosProcessamento de eventos, filas de mensagens

Funcionalidades Herdadas do BaseIntegrator

  • ✅ Métricas automáticas (tempo, contadores, throughput)
  • ✅ Tratamento centralizado de erros
  • ✅ Hooks de execução: PreExecution, PostExecution, OnError
  • ✅ Validações automáticas: ValidateQuery, ValidateParse
  • ✅ Retorno padronizado com IntegrationResult<TOutput>

Boas Práticas

  1. Query e Parse: mantenha simples e focado, evitando lógica complexa dentro de Query.
  2. Send: trate apenas persistência ou envio; não faça transformações aqui.
  3. Escolha da implementação:
    • Polling → quando precisa executar periodicamente
    • MessageProcessor → quando cada execução é disparada por evento/mensagem
  4. Métricas e monitoramento: não é necessário implementar manualmente; já é automático.
Portanto

Com este padrão, o fluxo Query → Parse → Send fica claro e consistente, independente do tipo de integração.