package com.magamochi.common.config; import com.magamochi.common.model.enumeration.ContentType; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.QueueBuilder; import org.springframework.amqp.core.TopicExchange; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.support.converter.JacksonJsonMessageConverter; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitConfig { @Value("${queues.manga-ingest}") private String mangaIngestQueue; @Value("${queues.manga-content-ingest}") private String mangaContentIngestQueue; @Value("${queues.manga-content-image-ingest}") private String mangaContentImageIngestQueue; @Value("${queues.provider-page-ingest}") private String providerPageIngestQueue; @Value("${queues.manga-update}") private String mangaUpdateQueue; @Value("${queues.manga-cover-update}") private String mangaCoverUpdateQueue; @Value("${queues.manga-content-image-update}") private String mangaContentImageUpdateQueue; @Value("${queues.image-fetch}") private String imageFetchQueue; @Value("${queues.file-import}") private String fileImportQueue; @Value("${topics.image-updates}") private String imageUpdatesTopic; @Value("${routing-key.image-update}") private String imageUpdateRoutingKey; @Bean public TopicExchange imageUpdatesExchange() { return new TopicExchange(imageUpdatesTopic); } @Bean public Queue imageFetchQueue() { return QueueBuilder.nonDurable(imageFetchQueue) .deadLetterExchange("") .deadLetterRoutingKey(imageFetchQueue + ".dlq") .build(); } @Bean public Queue imageFetchDlq() { return QueueBuilder.nonDurable(imageFetchQueue + ".dlq").build(); } @Bean public Queue mangaUpdateQueue() { return QueueBuilder.nonDurable(mangaUpdateQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaUpdateQueue + ".dlq") .build(); } @Bean public Queue mangaUpdateDlq() { return QueueBuilder.nonDurable(mangaUpdateQueue + ".dlq").build(); } @Bean public Queue mangaContentImageUpdateQueue() { return QueueBuilder.nonDurable(mangaContentImageUpdateQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaContentImageUpdateQueue + ".dlq") .build(); } @Bean public Queue mangaContentImageUpdateDlq() { return QueueBuilder.nonDurable(mangaContentImageUpdateQueue + ".dlq").build(); } @Bean public Queue mangaCoverUpdateQueue() { return QueueBuilder.nonDurable(mangaCoverUpdateQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaCoverUpdateQueue + ".dlq") .build(); } @Bean public Queue mangaCoverUpdateDlq() { return QueueBuilder.nonDurable(mangaCoverUpdateQueue + ".dlq").build(); } @Bean public Queue fileImportQueue() { return QueueBuilder.nonDurable(fileImportQueue) .deadLetterExchange("") .deadLetterRoutingKey(fileImportQueue + ".dlq") .build(); } @Bean public Queue fileImportDlq() { return QueueBuilder.nonDurable(fileImportQueue + ".dlq").build(); } @Bean public Binding bindingMangaCoverUpdateQueue( Queue mangaCoverUpdateQueue, TopicExchange imageUpdatesExchange) { return new Binding( mangaCoverUpdateQueue.getName(), Binding.DestinationType.QUEUE, imageUpdatesExchange.getName(), String.format(imageUpdateRoutingKey + ".%s", ContentType.MANGA_COVER.name().toLowerCase()), null); } @Bean public Binding bindingMangaContentImageUpdateQueue( Queue mangaContentImageUpdateQueue, TopicExchange imageUpdatesExchange) { return new Binding( mangaContentImageUpdateQueue.getName(), Binding.DestinationType.QUEUE, imageUpdatesExchange.getName(), String.format( imageUpdateRoutingKey + ".%s", ContentType.CONTENT_IMAGE.name().toLowerCase()), null); } @Bean public Queue mangaContentIngestQueue() { return QueueBuilder.nonDurable(mangaContentIngestQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaContentIngestQueue + ".dlq") .build(); } @Bean public Queue mangaContentIngestDlq() { return QueueBuilder.nonDurable(mangaContentIngestQueue + ".dlq").build(); } @Bean public Queue mangaContentImageIngestQueue() { return QueueBuilder.nonDurable(mangaContentImageIngestQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaContentImageIngestQueue + ".dlq") .build(); } @Bean public Queue mangaContentImageIngestDlq() { return QueueBuilder.nonDurable(mangaContentImageIngestQueue + ".dlq").build(); } @Bean public Queue mangaIngestQueue() { return QueueBuilder.nonDurable(mangaIngestQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaIngestQueue + ".dlq") .build(); } @Bean public Queue mangaIngestDlq() { return QueueBuilder.nonDurable(mangaIngestQueue + ".dlq").build(); } @Bean public Queue providerPageIngestQueue() { return QueueBuilder.nonDurable(providerPageIngestQueue) .deadLetterExchange("") .deadLetterRoutingKey(providerPageIngestQueue + ".dlq") .build(); } @Bean public Queue providerPageIngestDlq() { return QueueBuilder.nonDurable(providerPageIngestQueue + ".dlq").build(); } // TODO: remove unused queues @Value("${rabbit-mq.queues.manga-chapter-download}") private String mangaChapterDownloadQueue; @Value("${rabbit-mq.queues.manga-follow-update-chapter}") private String mangaFollowUpdateChapterQueue; @Bean public Queue mangaChapterDownloadQueue() { return QueueBuilder.nonDurable(mangaChapterDownloadQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaChapterDownloadQueue + ".dlq") .build(); } @Bean public Queue mangaChapterDownloadDlq() { return QueueBuilder.nonDurable(mangaChapterDownloadQueue + ".dlq").build(); } @Bean public Queue mangaFollowUpdateChapterQueue() { return QueueBuilder.nonDurable(mangaFollowUpdateChapterQueue) .deadLetterExchange("") .deadLetterRoutingKey(mangaFollowUpdateChapterQueue + ".dlq") .build(); } @Bean public Queue mangaFollowUpdateChapterDlq() { return QueueBuilder.nonDurable(mangaFollowUpdateChapterQueue + ".dlq").build(); } @Bean public JacksonJsonMessageConverter messageConverter() { return new JacksonJsonMessageConverter(); } @Bean public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) { var rabbitTemplate = new RabbitTemplate(connectionFactory); rabbitTemplate.setMessageConverter(messageConverter()); return rabbitTemplate; } }