Migrando para o Brighter V10 com Configuração do RabbitMQ
Rafael Andrade

Rafael Andrade @actor-dev

About: I'm Rafael the Actor Dev and I like to talk about Actor Models, Brighter, Elixir & Design Patterns Eu me chamo Rafael o Actor Dev e eu gosto de falar sobre Actor Models, Brighter, Elixir & Design Pat

Location:
London, UK
Joined:
Jan 24, 2025

Migrando para o Brighter V10 com Configuração do RabbitMQ

Publish Date: Jul 14
0 0

Em artigos anteriores, abordei integração do Brighter com RabbitMQ e Brighter V10 RC1. Este guia foca na migração para o Brighter V10, destacando mudanças na configuração do RabbitMQ e atualizações que quebram a compatibilidade.

Requisitos

Recapitulação do Brighter

Antes de continuar com a configuração do RabbitMQ, vamos revisar conceitos básicos do Brighter.

Requisição (Comando/Evento)

Defina mensagens usando IRequest:

public class Greeting() : Event(Guid.NewGuid())
{
    public string Name { get; set; } = string.Empty;
}
Enter fullscreen mode Exit fullscreen mode
  • Comandos: Operações para único destinatário (ex: SendEmail)
  • Eventos: Notificações broadcast (ex: OrderShipped)

Mapeador de Mensagem (Opcional)

Traduz entre mensagens do Brighter e objetos do app:

public class GreetingMapper : IAmAMessageMapper<Greeting>
{
    public Message MapToMessage(Greeting request, Publication publication)
    {
        var header = new MessageHeader
        {
            MessageId = request.Id,
            TimeStamp = DateTimeOffset.UtcNow,
            Topic = publication.Topic!,
            MessageType = MessageType.MT_EVENT
        };

        var body = new MessageBody(JsonSerializer.Serialize(request));
        return new Message(header, body);
    }

    public Greeting MapToRequest(Message message)
    {
        return JsonSerializer.Deserialize<Greeting>(message.Body.Bytes)!;
    }

