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