Reveiver projemizin kodlarına da şuradan erişebilirsiniz: https://github.com/ilkgunel/SpringIntegrationRabbitMQReceiver
Şimdi öncelikle Sender uygulamamızı inceleyelim:
Product.java
Product sınıfımız bir üst sınıf görevi üstlenecek. İçerisinde ürün tipini belirten bir type alanı ve fiyatını belirten bir price alanı yer alıyor. Devam eden kısımda da bu alanlara ait get-set metotları yer alıyor.
Book.java
Product sınıfımızı kalıtan Book sınıfımız tip olarak B’yi ve fiyat olarak da 100 değerini kullanacak şekilde yapılandırılıyor.
Product sınıfımızı kalıtan Perfume sınıfımız tip olarak P’yi ve fiyat olarak da 200 değerini kullanacak şekilde yapılandırılıyor.
LineItem.java
LineItem sınıfımız ürünlerimizin siparişi sırasında kullanacağımız bir ara sınıf olacak. İçerisinde ürünü simgeleyecek bir product ve miktarını simgeleyecek qty alanları yer alıyor.
Order.java
Verilecek siparişleri simgelemek için oluşturulmuş Order sınıfımız içerisinde items isminde LineImtem tipinde bir liste ve bir de sipariş id tutuyor.
SenderConfiguration.java
SenderConfiguration sınıfımız uygulamamızın RabbitMQ’ya nasıl mesaj göndereceğini bildiriyor arkadaşlar. topicExchangeName ismi ile tanımlanmış değişkenin değeri RabbitMQ içerisinde bir exchange yani dönüşüm uygulanması için kullanılacak. queueName ismi ile tanımlanmış değişken de mesajların hangi kuyruğa iletileceğini bildiriyor. Bizim uygulamamız ecommExchange adındaki bir exchange üzerinden geçip orders isimindeki bir que’ya gönderilecek. binding(…) metoduna dikkat edersek orders.# şeklinde bir ifade görüyoruz. Bu kısım aslında routingKey anlamına geliyor arkadaşlar. Exchange üzerinde bu key ile que’ya yönlendirme yapılacak. # işareti bildiğimiz gibi number ifade etmek için kullanılıyor. Bu nedenle biz de routingKey orders.1, orders.2 gibi ifadeler kullanacağız.
RabbitMQ’da Publisher konumunda olan birisi bir mesaj gönderdiğinde RabbitMQ içerisindeki Exchange bu mesajı karşılar ve routingKey’e bakarak bunu que’ya gönderir.
Runner.java
Runner sınıfı aslında bu örnek için oluşturduğumuz ve que’ya otomatik veri basması için kullanacağımız bir sınıf. CommandLineRunner’ı kalıtan bu sınıf içerisindeki run metodu uygulama başlatıldığında çalışacak que’ya veri gönderecek.
run(…) metodu içerisinde çeşitli ürünler oluşturulup bu ürünlerle LineItem nesneleri oluşturuluyor ve bu nesneler ile de siparişler oluşturuluyor. Yapılandırıcıdan gelen rabbitTemplate üzerinden convertAndSend(…) metodu çağırılarak da veriler RabbitMQ’ya gönderiliyor. convertAndSend metoduna parametre olarak exchangeName’i, routingKey’i ve sipariş nesnesini geçiyoruz. routingKey gördüğümüz gibi number’lı bir patterne sahip.
SenderApplication.java
SenderApplication sınıfımızın da yaptığı tek iş main metodu üzerinden uygulamayı ayağa kaldırmak.
Sender uygulaması ile işimiz bu kadar, şimdi Receiver uygulamasına bakalım.
RECEIVER APPLICATION
Reveiver uygulamamızda da Product, Book, Perfume, Order ve LineItem sınıfları aynen yer alıyor. Farklı olarak Invoice sınıfımız var.
Invoice.java
Invoice sınıfımız aslında gelen siparişler için faturalama işi yapacağından içerisinde buna ait alanlar tutuyor. Bu alanların nasıl kullandığına ReceiverApplication sınıfında bakacağız.
ReceiverConfiguration.java
ReceiverConfiguration sınıfımız que’yu nasıl dinleyeceğimiz ve mesaj geldiğinde ne yapacağımıza dair tanımlamalarımız yer alıyor.
Receiver uygulamamız bizim Spring Integration’ın özelliklerinden yararlanacağımız bir uygulama olacak. Spring Integration içindeki channels, transformers ve serviceactivators’ı kullanarak burada işimi gerçekleştireceğiz.
Sınıfımız içerisinde bir orderChannel ve bir de invoiceChannel tanımı yapıyoruz. Bu channel’lar bizim que’dan gelen mesajı karşılamada ve fatura hazılarmada kullanacağımız channel’lardır.
container(…) metodu ile tanımladığımız Bean bizim hangi que’yu dinleyeceğimizi tanımladığımız Bean’dir. container.setQueueNames(“orders”); ifadesi ile orders ismindeki que’yu dinlemeisni söylüyoruz.
inbound(…) metodu ile de que’dan mesaj geldiğinde nasıl davranılacağını bildiriyoruz. Metoda parametre olarak geçilen listenerContainer que’yu dinleme görevini üstlenirken orderChannel‘a işaret eden channel ise mesajın iletileceği channel olma görevini üstleniyor.
ReceiverApplication.java
ReceiverApplication sınıfımız uygulamayı başlatacak main metodumuzu barındırıyor ve bunun yanında faturalandırma yapacak metodu da içinde barındırıyor.
Invoice dönüş tipine sahip convertToInvoice(…) metodu @Transformer notasyonu ile işaretli. Bu notasyona bir inputChannel ve bir de outputChannel parametreleri verilmiş. inputChannel ile denmek istenen ilgili channel’a veri girişi olduğunda burasının tetikleneceğidir. outputChannel ile denmek istenen de bu metodun işini bitirip döndürdüğü objenin gönderileceği channel’dır. Bu örneğimizde orderChannel’a veri gönderildiğinde bu metot devreye girecek, işlemler yapıp Invoice tipinde bir obje dönecek ve bu obje de outputChannel olarak tanımlanmış invoiceChannel’a iletilecektir. convertToInvoice metodu içerisinde Sender uygulamasından gelen Order’dan alanlar alınıyor, gelen adete göre vergili ve vergisiz fiyat hesaplaması yapılıyor, akabinde de Invoice objesine koyulup göndeirliyor.
Son olarak handler(…) metodu da bir @ServiceActivator notasyonuna sahip. Burada da yine bir inputChannel tanımı var. @Transformer ile aynı şekilde @ServiceActivator’da da bir channel’a veri geldiğinde tetiklenmesi sağlanabilir. Burada da invoiceChannel’a veri geldiğinde handler(…) metodunun tetiklenmesini sağlıyoruz.Metot içerisinde gelen Invoice objesindeki alanlar konsola yazdırılıyor.
DEMO
Şimdi ilk olarak Sender uygulamasındaki main metodun olduğu sınıf üzerinden uygulamamızı çalıştıralım.
Aşağıdaki gibi 2 metni konsolda görüyoruz:
Sending first order, two Books & three Perfumes
Sending second order, five books & two Perfumes
http://localhost:15672/ adresinden orders que’sunu kontrol ettiğimde kuyrukta 2 adet verinin bekleidğini görüyorum.
Şimdi de Receiver uygulamasını ayağa kaldırıyorum ve konsolu kontrol ediyorum.
Receiver uygulamasının konsolunda da Sender uygulamasından gönderilen ve que’da bekleyen mesajların işlendiğini görüyorum.
Bu yazıda anlatacaklarım da bu kadar arkadaşlar. Başka bir yazıda görüşene kadar sağlıcakla kalın.