    public IRequestContext? Context { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Mudança no V10: Mapeadores assíncronos agora exigem IAmAMessageMapperAsync

Manipulador de Requisição

Processa mensagens recebidas:

public class GreetingHandler(ILogger<GreetingHandler> logger) : RequestHandler<Greeting>
{
    public override Greeting Handle(Greeting command)
    {
        logger.LogInformation("Olá {Name}", command.Name);
        return base.Handle(command);
    }
}
Enter fullscreen mode Exit fullscreen mode

Configurando Brighter com RabbitMQ

1. Escolha entre Sync vs Async

  • Sync (RMQ.Sync): Usa RabbitMQ.Client V6 (API bloqueante). Adequado para migrações graduais.
  • Async (RMQ.Async): Usa RabbitMQ.Client V7 (API totalmente assíncrona). Recomendado para novos projetos.

Dica: Migre primeiro para o Brighter V10 usando RMQ.Sync antes de adotar o RMQ.Async.

2. Configuração da Conexão

Defina detalhes da conexão com RabbitMQ:

var connection = new RmqMessagingGatewayConnection
{
    AmpqUri = new AmqpUriSpecification(new Uri("amqp://guest:guest@localhost:5672")),
    Exchange = new Exchange("paramore.brighter.exchange"),
};
Enter fullscreen mode Exit fullscreen mode

3. Assinatura no RabbitMQ

Assine uma fila/tópico:

.AddServiceActivator(opt =>
{
    opt.Subscriptions = [
       new RmqSubscription<Greeting>(
           new SubscriptionName("kafka.greeting.subscription"),
           new ChannelName("greeting.queue"),
           new RoutingKey("greeting.topic"),
           makeChannels: OnMissingChannel.Create,
           messagePumpType: MessagePumpType.Reactor
       ),
    ];

    opt.DefaultChannelFactory = new ChannelFactory(new RmqMessageConsumerFactory(connection));
})
Enter fullscreen mode Exit fullscreen mode

4. Configuração do Produtor RabbitMQ

Publique eventos em um tópico:

.UseExternalBus(opt =>
{
    opt.ProducerRegistry = new RmqProducerRegistryFactory(connection, [
       new RmqPublication<Greeting>
       {
           MakeChannels = OnMissingChannel.Create,
           Topic = new RoutingKey("greeting.topic"),
       },
    ]).Create();
});
Enter fullscreen mode Exit fullscreen mode

Mudanças que quebram a compatibilidade no Brighter V10

O Brighter V10 introduz atualizações significativas na integração com RabbitMQ, principalmente devido à adoção do RabbitMQ.Client V6/V7 e melhor separação entre async/sync. Abaixo estão as principais mudanças:

Renomeação de Pacotes

Para alinhar com a versão do RabbitMQ.Client e clarificar uso async/sync:

  • Antigo: Paramore.Brighter.MessagingGateway.RMQ
  • Novo:
    • Paramore.Brighter.MessagingGateway.RMQ.Sync (API sync V6)
    • Paramore.Brighter.MessagingGateway.RMQ.Async (API async V7)

Por quê? O RabbitMQ.Client V7 introduziu mudanças que exigem ajustes no código. A divisão garante compatibilidade explícita e evita surpresas em runtime.

Reestruturação dos Mapeadores de Mensagem

Serialização JSON Padrão:

No V9, mapeadores eram obrigatórios. No V10, a serialização JSON é nativa, exceto quando lógica personalizada é necessária.

Separação de Interfaces

  • IAmAMessageMapper (sync/reactor): Para fluxos síncronos
  • IAmAMessageMapperAsync (async/proactor): Para fluxos assíncronos

Mudanças em IAmAMessageMapper

// V10
IRequestContext? Context { get; set; }
Message MapToMessage(Greeting request, Publication publication);

// V9
Message MapToMessage(Greeting request);
Enter fullscreen mode Exit fullscreen mode

Assinaturas

Tiveram 2 principais mudanças:

Tipos de Message Pump Explícitos

Antes tinhamos runAsync ou isAsync como booleanos. Agora temos messagePumpType do tipo MessagePumpType (Reactor, Proactor, Unknown).

Renomeação de Propriedades

Na AddServiceActivator renomeamos a propriedade ChannelFactory para DefaultChannelFactory

Publicações

Também tiveram 2 principais mudanças:

Reestruturação da Configuração

Removemos IAmAProducerRegistry. Use ExternalBusConfiguration para configurar produtores e padrões de outbox:

// V10
.UseExternalBus(opt => { ... })

// V9
.UseExternalBus(new RmqProducerRegistryFactory(...))
Enter fullscreen mode Exit fullscreen mode

Especificação do Tipo de Requisição

Na Publication, você deve especificar o tipo da requisição ou alterar o IAmAPublicationFinder padrão com UsePublicationFinder:

new RmqPublication<Greeting>
{
    MakeChannels = OnMissingChannel.Create,
    Topic = new RoutingKey("greeting.topic"),
}

// ou
new RmqPublication
{
    MakeChannels = OnMissingChannel.Create,
    Topic = new RoutingKey("greeting.topic"),
    RequestType = typeof(Greeting)
}
Enter fullscreen mode Exit fullscreen mode

Dicas para Migração

  • Comece com RMQ.Sync: Migre primeiro para o Brighter V10 usando RabbitMQ.Client V6 antes de adotar o pacote async V7
  • Revise Mapeadores: Substitua IAmAMessageMapper por IAmAMessageMapperAsync para fluxos assíncronos
  • Valide Assinaturas: Garanta que messagePumpType corresponda aos requisitos async/sync
  • Atualize Publicações: Adicione RequestType em instâncias não genéricas de RmqPublication ou defina um IAmAPublicationFinder

Conclusão

O Brighter V10 simplifica a integração com RabbitMQ com uma separação mais clara entre async/sync e menos boilerplate. Principais etapas incluem:

  • Atualizar pacotes NuGet
  • Refatorar mapeadores para padrões assíncronos

Comments 0 total

    Add comment