package com.intrbiz.bergamot.queue.impl; import java.io.IOException; import java.util.UUID; import com.intrbiz.bergamot.io.BergamotTranscoder; import com.intrbiz.bergamot.model.message.notification.Notification; import com.intrbiz.bergamot.queue.NotificationQueue; import com.intrbiz.bergamot.queue.key.NotificationKey; import com.intrbiz.gerald.source.IntelligenceSource; import com.intrbiz.gerald.witchcraft.Witchcraft; import com.intrbiz.queue.Consumer; import com.intrbiz.queue.DeliveryHandler; import com.intrbiz.queue.QueueBrokerPool; import com.intrbiz.queue.QueueManager; import com.intrbiz.queue.RoutedProducer; import com.intrbiz.queue.rabbit.RabbitConsumer; import com.intrbiz.queue.rabbit.RabbitProducer; import com.rabbitmq.client.Channel; public class RabbitNotificationQueue extends NotificationQueue { public static final void register() { QueueManager.getInstance().registerQueueAdapter(NotificationQueue.class, RabbitNotificationQueue::new); } private final BergamotTranscoder transcoder = new BergamotTranscoder(); private final QueueBrokerPool<Channel> broker; private final IntelligenceSource source = Witchcraft.get().source("com.intrbiz.bergamot.queue"); @SuppressWarnings("unchecked") public RabbitNotificationQueue(QueueBrokerPool<?> broker) { this.broker = (QueueBrokerPool<Channel>) broker; } public String getName() { return "notification-queue"; } @Override public RoutedProducer<Notification, NotificationKey> publishNotifications(NotificationKey defaultKey) { return new RabbitProducer<Notification, NotificationKey>(this.broker, this.transcoder.asQueueEventTranscoder(Notification.class), defaultKey, this.source.getRegistry().timer("publish-notifications")) { protected String setupExchange(Channel on) throws IOException { // exchange on.exchangeDeclare("bergamot.notification", "topic", true); on.exchangeDeclare("bergamot.retry_notification", "topic", true); // the queue to hold delayed messages on.queueDeclare("bergamot.notification.delayed", true, false, false, args(args("x-dead-letter-exchange", "bergamot.notification"), "x-message-ttl", 300_000)); on.queueBind("bergamot.notification.delayed", "bergamot.retry_notification", "#"); return "bergamot.notification"; } }; } @Override public Consumer<Notification, NotificationKey> consumeNotifications(DeliveryHandler<Notification> handler, UUID site, String engineName) { return new RabbitConsumer<Notification, NotificationKey>(this.broker, this.transcoder.asQueueEventTranscoder(Notification.class), handler, this.source.getRegistry().timer("consume-notifications"), 1, false) { public String setupQueue(Channel on) throws IOException { // exchange on.exchangeDeclare("bergamot.notification", "topic", true); on.exchangeDeclare("bergamot.retry_notification", "topic", true); // the queue to hold delayed messages on.queueDeclare("bergamot.notification.delayed", true, false, false, args(args("x-dead-letter-exchange", "bergamot.notification"), "x-message-ttl", 300_000)); on.queueBind("bergamot.notification.delayed", "bergamot.retry_notification", "#"); // queue String queueName = "bergamot.notification." + (site == null ? "default" : site.toString()) + "." + engineName; // dead messages go to the retry exchange on.queueDeclare(queueName, true, false, false, args("x-dead-letter-exchange", "bergamot.retry_notification")); on.queueBind(queueName, "bergamot.notification", site == null ? "#" : site.toString()); return queueName; } }; } @Override public Consumer<Notification, NotificationKey> consumeNotifications(DeliveryHandler<Notification> handler, UUID site) { return new RabbitConsumer<Notification, NotificationKey>(this.broker, this.transcoder.asQueueEventTranscoder(Notification.class), handler, this.source.getRegistry().timer("consume-notifications"), 1, false) { public String setupQueue(Channel on) throws IOException { // exchange on.exchangeDeclare("bergamot.notification", "topic", true); // queue String queueName = on.queueDeclare().getQueue(); // bind using the site on.queueBind(queueName, "bergamot.notification", site == null ? "#" : site.toString()); return queueName; } }; } @Override public void close() { } }