Java, SMPP ve Camel

Bu yazıda biraz daha piyasaya yönelik bir uygulama geliştireceğiz. GSM sektörüne yazılım geliştiren her firmanın ürün kataloğunda olan, toplu SMS gönderimi yapan uygulamalar vardır. Bunlar SMPP kullanılarak, farklı noktalara önem verilerek oluşturulur. Bense bu yazıda Camel kullarak, enterprise integration pattern kullanımına önem vererek, benzer bir toplu SMS gönderimi uygulamasının nasıl geliştirilebileceğini anlatacağım.

SMPP Nedir?

SMPP, Short Message Peer-to-Peer, kısa mesaj gönderimi için kullanılan bir haberleşme protokolü. Bunun için sizin bir kısa mesaj servisi merkezine (SMSC, Short Message Service Center) ihtiyacınız vardır. SMSC’nin temel işlevi gönderdiğiniz kısa mesajları saklama ve iletmektir. SMPP protokolünde sadece mesaj göndermeye bilir mesajda alabilirsiniz. Bu tamamen SMSC’nize bağlanırken kullanacağınız haberleşme şekli ile ilgilidir. İsterseniz sadece mesaj gönderebilir, sadece mesaj alabilir ya da hem mesaj gönderebilir hem mesaj alabilirsiniz. Haberleşme şeklinize göre SMPP protokolünün en küçük birimini yani PDU’ları (Protocol Data Unit) doğru şekilde ayarlamalısınız.camel_smpp_jpa

SMPP üzerinden bir SMSC ile haberleşirken az çok aşağıdaki adımları uygulamalısınız.

  • SMSC ye bağlantı sağlamalı ve bağlantıyı ne şekilde sağlayacağınızı bildirmelisiniz. (bind)
  • SMSC ye bağlantı şeklinize uygun içerikler göndermelisiniz (SubmitSM, ReplaceSM, SubmitMultiSM, DataSM)
  • SMSC bağlantı şeklinize uygun olarak size yanıt dönecektir. Eğer bağlantınızı yanıt alacak şekilde yapmadıysanız SMSC’nizden yanıt alamazsınız. (DeliverSM, DeliverReceipt)
  • Belirli aralıklarla SMSC’nize ayakta olduğunuzu ve herşeyin yolunda gittiğini bildirmelisiniz. Aksi halde SMSC sizin bağlantı bilgilerinizi koparabilir. (EnquireSm)

Tabi bu mesaj tiplerinin hepsi alt tarafta az öcne bahsettiğim şekilde yani PDU olarak taşınmaktadırlar. Kullandığımız kütüphaneler bizden PDU oluşturmasını bir nebze olsun sakladıkları için işimi kolaylaşıyor. Eğer daha önce bir Bulk Sms uygulaması yazdıysanız ya da şirketinizin bu tip bir ürününün bakımını yaptıysanız buraya kadar anlattıklarımı kullanmışsınızdır. Aynı şekilde bu talaplerin gönderilmesinin senkronize edilmesininde ne kadar önemli olduğunu biliyorsunuzdur.

SMPP Kütüphaneleri

Hemen hemen tüm diller için açık kaynak kodlu ya da ücretsiz SMPP kütüphaneleri bulunuyor. SMPP kütüphanesi geliştirmek çok zor olmasa da yine de bazı paralı kütüphaneler de mevcut. Ben bildiklerimden bir kaç örnek vereceğim.

Java: OpenSmpp, JSmpp

C#: Inetlab.Smpp, Jamaa Smpp, EasySmpp, Roamin Smpp

C/C++:  Smpp-lib

Bunlardan istediğinizi kullanarak yukarıda bahsettiğim aşamaları gerçekleştirebilirsiniz. Benise ağırlıklı olarak OpenSMPP ve JSmpp kullandım. Bu yazıda yapacağım örnekte Camel üzerinden JSmpp kullanacağım.

SMPP Uygulaması Nasıl Test Edilir

