Apache Camel - Hızlı Kılavuz
Şehrinizdeki Hindistan'daki Bigbasket gibi büyük bir çevrimiçi marketin sizi onlar için bir BT çözümü tasarlamaya davet ettiği bir durumu düşünün. Kararlı ve ölçeklenebilir çözüm, bugün karşılaştıkları yazılım bakım sorunlarının üstesinden gelmelerine yardımcı olacaktır. Bu çevrimiçi mağaza, son on yıldır işini yürütüyor. Mağaza, müşterilerinden farklı ürün kategorileri için çevrimiçi siparişleri kabul eder ve bunları ilgili tedarikçilere dağıtır. Örneğin, sabun, yağ ve süt sipariş ettiğinizi varsayalım; bu üç ürün ilgili üç tedarikçiye dağıtılacaktır. Üç tedarikçi daha sonra malzemelerini, tüm siparişin teslimat merkezi tarafından yerine getirileceği ortak bir dağıtım noktasına gönderecek. Şimdi bugün karşı karşıya oldukları soruna bakalım.
Bu mağaza faaliyete geçtiğinde, siparişleri virgülle ayrılmış bir düz metin dosyasında kabul ediyordu. Mağaza, bir süre içinde mesaja dayalı sipariş yerleştirmeye geçti. Daha sonra, bazı yazılım geliştiricileri XML tabanlı bir sipariş yerleştirme önerdi. Sonunda, mağaza bir web hizmeti arayüzünü bile uyarladı. Şimdi, işte asıl sorun geliyor. Siparişler artık farklı formatlarda geliyor. Açıkçası, şirket sipariş kabul formatını her yükselttiğinde, müşterinin kafasında karışıklıklara neden olmamak için önceden konuşlandırılan arayüzü kırmak istemiyordu.
Aynı zamanda, iş büyümeye devam ederken mağaza, repertuarına periyodik olarak yeni tedarikçiler ekledi. Bu tür her tedarikçinin siparişleri kabul etmek için kendi protokolü vardı. Bir kez daha entegrasyon sorunuyla karşı karşıyayız; Uygulama mimarimiz, benzersiz sipariş verme mekanizmalarına sahip yeni tedarikçileri barındıracak şekilde ölçeklenebilir olmalıdır.
Durumun tamamı aşağıdaki şekilde gösterilmektedir -
Şimdi, Apache Camel'in açıklanan senaryo için zarif, bakımı yapılabilir, ölçeklenebilir bir çözüm mimarisi sağlamak için nasıl kurtarmanıza gelebileceğini görelim.
Çözüme geçmeden önce küçük bir varsayım yapmamız gerekiyor. Bu eğitimdeki tüm tartışmalar için, çevrimiçi siparişlerin XML biçiminde verildiğini varsayacağız. Tartışmalarımız boyunca kullanacağımız sipariş dosyası için tipik bir format burada gösterilmektedir -
<?xml version = "1.0" encoding = "UTF-8"?>
<OrderID Order = "001">
<order product = "soaps">
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
</order>
<order product = "Oil">
<items>
<item>
<Brand>Saffola</Brand>
<Type>Gold</Type>
<Quantity>2</Quantity>
<Price>649</Price>
</item>
<item>
<Brand>Fortune</Brand>
<Type>Sunlite</Type>
<Quantity>1</Quantity>
<Price>525</Price>
</item>
</items>
</order>
<order product = "Milk">
<items>
<item>
<Product>Milk</Product>
<Brand>Amul</Brand>
<Type>Pure</Type>
<Quantity>2</Quantity>
<Price>60</Price>
</item>
</items>
</order>
</OrderID>
Bu eğiticide Camel örneklerini göstermek için yukarıdaki XML şablonunu kullanacağız.
Deve, bir uç noktadan gelen mesajları alan ve başka birine gönderen kara bir kutudur. Kara kutu içinde mesajlar işlenebilir veya basitçe yeniden yönlendirilebilir.
Öyleyse neden bunun için bir çerçeve var? Giriş vaka çalışmasında görüldüğü gibi pratik durumlarda, çok sayıda gönderici ve her biri ftp, http ve jms gibi kendi protokollerini izleyen birçok alıcı olabilir. Sistem, A göndereninden gelen mesajın yalnızca B & C'ye iletilmesi gibi birçok karmaşık kuralı gerektirebilir. Durumlarda, mesajı alıcının beklediği başka bir formata çevirmeniz gerekebilir. Bu çeviri, mesaj içeriğine bağlı olarak belirli koşullara tabi olabilir. Bu nedenle, esasen protokoller arasında çeviri yapmanız, bileşenleri birbirine yapıştırmanız, yönlendirme kurallarını tanımlamanız ve mesaj içeriklerine göre filtreleme sağlamanız gerekebilir. Bu, aşağıdaki şekilde gösterilmektedir -
Yukarıdaki gereksinimleri karşılamak ve bu tür birçok durum için uygun bir yazılım mimarisi tasarlamak amacıyla, Enterprise Integration Patterns ( EIP ) 2003 yılında Gregor Hohpe ve Bobby Woolf tarafından belgelenmiştir. Apache Camel bu modellerin uygulanmasını sağlar ve bu eğitimin amacı öğretmektir. Giriş bölümünde anlatılana benzer durumlarda Camel'ı nasıl kullanacağınızı öğreneceksiniz.
Apache Camel, açık kaynaklı bir çerçevedir. Kural tabanlı yönlendirme ve uyumlulaştırma motoru sağlayan mesaj odaklı bir ara yazılımdır. "Süt" siparişi olup olmadığı gibi kuralları bir süt satıcısına, bir "yağ" siparişi ise bir petrol satıcısına yönlendirmek gibi kurallar tanımlayabilirsiniz. Camel'i kullanarak bu kuralları uygulayabilir ve yönlendirmeyi tanıdık bir Java kodunda yapabilirsiniz. Bu, tür güvenli bir ortamda bu kuralları tanımlamak için tanıdık Java IDE'nizi kullanabileceğiniz anlamına gelir. Genellikle hantal olma eğiliminde olan XML yapılandırma dosyalarını kullanmamıza gerek yoktur. Kuralları yapılandırmak için XML kullanmayı tercih ederseniz Camel, Spring çerçevesi aracılığıyla XML yapılandırmasını destekler. Bir Scala aşığıysanız, Blueprint XML Yapılandırma dosyalarını ve hatta bir Scala DSL bile kullanabilirsiniz. Ayrıca, kuralları yapılandırmak için favori Java'nızı, Scala IDE'nizi veya hatta basit bir XML düzenleyiciyi kullanabileceğiniz anlamına gelir.
Bu motorun girdisi virgülle ayrılmış bir metin dosyası olabilir, bir POJO (Düz Eski Java Nesnesi), XML Camel tarafından desteklenen diğer birkaç biçimden herhangi biridir. Benzer şekilde, ilgili satıcılara gönderilen siparişleri görüntülemeniz için motorun çıktısı bir dosyaya, bir mesaj kuyruğuna veya hatta monitör ekranınıza yeniden yönlendirilebilir. Bunlar uç noktalar olarak adlandırılır ve Camel, Mesaj Uç Noktası EIP modelini destekler . Deve uç noktaları daha sonra Uç Noktalar bölümünde ele alınmaktadır.
Camel, hizmet odaklı mimarileri uygulamak için genellikle Apache ServiceMix , Apache ActiveMQ ve Apache CXF ile birlikte kullanılır .
Apache Camel'in bir özetini gördükten sonra, şimdi ne sunduğunu görmek için özelliklerini inceleyelim. Apache Camel'in temelde çeşitli EIP'lerin uygulamasını sağlayan açık kaynaklı bir Java çerçevesi olduğunu zaten biliyoruz. Camel, çok çeşitli aktarımlara ve API'lere bağlantı sağlayarak entegrasyonu kolaylaştırır. Örneğin, JMS'yi JSON'a, JSON'dan JMS'ye, HTTP'den JMS'ye, FTP'den JMS'ye, hatta HTTP'den HTTP'ye ve Mikro Hizmetlere bağlanabilirliği kolayca yönlendirebilirsiniz. Her iki uçta da uygun uç noktaları sağlamanız yeterlidir. Camel genişletilebilir ve bu nedenle gelecekte çerçeveye kolayca daha fazla uç nokta eklenebilir.
EIP'leri ve aktarımları birbirine bağlamak için Java, Scala ve Groovy gibi Etki Alanına Özgü Diller (DSL'ler) kullanırsınız. Tipik bir Java yönlendirme kuralı şöyle görünebilir:
from ("file:/order").to("jms:orderQueue");
Bu yönlendirme kuralı, dosyaları şuradan yükler: order dizin, dosyanın içeriğiyle bir JMS mesajı oluşturur ve bu mesajı, dosya adı verilen bir kuyruğa gönderir. orderQueue.
İşte Camel uygulamalarının geliştirilmesinde faydalı bulacağınız en önemli özelliklerden bazıları:
Camel , bu tür mesaj dönüşümleri için takılabilir veri formatlarını ve tür dönüştürücüleri destekler , böylece gelecekte yeni formatlar ve dönüştürücüler eklenebilir. Şu anda, birkaç popüler biçimi ve dönüştürücüyü desteklemektedir; CSV, EDI, JAXB, JSON, XmlBeans, XStream, Flatpack, Zip.
Camel, DSL'de tahminler yazmak için takılabilir dilleri destekler . Desteklenen dillerden bazıları JavaScript, Groovy, Python, PHP, Ruby, SQL, XPath, XQuery'dir.
Camel, Javabeans'ı çeşitli noktalarda takabilmeniz için POJO modelini destekler.
Camel, mesajlaşma kullanarak bu kadar büyük dağıtılmış ve asenkron sistemlerin test edilmesini kolaylaştırır.
Şimdi Camel'in mimarisini anlayalım ve çeşitli özelliklerin nasıl uygulandığını görelim.
Camel mimarisi üç bileşenden oluşur - Entegrasyon Motoru ve Yönlendirici, İşlemciler ve Bileşenler. Bu, aşağıdaki şekilde gösterilmektedir -
Deve çekirdeğinin kendisi çok küçüktür ve 13 temel bileşen içerir. Geri kalan 80+ bileşen çekirdeğin dışında. Bu, dağıtıldığı yere düşük bir bağımlılığın korunmasına yardımcı olur ve gelecekte uzantıları teşvik eder. Components modül bir Endpointdış dünyaya arayüz. Uç noktalar, URI'ler tarafından belirtilir, örneğinfile:/order ve jms:orderQueue son bölümde gördüğünüz.
Processorsmodülü, Uç Noktalar arasındaki mesajları işlemek ve aracılık etmek için kullanılır. Daha önce bahsettiğim EIP'ler bu modülde uygulanmaktadır. Şu anda EIP kitabında ve diğer kullanışlı işleme birimlerinde belgelendiği gibi 40'tan fazla kalıbı desteklemektedir .
Processors ve Endpoints birbirine bağlı Integration Engine and RouterDSL'leri kullanan modül. Bunları bağlarken, mesajları kullanıcı tanımlı kriterlere göre filtrelemek için filtreler kullanabilirsiniz. Daha önce de belirtildiği gibi, bu kuralları yazarken birkaç seçeneğiniz vardır. Bunun için Java, Scala, Groovy ve hatta XML kullanabilirsiniz.
Şimdi, Camel'in çekirdek olarak düşünülebilecek en önemli bileşenine geliyoruz - CamelContext.
CamelContext aşağıdaki şekilde gösterildiği gibi Camel'deki diğer tüm hizmetlere erişim sağlar -
Çeşitli hizmetlere bakalım. Registrymodülü varsayılan olarak, uygulamanızın kullandığı çeşitli Javabian'ların adını tutan bir JNDI kayıt defteridir. İlkbahar ile Deve kullanırsanız, bu Bahar olacaktır.ApplicationContext. Camel'i OSGI kapsayıcısında kullanırsanız, buOSGI registry. Type convertersAdından da anlaşılacağı gibi, girişinizi bir formattan diğerine dönüştüren çeşitli yüklü tip dönüştürücüler içerir. Yerleşik tip dönüştürücüleri kullanabilir veya kendi dönüştürme mekanizmanızı sağlayabilirsiniz. Componentsmodülü, uygulamanız tarafından kullanılan bileşenleri içerir. Bileşenler, otomatik keşif ile yüklenir.classpathbelirttiğiniz. OSGI kapsayıcısı durumunda, bunlar yeni bir paket etkinleştirildiğinde yüklenir. Zaten tartıştıkEndpoints ve Routesönceki bölümlerde. Data formats modül, yüklenen veri formatlarını ve son olarak Languages modül yüklenen dilleri temsil eder.
Buradaki kod parçacığı size bir CamelContext bir Camel uygulamasında oluşturulur -
CamelContext context = new DefaultCamelContext();
try {
context.addRoutes(new RouteBuilder() {
// Configure filters and routes
}
}
);
DefaultCamelContext sınıf somut bir uygulama sağlar CamelContext. İçindeaddRoutes yöntem, anonim bir örnek oluşturuyoruz RouteBuilder. Birden fazla oluşturabilirsinizRouteBuilderbirden fazla yönlendirme tanımlamak için örnekler. Aynı bağlamdaki her yolun benzersiz bir kimliği olmalıdır. Rotalar, çalışma zamanında dinamik olarak eklenebilir. Önceden tanımlananla aynı kimliğe sahip bir yol, eski rotanın yerini alacaktır.
İçinde ne var RouteBuilder örnek aşağıda açıklanmaktadır.
Rotalar
Yönlendirici, mesajı taşımak için kuralı tanımlar from bir toyer. KullanRouteBuilderJava DSL'de bir rota tanımlamak için. Yerleşik rotayı genişleterek bir rota oluşturursunuz.RouteBuildersınıf. Rota birfromuç nokta ve bir veya daha fazla uç noktada biter. İkisinin arasında, işleme mantığını uygularsınız. Tek bir yol içinde istediğiniz sayıda yolu yapılandırabilirsiniz.configure yöntem.
İşte rotanın nasıl oluşturulduğuna dair tipik bir örnek -
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.to("stream:out");
}
}
Yapılandırma yöntemini geçersiz kılıyoruz RouteBuildersınıflayın ve içindeki yönlendirme ve filtreleme mekanizmamızı uygulayın. Mevcut durumda, Endpoint'ten alınan girdiyi yeniden yönlendiriyoruz.DistributeOrderDSL Endpoint tarafından belirtilen konsola stream:out.
Dil Seçimi
Rotaları farklı dillerde oluşturabilirsiniz. İşte aynı rotanın üç farklı dilde nasıl tanımlandığına dair birkaç örnek:
Java DSL
from ("file:/order").to("jms:orderQueue");
Bahar DSL
<route>
<from uri = "file:/order"/>
<to uri = "jms:orderQueue"/>
</route>
Scala DSL
from "file:/order" -> "jms:orderQueue"
Filtreler
Giriş içeriğinin bir bölümünü seçmek için filtre kullanırsınız. Bir filtre oluşturmak için herhangi bir rastgele Predicate uygulamasını kullanırsınız. Filtrelenen giriş daha sonra istediğiniz hedef Uç Noktaya gönderilir. Bu örnekte, sabun tedarikçisine toplu olarak gönderilebilmesi için tüm sabun siparişlerini filtreliyoruz.
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product = 'soaps']/items"))
.to("stream:out");
Örnekte kullandık xpathfiltreleme için yüklem. Filtreleme için Java sınıfını kullanmayı tercih ederseniz, aşağıdaki kodu kullanın -
from("direct:DistributeOrderDSL")
.filter()
.method(new Order(),"filter")
.to("stream:out");
Order kendi filtreleme mekanizmanıza sahip özel Java sınıfınızdır.
Burada olduğu gibi, tek bir rotada birden fazla tahmini birleştirebilirsiniz -
from("direct:DistributeOrderDSL")
.choice()
.when(header("order").isEqualTo("oil"))
.to("direct:oil")
.when(header("order").isEqualTo("milk"))
.to("direct:milk")
.otherwise()
.to("direct:d");
Yani artık tüm “petrol” siparişleri petrol satıcısına, “süt” siparişleri süt satıcısına ve geri kalanı ortak havuza gidecek.
Özel İşlemci
Ayrıca özel işleme de kullanabilirsiniz. Aşağıdaki örnek, adında özel bir işlemci oluştururmyCustomProcessor ve bunu rota oluşturucuda kullanır.
Processor myCustomProcessor = new Processor() {
public void process(Exchange exchange) {
// implement your custom processing
}
};
RouteBuilder builder = new RouteBuilder() {
public void configure() {
from("direct:DistributeOrderDSL")
.process(myProcessor);
}
};
Uyumlulaştırma ve yönlendirmeniz üzerinde daha iyi bir kontrol elde etmek için seçim ve filtreleme ile birlikte özel işlemcileri kullanabilirsiniz -
from("direct:DistributeOrderDSL")
.filter(header("order").isEqualTo("milk"))
.process(myProcessor);
XML kullanma
Tercih ederseniz, rotalar daha hacimli XML olarak tanımlanabilir. Aşağıdaki XML parçacığı, Spring XML aracılığıyla bazı filtrelemeyle birlikte bir yolun nasıl oluşturulacağını gösterir -
<camelContext xmlns = "http://camel.apache.org/schema/spring">
<route>
<from uri = "direct:DistributeOrderXML"/>
<log message = "Split by Distribute Order"/>
<split>
<xpath>//order[@product = 'Oil']/items</xpath>
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
</split>
</route>
</camelContext>
Rotaların nasıl inşa edildiğini gördükten sonra, şimdi Uç Noktalar oluşturmanın çeşitli tekniklerini göreceğiz.
Entegrasyon kodumuzda uç noktaların nasıl göründüğünü öğrendik. Şimdiye kadar kullandığımız ifadelerfile:/order, jms:orderQueue, direct:distributeOrderDSLuç noktalardır. Gördüğünüz gibi, URI spesifikasyon formatlarını takip ediyorlar. Bu URI'yi değerlendirirken,CamelContext yaratır Endpointörnek; örnekleme konusunda endişelenmenize gerek yokEndpoint DSL'inizde uygulama.
Önceki örneklerimizi alarak, burada olduğu gibi Java DSL'de uç noktaları belirtirsiniz -
from ("file:/order").to("jms:orderQueue");
Ve burada olduğu gibi baharda -
<route>
<from uri = "file:/order"/>
<to uri = "jms:orderQueue"/>
</route>
Her iki durumda da uç nokta sabit bir dizedir. Bazı durumlarda, bu dizeyi çalışma zamanında oluşturmak isteyebilirsiniz. Bunu Java kullanarak yapabilirsinizStringbiçimlendirici yöntemleri. Camel, bu URI dizelerini çalışma zamanında oluşturmak için başka bir basit yaklaşım sağlar. Bu amaçla Camel,fromF ve toFKullanıcı tanımlı parametrelerle bağımsız değişkenleri kabul eden yöntemler. Aşağıdaki ifade,toF yöntem -
from("direct:distributeOrderDSL”).toF("file://%s?fileName=%s", path, name);
Bu yöntemler nedeniyle, yerleşik Java kullanma ihtiyacı String formatlayıcı yöntemleri ortadan kaldırılır.
Camel , uç nokta ifadesini hesaplamak için varsayılan olarak Basit dil kullanır . Simple dil öncelikle değerlendirmek için tasarlandı Expressions ve Predicateskarmaşıklıkları hakkında fazla uğraşmadan XPath. Tahminleri değerlendirmek için, aşağıdaki gibi başka bir dili birleştirebilirsiniz:xpath varsayılan ile Simpledil. Bu, diğer dili ayırmak için artı işareti kullanılarak yapılır. Buradaki kod parçacığı, nasıl birleştirileceğini gösterirxpath yazılan ifadeye dize Simple.
from("direct:start")
.toD("jms:${orderQueue}+language:xpath:/order/@id");
İçinde Spring, burada olduğu gibi aynı şeyi başarabilirsiniz -
<route>
<from uri = "direct:start"/>
<toD uri = "jms:${orderQueue}+language:xpath:/order/@id"/>
</route>
Her biri bir öncekinden artı işaretiyle ayrılmış, istediğiniz kadar dili birleştirebilirsiniz. Desteklenen dillerin listesi burada bulunabilir .
Camel, önceden oluşturulmuş birkaç bileşen sağlar.
Bu bölümde, birkaç önemli bileşeni tartışacağız. camel-core modül.
Fasulye
Beanbileşeni, fasulyeleri Camel mesaj alışverişlerine bağlar. Bir Uç Nokta oluşturmak için URI şu şekilde belirtilir:bean:beanID, nerede beanID fasulyenin adıdır. Registry.
JndiContext jndiContext = new JndiContext();
jndiContext.bind("MilkOrder", new MilkOrderProcessor());
CamelContext camelContext = new DefaultCamelContext(jndiContext);
camelContext.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:bigBasket")
.to("bean:MilkOrder?method=placeOrder");
}
});
Uç noktanın nasıl belirtildiğine dikkat edin. bean:protokol. İsteğe bağlı olarak çağrılacak fasulye yöntemini belirtebilirsiniz; bu durumda yöntem denirplaceOrderEndpoint ifadesi değerlendirilirken çağrılacaktır. MilkOrder JNDI adıdır MilkOrderProcessorKod pasajının ilk iki satırında kayıtlı Javabean. TanımıMilkOrderProcessor kısalık için burada kendisi ihmal edilmiştir.
Doğrudan
Kullanımını fark etmiş olmalısın Directönceki örneklerimizde. Bir petrol satıcısına sipariş göndermek içindirect:oilEndpoint spesifikasyonunda. KullanımıDirectbileşeni, bir uç noktayı eşzamanlı olarak çağırmanıza izin verir. Önceki örneklerimizden aşağıdaki iki kod parçacığı,Direct -
.when(header("order").isEqualTo("oil"))
.to("direct:oil")
Ve,
from("direct:DistributeOrderDSL")
.process(myProcessor);
Dosya
Filebileşeni, makinenizdeki dosya sistemine erişim sağlar. Bu bileşeni kullanarak, diğer bileşenlerden gelen mesajları yerel bir diske kaydedebileceksiniz. Ek olarak, diğer Camel bileşenlerinin yerel dosyaları işlemesine izin verir. Ya kullanabilirsinizfile:directoryName[?options] veya file://directoryName[?options]Dosya bileşenini kullanırken bir URI biçimi olarak. Bu bileşenin kullanımını daha önce gördünüz -
from ("file:/order").to("jms:orderQueue");
Unutmayın ki Filebileşen varsayılan olarak dizin adını alır. Bu nedenle, sipariş dizininin içeriği girdi içeriği olarak alınacaktır. İçindeki belirli bir dosyayı belirtmek içinorder dizin, aşağıdaki ifadeyi kullanacaksınız -
from ("file:/order?fileName = order.xml").to("jms:orderQueue");
Günlük
Logbileşeni, iletileri temeldeki günlük kaydı mekanizmasına kaydetmenize olanak tanır. Camel, çeşitli günlükleme çerçevelerine bir soyutlama olarak Java için Basit Günlük Kaydı Cephesi'ni (SLF4J) kullanır. Kullanabilirsinjava.util.logging, logback, log4jgünlüğü için. Bu kod parçacığı,Log bileşen -
from("direct:DistributeOrderDSL")
.to("bean:MilkOrder?method = placeOrder")
.to("log:com.example.com?level = INFO&showBody = true");
SEDA
SEDA bileşeni, aynı anda başka bir uç noktayı eşzamansız olarak çağırmanıza olanak tanır CamelContext. CamelContext örneklerinde arama yapmak istiyorsanız, şunu kullanmanız gerekir:VMbileşen. SEDA'nın kullanımı burada gösterilmektedir -
from("direct:DistributeOrderDSL")
// send it to the seda queue that is async
.to("seda:nextOrder")
Bu rotada, siparişleri yalnızca nextOrderzaman uyumsuz kuyruk. Bu kuyruğa abone olan bir müşteri bu kuyruktaki mesajları alacaktır.
Zamanlayıcı
Timerbileşeni, düzenli aralıklarla mesaj göndermek için kullanılır ve bu nedenle Camel uygulamalarını test ederken çok yararlı olabilir. Buradaki kod parçacığı, her iki saniyede bir konsola bir test mesajı gönderir -
from("timer://testTimer?period = 2000")
.setBody()
.simple("This is a test message ${header.timer}")
.to("stream:out");
Entegrasyon projelerinin çoğu, gevşek bağlı uygulama mimarisi oluşturmaya yardımcı olduğu için mesajlaşma kullanır. Mesajlaşma eşzamanlı veya eşzamansız olabilir. JMS her ikisini de desteklerpoint-to-point ve publish-subscribemodeller. KullanıyorsunQueue noktadan noktaya ve Topicbir yayınlama-abone olma modeli için. Bir Java platformunda, JMS - Java Messaging Service, bir mesajlaşma sunucusuna bir arabirim sağlar. Apache activeMQ böyle bir açık kaynak JMS sağlayıcısıdır. Camel, bir JMS sağlayıcısı ile birlikte gönderilmez; ancak, activeMQ kullanacak şekilde yapılandırılabilir. Bu bileşeni kullanmak için, projenize şu kavanozları eklemeniz gerekir - activemq, camel-spring ve camel-jms.
Aşağıdaki kod parçacığı, Camel'in activeMQ için nasıl yapılandırılacağını gösterir.
<bean id = "jms" class = "org.apache.camel.component.jms.JmsComponent">
<property name = "connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name = "orderQueue" value = "tcp://localhost:61000" />
</bean>
</property>
</bean>
Burada Camel uygulaması, adı verilen bir kuyruğu dinlemeye başlayacaktır. orderQueue. Kuyruğun kendisi, yerel ana bilgisayarda çalışan ve 61000 numaralı bağlantı noktasını listeleyen activeMQ mesajlaşma sunucusunda ayarlanır. Bu yapıldığında, uygulamanız, uygulamanızda tanımlanan uç noktalardan herhangi birinden bu kuyruğa mesaj gönderebilir veya alabilir.
Son olarak, Camel uygulamalarının nasıl oluşturulduğunu daha iyi anlamak için bir projede her şeyi bir araya getirmenin zamanı geldi.
Bir Camel projesi inşa etmek için Maven'i kullanacağız. Bununla birlikte, geliştirme için IntelliJ IDE'yi tercih ediyoruz. Bu proje için seçtiğiniz herhangi bir IDE'yi kullanabilirsiniz.
Yeni Proje Oluşturma
Yeni bir tane oluştur Maven projelendirin ve aşağıdakileri belirtin -
GroupId: Basket
ArtifactId: Basket
Projeniz için varsayılan konumu seçin veya tercih ettiğiniz dizini belirtin.
Bağımlılıklar Ekleme
Camel'i kullanmak için birkaç bağımlılık eklemeniz gerekir. Bağımlılıklar eklenirpom.xml. Bu yüzden pom.xml dosyasını açın ve aşağıdaki iki bağımlılığı ekleyin -
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stream</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
Note- Uygulamamız için minimum bağımlılıklara ihtiyacımız var. Kitaplıklarından daha fazla Camel bileşeni kullandıkça, bu pom.xml dosyasına karşılık gelen bağımlılıkları eklemeniz gerekecektir.
Java DSL oluşturma
Ardından, filtreleme ve yönlendirme kodunuzu bir Java DSL'de yazacaksınız. Adlı yeni bir Java sınıfı oluşturunDistributeOrderDSL. Aşağıdaki kodu ekleyin -
public class DistributeOrderDSL {
public static void main(String[] args) throws Exception {
CamelContext context = new DefaultCamelContext();
try {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product='soaps']/items")).to("stream:out");
// .to("file:src/main/resources/order/");
}
});
context.start();
ProducerTemplate orderProducerTemplate = context.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
orderProducerTemplate.sendBody("direct:DistributeOrderDSL", orderInputStream);
} finally {
context.stop();
}
}
}
İçinde main yöntem, önce yaratırız CamelContext içinde sağlanan bir varsayılan uygulamayı örnekleyerek DefaultCamelContext sınıf.
CamelContext context = new DefaultCamelContext();
Ardından, anonim bir yol oluşturarak bir yol ekliyoruz. RouteBuilder örnek -
context.addRoutes(new RouteBuilder() {
Biz geçersiz kılıyoruz configure doğrudan bir URI'dan bir yol ekleme yöntemi DistributeOrderDSLsistem konsoluna. Xpath sorgusunu kullanarak bazı filtreleme sağlıyoruz.
public void configure() throws Exception {
from("direct:DistributeOrderDSL")
.split(xpath("//order[@product = 'soaps']/items")).to("stream:out");
// .to("file:src/main/resources/order/");
}
Rotayı ekledikten sonra içeriği başlatıyoruz -
context.start();
Ardından, doğrudan URI'mızı oluşturmak için kod ekliyoruz - DistributeOrderDSL.
ProducerTemplate orderProducerTemplate = context.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
Son olarak, işlemeye başlıyoruz -
orderProducerTemplate.sendBody("direct:DistributeOrderDSL", orderInputStream);
Şimdi, Java DSL kodunuz tamamlandığında, uygulamayı test etmeden önce geriye kalan tek şey, order.xmlprojenize dosya. Bu amaçla Giriş bölümünde gösterilen örnek XML'i kullanabilirsiniz.
Test sonuçları
Uygulamayı çalıştırdığınızda, aşağıdaki çıktıyı görürsünüz -
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
Burada yalnızca Sabun siparişlerinin listelendiğini unutmayın. Bunu yerel bir dosyada saklamak isterseniz,stream.out satırında ve aşağıdaki satırı uncomment your configure yöntem -
// .to("file:src/main/resources/order/");
Sonraki bölümümüzde Deve Yayını nasıl kullanacağımızı öğreneceğiz.
Şimdi Spring'i kullanarak önceki bölümdeki uygulamayı yeniden oluşturacağız. Bu bize bir DSL yerine XML'de Deve yönlendirmesinin nasıl oluşturulacağı konusunda bir fikir verecektir.
Yeni Proje Oluşturma
Yeni bir tane oluştur Maven projelendirin ve aşağıdakileri belirtin -
GroupId: BasketWithSpring
ArtifactId: BasketWithSpring
Projeniz için varsayılan konumu seçin veya tercih ettiğiniz dizini belirtin.
Bağımlılıklar Ekleme
Önceki uygulamada kullandığınız temel bağımlılıklara ek olarak, Spring'i kullanmak için birkaç bağımlılık daha eklemeniz gerekir. Bağımlılıklar pom.xml dosyasına eklenir. Şimdi, pom.xml'yi açın ve aşağıdaki bağımlılıkları ekleyin -
<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.2</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>2.15.1</version>
</dependency>
</dependencies>
Bahar için Java DSL Oluşturmak
Şimdi adında yeni bir Java sınıfı oluşturalım DistributeOrderXML. Aşağıdaki kodu ekleyin -
public class DistributeOrderXML {
public static void main(String[] args) throws Exception {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"SpringRouteContext.xml");
CamelContext camelContext = SpringCamelContext.springCamelContext(appContext, false);
try {
camelContext.start();
ProducerTemplate orderProducerTemplate = camelContext.createProducerTemplate();
InputStream orderInputStream = new FileInputStream(ClassLoader.getSystemClassLoader()
.getResource("order.xml").getFile());
orderProducerTemplate.sendBody("direct:DistributeOrderXML", orderInputStream);
} finally {
camelContext.stop();
}
}
}
İçinde main yöntem, önce bir örnek oluşturuyoruz ApplicationContext, bir Spring uygulamasındaki merkezi arabirimdir. Yapıcısında, yönlendirme ve filtreleme bilgilerimizi içeren XML dosyasının adını belirtiyoruz.
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"SpringRouteContext.xml");
Sonra yaratıyoruz CamelContext yukarıda oluşturulanları belirterek ApplicationContext parametresinde.
CamelContext camelContext = SpringCamelContext.springCamelContext(appContext, false);
Bu noktada, yönlendirmemiz ve filtrelememiz ayarlanmıştır. Bu nedenle,CamelContext kullanarak startyöntem. Önceki durumda olduğu gibi, order.xml dosyasını yüklemek için Endpoint'i tanımlıyoruz ve işlemeyi başlatıyoruz. Şimdi, XML'de yönlendirmenin nasıl tanımlandığını anlayalım.
Uygulama Bağlamı Oluşturma
Projeye yeni bir XML dosyası ekleyin ve onu çağırın SpringRouteContext.xml. Aşağıdaki içeriği bu dosyaya kesip yapıştırın.
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd ">
<camelContext xmlns = "http://camel.apache.org/schema/spring">
<route>
<from uri = "direct:DistributeOrderXML"/>
<log message = "Split by Distribute Order"/>
<split>
<xpath>//order[@product = 'Oil']/items</xpath>
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
</split>
</route>
</camelContext>
</beans>
Burada xpath sorgusunu aşağıdaki gibi tanımlıyoruz, şimdi "petrol" için tüm siparişleri seçtiğimize dikkat edin.
<xpath>//order[@product = 'Oil']/items</xpath>
Çıktı Uç Noktaları birden çoktur. İlk uç nokta,order klasör ve ikincisi konsolu belirtir.
<to uri = "file:src/main/resources/order/"/>
<to uri = "stream:out"/>
Uygulamayı çalıştırın.
Test sonuçları
Uygulamayı çalıştırdığınızda, ekranda aşağıdaki çıktıyı göreceksiniz.
<items>
<item>
<Brand>Cinthol</Brand>
<Type>Original</Type>
<Quantity>4</Quantity>
<Price>25</Price>
</item>
<item>
<Brand>Cinthol</Brand>
<Type>Lime</Type>
<Quantity>6</Quantity>
<Price>30</Price>
</item>
</items>
Kontrol et ordersizin tarafınızdan belirtilen yoldaki klasör. Yukarıdaki XML kodunu içeren yeni oluşturulmuş bir dosya bulacaksınız.
Sonuç
Camel, entegrasyon projelerinizi kolaylaştırmak için EIP'leri uygulayan kullanıma hazır bir çerçeve sağlar. Alana özgü dillerde kodlamayı ve ayrıca XML kullanımını destekler.