Camel Soap ve Nesneler

Bu yazıda sevdiğim diğer bir camel bileşeni yani soap bileşeni üzerinde duracağım. Bu bileşeni kullanarak JAXB kullanılarak oluşturulmuş istekleri camel yönlendirmeleri içerisinde nesneye dönüştüreceğiz. Ardından bu nesneleri işleyip, tekrardan XML’e dönüştürüp gerçek servislere yönlendireceğiz.

Öncelikle bunu neden yaptığımızdan ve bu işlemin alternatiflerinden bahsedeceğim. Bu yolu seçme nedenlerimizin başında XML lerin nesneler kadar kullanışlı olmaması geliyor. Gelen XML içerisindeki belirli alanları kullanarak bir veritabanı sorgusu yapmanız gerektiğini ve bu sorgunun sonucuna göre XML’inizi başka servislere yönlendirmek durumunda olduğunuzu düşünün. Bunu doğrudan Camel context üzerinden yapmanız biraz zor olacağından bir Bean ya da Processor üzerinden yapmayı tercih ediyoruz. Tabi doğrudan tüm XML’i nesneye çevirmek yerine XPATH yada XQUERY gibi bir araç kullanarak sadece istediğimiz kısımları alıp onları da kullanabilirdik. camel_soap

Projenin Olusturulması

Diğer Camel yazılarında oludğu gibi bu yazıda da WSDL-First yöntemini kullanacağız. Diğer yazılardan farkı WSDL2JAVA işlemini maven üzerinden yöneteceğiz. Üretilen tüm JAVA sınıflarını ayrı bir dizinde saklayacağız. Böylelikle uygulama derlenirken sınıflar tekrardan üretilecek ve uygulamanın güncelliği korunacak.

maven-archetype-webapp archetype’ını kullanarak projemizi oluşturuyoruz. Oluştururken kullandığımız parametreler:

  • GroupId: com.bahadirakin
  • ArtifactId: camel-soap
  • Version: 0.0.1-SNAPSHOT
  • Package: com.bahadirakin

şeklinde oluyor. Burdan sonra projenin bağımlılıklarını aşağıdaki gibi ayarlıyoruz.

pom.xml

WSDL

Şimdi demin bahsettiğimiz WSDL’i verelim ve bu WSDL’den bahsedelim.

HelloWorldService.wsdl

Burada gördüğünüz gibi tek bir metodu olan (sayHello) bir servis tanımı bulunmaktadır. Bu servis tanımı içine HelloRequest tipinde bir nesne alıyor ve sadece bir String dönüyor geriye. Bu wsdl’i alıp src/main/resources/wsdl klasörünün içersine atıyoruz.

Wsdl2Java Maven Entegrasyonu

Şimdi src/main/resources/wsdl klasörüne kaydettiğimiz WSDL dosyasını düzenli şekilde Java sınıflarına çevirmemiz gerekiyor. Bunun için pom.xml dosyamıza iki yeni ayarlama yapıyoruz.

Böylelikle üretilen Java sınıfları src/main/gen klasörüne kayıt ediliyor. Ayrıca bu klasör resource klasörü olarak belirtiliyor. Aksi halde proje dosyalarını göremeyecektir.

Tüm bu değişikliklerden sonra pom.xml dosyasının son hali aşağıdaki gibi oluyor.

pom.xml (son hali)

 Web, CXF ve Spring Ayarları

Şimdi ise web.xml, cxf ve Spring ayarlarını yapıyoruz.

Bunun için öncelikle web.xml içeriğini aşağıdaki gibi yapıyoruz.

web.xml

Böylelikle CXF için gerekli olan Servlet’i ve Spring için gerekli olan parametreleri ayarlamış oluyoruz. Sırada Spring’in kullanacağı Context.xml dosyasını yaratmak kalıyor.

Bunun için üç adet dosya kullanacağız. Bu dosyaları src/main/resources altına yaratmalısınız. Bazı dosyaları ilerleyen bölümlerde dolduracağız.

  • applicationContext.xml: Tüm Spring kullanan sistemler bu dosya üzerinden yönetilecek.
  • jaxws-context.xml:  CXF ve JaxWs ile ilgili tüm bean ve endpoint tanımlamaları bu dosya üzerinden yönetilecek.
  • camel-context.xml: Camel ile ilgili Endpoint ve Bean’ler bu dosya üzerinden yönetilecek.

Şimdi applicationContext.xml dosyamızı yaratalım ve içeriğini aşağıdaki gibi yapalım.

applicationContext.xml

Burda CXF ve Spring entegrasyonu için gerek xml dosyalarını ve kendi xml dosyalarımı import ediyoruz. Spring alanında başka bir işlem yapmadığımızdan başka bir bean tanımımız bulunmuyor. Ama gerçek bir projede burada daha başka importlar ve bean tanımlamaları olacaktır.

Diğer iki context dosyamızı şimdilik boş bırakıyoruz. Onları birazdan dolduracağız. Şimdilik ilgili import satırlarını yorum satırı haline getirip devam edebilirsiniz.