Diyelim ki yukarıda bahsettiğim kütüphaneleri kullanarak uygulama geliştirdiniz. Peki nasıl test edeceksiniz? Gidip test için bir SMSC kiralamanız çok saçma olacak. Bu gibi durumlarda test edebileceğiniz konsol ve masaüstü uygulamaları bulunuyor. Özellikle SMPP kütüphanenizi satın aldıysanız (Inetlab.Smpp gibi) size kütüphaneyle birlikte test etmede kullanabileceğiniz bir SMPP sunucusuda veriyor. Ben daha basit, daha kullanışlı ve bedava olan başka bir yol önereceğim.

Logica’nın yani OpenSmpp kütüphanesini geliştiren şirketin bir de SMPP simulasyon uygulaması var. Uygulama çok basit. Uygulamanıza bağlanabilecek kullanıcıları belirliyorsunuz, sonrasında uygulamanızı konsol üzerinden ayağa kaldırıyorsunuz. Uygulamanız ayağa kalktıktan sonra hangi porttan dinleme yapacağınızı belirliyorsunuz ve sunucunuz hazır oluyor. Sonra sunucunuza gelen-giden istekleri konsol üzerinden takip edebiliyorsunuz. Yine aynı şekilde sunucunuza bu zamana kadar gelmiş SMS’leri ve bağlı kullanıcıları listeleyebiliyorsunuz. Hatta isterseniz bağlı olan kullanıcılara mesaj bile gönderebiliyorsunuz. Özetle bir SMSC’nin hemen hemen tüm davranışlarını gerçekleştirebiliyorsunuz.

Bu uygulamaya OpenSmpp’nin sitesinden erişebilirsiniz. Fakat buradan eriştiğinizde uygulamanın tüm bağımlılıklarını falan kendinizin eklemesi gerekiyor. Aynı şekilde main sınıfını falan da aratıp bulmalısınız. Tabi siz bunlarla tek tek uğraşmayın diye ben bunları toplarladım. Bu linkten, uygulamanın toparlanmış haline erişebilirsiniz. start.sh ile uygulamanızı sorunsuz çalıştırabilirsiniz.

Proje

Yazının başında, toplu sms gönderim uygulaması yapacağımızdan bahsetmiştik. Normalde böyle uygulamalarda bir ara yüzden veri girişi alınır ve bu veri girişi veritabanına kaydedilir. Daha sonrasında bir kaç thread bu veritabanını tarayarak veriyi yorumlayıp SMPP protokolü ile SMSC’ye bildirir.

Bu tarz bir akış bir tutorial yazısına sığmayacağından ben sadece core kımını anlatmaya çalışacağım. Yani veritabanından veriler çekilerek otomatik olarak SMSC’ye bildirilecek.

Proje genelinde her zaman olduğu gibi maven kullanacağım. Bunun yanı sıra veri tabanından polling işlemi için Camel’ın JPA bileşenini, veritabanından çekilen bilgilerin SMSC’ye gönderimi için ise yine Camel’in SMPP bileşenini kullanacağım. Tabi tüm bu JPA ve servislerle, Camel’ı bağlamak için Spring kullanacağım.

Ne yazık ki arayüz olarak bişey kullanmayacağım. Uygulama ayağa kalkarken import.sql içerisindekileri veritabanına kaydedecek, daha sonradan veritabanından okunan bilgiler camel yardımı ile SMSC’ye bildirilecek. Ama inanıyorum ki arayüz eklemek isterseniz de bunu yapmanız çok zaman almayacak.

Diğer projelerimden farklı olarak bunda maven assembly plugin’ini kullanacağım ki uygulamayı evde ya da iş yerinde kullanmak isteyen olursa, rahatlıkla kullanabilsin. Yine yazının uzunluğunu azaltmak adına diğer projelerimde ki gibi satır satır ne yaptığımı yazmayacağım. Sadece ana hatlarıyla ne yaptığımı yazacağım.

Maven

Projeden kısaca bahsettiğimize göre Maven ile projeyi oluşturmaya başlayabiliriz. Maven ile, maven-archetype-quickstart  archetpye’ını kullanarak projemizi oluşturuyoruz. Benim örneği yaparken kullandığım diğer bilgiler aşağıdaki gibidir. Eskiden projeleri oluştururken önce maven ile projeyi oluşturup sonra eclipse’e eklerdim. Fakat şimdi bunu yapmama gerek yok. Intellij’in maven özelliği çok başarılı.

  • Group Id: com.bahadirakin
  • Artifact Id: simple-smpp-routing
  • Package: com.bahadirakin