Eğer projeyi bu haliyle “mvn clean install” komutunu çalıştırırsanız, src/main/gen klasörünüzün altında com.bahadirakin.helloworld paketinde aşağıdaki sınıfları göreceksiniz.

  • HelloRequest: Servis çağırımında kullanılacak veri yapısı
  • HelloWorldService: Servis tanımlamasının yapıldığı Interface. Servisleri tanımlarken biz sadece bu Interface’i kullanarak yeni bir sınıf oluşturacağız.
  • HelloWorldServiceService: HelloWorldService Interface’ini kullanarak, isteklerde bulunabilecek istemci.
  • ObjectFactory: JAXB için gerekli ObjectFactory. Eğer siz Java-First bir uygulama geliştiriyorsanız bunun yerine jaxb.index dosyası kullanmanız gerekecektir.
  • package-info: Paket bilgilerinin yer aldığı dosya-sınıf.

Servis Tanımlamaları

Gerekli ayarları yaptığımıza ve sınıflarımızı başarıyla ürettiğimize göre artık servisimizi yazmaya geçebiliriz. Servis yazarken yapmamız gereken tek şey oluşturulan HelloWorldService Interface’ini uygulayan bir sınıf yazmak olcak.

Bunun için src/main/java altında com.bahadirakin.helloworld isminde bir paket yaratıyoruz. Daha sonra bu paketin içerisine HelloWorldServiceImpl.java isimli yeni bir sınıf yazıyoruz ve içeriğini aşağıdaki gibi dolduruyoruz.

HelloWorldServiceImpl.java

Şimdi ise bu servisin tanımlamasını jaxws-context.xml dosyamıza ekleyelim.

jaxws-context.xml

Eğer applicationContext.xml dosyanızı yaratırken bu dosyayı eklemediyseniz şimdi eklemeniz gerekiyor aksi halde hata verecektir.

Camel

Şimdi Camel endpointlerimizi oluşturulım ve ilgili yönlendirmeleri yapalım. Benim tasarladığım akış şu şekilde olacak;

  • Kullanıcı isteğini Camel tarafından tanımlanmış bir Endpoint’e yapacak. Bu endpoing tanımlamaları Camel’ın CXF bileşeni ile yapılacak.
  • Bu Endpoint’e gelen SOAP istekleri, XML’den Java nesnelerine çevrilecek (UNMARSHAL). Bizim tek isteiğimiz SOAP işlemimiz sayHello ve bunun da tek parametresi var, oda HelloRequest. Bu sebepten bizim üreteceğimiz Java nesnesi HelloRequest tipinde olacak.
  • Üretilen java nesnesi Camel üzerinde tanımlı bir işleyiciye(processor) gönderilecek. Bu işleyici sadece ekrana yazı yazacak. Fakat bu işleyici herhangibir Spring Bean’ninden farklı olmadığından siz istediğiniz işlemi rahatlıkla yapabilirsiniz.
  • İşleyiciden değişmeden çıkan Java nesnesi tekrardan XML’e dönüştürülecek (MARSHAL).
  • SOAP Envlope tipindeki XML doğruca gerçek Endpoint’e yani az önce JAX-WS ile tanımladığımız servise iletilecek.

Öncelikle işlemciyi(Processor) yazalım. Bildiğiniz üzere tüm işlemci sınıfları Processor Interface’ini kullanmalı. Bunun için src/main/java altına com.bahadirakin.camel isminde bir paket oluşturalım. Daha sonra bu paketin altına HelloProcessor.java isminde bir sınıf oluşturalım. Sınıfın içeriği ise aşağıdaki gibi olacak. Tek yapacağım gelen isteği loglamak olacak.

HelloProcessor.java

Şimdi ise Camel Context’imizi ve ilişkili yönlendiriciyi (route) yazalaım.

camel-context.xml

Burdan sonra porojenizi çalıştırdığınızda beklediğimiz gibi iki adet Endpoint’in ayağa kalktığını göreceksiniz. “http://localhost:8080/HelloWorld” lokasyonuna gönderdiğiniz istekler Camel tarafından karşılacak ve ilgili log kayıtlarını yazacaktır. SOAP-UI ile bu işlemlerin testlerini yapabilirsiniz.

SOAP-UI içinde kullanabileceğiniz örnek SOAP İsteği

Bu isteği Camel tarafına yani http://localhost:8080/HelloWorld adresine gönderdiğiniz de logların içerisinde aşağıdaki satırları göreceksiniz.

Aynı şekilde SOAP-UI tarafında ise aşağıdaki cevabı göreceksiniz.

 Songitcat

Umarım Camel içerisinde SOAP XML’i nasıl Java nesnelerine dönüştüreceğiniz kısmında yardımcı olabilmişimdir. Eğer Java-First bir yapı kullanıyorsanız, lütfen NameSpace tanımlamalarına dikkat edin. Aynı şekilde Java-First çalışırken elinizde ObjectFactory sınıfı bulunmayacağından, nesnelerinizin bulunduğu pakete jaxb.index dosyası eklemeniz ve dosya içerisinde tüm JAXB sınıflarını tanıtmanız gerekmektedir. Fakat namespace ayarlarınızı düzgün yapmazsanız Java nesnelerine dönüşüm sırasında sorun yaşarsınız.

Proje

Projenin git adresi: https://github.com/bhdrkn/Java-Examples/tree/master/camel-soap