pom.xml

JPA Katmanı

Jpa katmanımızda çok bişey olmayacak. Sadece JPA entity mizi tanımlayacağız. Doğruca import.sql ve camel kullanacağımızdan bir Dao yada Service katmanına ihtiyacımız olmayacak. Fakat yine de spring içerisinde persistence context tanımlarının yapılması gerekiyor. Nasıl yapıldığına aşağıdaki kaynak kodlardan bakabilir, detaylarına ise spring-jpa yazısından bakabilirsiniz.

ShortMessage.java

Camel Katmanı

Tüm işin yapıldığı yer aslında Camel katmanı. Burada iki tip endpoint oluşturmamız gerekiyor.

  • JPA Endoint: JPA için endpoint oluştururken, okuma işlemlerini ne şekilde yapacağımıza, okuma yaparken tablomuzu ne şekilde kitleyeceğimize, okuma yaptıktan sonra veritabanındaki veriyi ne yapacağımıza kadar bir çok şeye karar verebiliyoruz. Hangi sorguyla polling yapacağımızı, persistence context içerisinde tanımlı entity’lerimizden hangisi için polling yapacağımızı seçebiliyoruz. Daha ayrıntılı bilgi için camel jpa bileşeninin sayfasını inceleyebilirsiniz.
  • SMPP Endpoint: SMPP host adresini, port bilgilerini, smpp kullanacak kullanıcı bilgilerini, smpp ile hangi şekilde haberleşeceğimizi ve daha bir çok bilgiyi bu katmanda veriyoruz. Bizim tek yapacağımız veritabanından kısa mesaj bilgilerini okuyup SMSC’ye bildirmek olacağından biz sadece consumer (yani transmitter) olarak bağlanıyoruz. Aynı şekilde kaç dakikada bir ayakta kontrolü yapacağımızı da belirleyebiliyoruz. Daha ayrıntılı bilgi için camel smpp bileşeninin sayfasını inceleyebilirsiniz.

camelContext.xml

Uygulamanın Paketlenmesi

Biz bir konsol uygulaması geliştirdik, uygulamamızı rahatça dağıtabilmek için .zip halinde paketleyebiliriz. Aynı şekilde hangi klasörde bağımlılıklarımızın olacağına, hangi klasörde başlatma sciptlerinin olacağına karar verebiliriz. Aynı şekilde dışarıdan değiştirmek isteyeceğimiz ayarlarımızı ve import.sql dosyamızı jar içerisine değil de zip içerisine koyup dağıtmalıyız ki rahatça değiştirilebilsin.

Bunun için maven’ın assembly pluginini kullanıyoruz. Zaten yukarıda verdiğim pom.xml içerisinde de dikkatinizi çekmiştir. Ek olarak bir assembly.xml dosyasına ihtiyaç duyuyor. Biz plugin’i ayarlarken pom.xml ile aynı seviyede olacak şekilde ayarladığımızdan pom.xml dosyasının yanına yeni bir assembly.xml dosyası yaratıyoruz ve içeriğini aşağıdaki gibi yapıyoruz.
assembly.xml

Son

gitcatUygulamayı zip dosyasından çıkarıp ana dizindeki run.sh ya da run.bat dosyasını kullanarak çalıştırabiliriz. Eğer ayarlarında bir değişiklik yapmadıysanız H2 veritabanı yaratıp, import.sql dosyasının içerisindekileri bu veritabanına kaydedecektir. Uygulamayı istediğiniz veritabanını kullanacak şekilde ayarlayabilirsiniz. Bu gibi durumlarda import.sql içerisindeki verileri ilgili veritabanına göre değiştirmeniz gerekebilir. Son bir uyarı daha unutmayın import.sql dosyası sadece create ya da create-drop modunda çalışır. Son olarak belirteyim, uygulamanın genelinin import.sql üzeirnden kullanılmasından ziyade, test edilmesi düşünüldü. Yarın başka bir arayüzde veritabanına insert atılacağı varsayılmıştır.

Uygulamanın kaynak kodlarına aşağıdaki adresten erişebilirsiniz.

End Of Line