advanced messaging queue protokolü, mqtt protokolü gibi mesaj bazlı çalışmaktadır. mqtt den daha karmaşık bir yapısı mevcuttur. buffer yaklaşımı vardır. tasarım olarak daha kapsamlı sunucularda asenkron haberleşme için tasarlanmıştır.
Az enerji ile cihazlarımızda iş yapacağımızı düşünürsek mqtt bu konuda ön planda olabilir ama güvenlik, performans, süreklilik gibi konular üzerinde mqtt ye göre daha yetenekli olan amqp protokolü de daha kritik iot uygulamalarında kullanılabilir.
Bu yazıda apache nin geliştirdiği qpid üzerinden protokolün incelemesini yaptık.
apache-qpid kurulumu için debian sistemlerde aşağıdaki iki komut girilerek kurulum gerçekleştirilir[1].
apt-get install -y qpidd qpid-tools
apt-get install -y libqpidmessaging2-dev python-qpid
Kurulum bittikten sonra mqtt gibi hemen veri alışverişine başlayamıyoruz. amqp protokolü incelemenin başında söylediğimiz gibi daha güvenli bir protokoldür. Kendi sağlamış olduğu authentication, authorization yapısı mevcuttur. ilk önce kullanıcı ve bu kullanıcının bağlı olduğu bir realm yaratacağız.
Kullanıcıyı yaratırken qpid bizden şifre isteyecektir.
amqp broker larına bağlanırken kullanıcı adı, şifre ikilisini kullanacağız. Veri tabanı jdbc bağlantıları gibi düşünülebilir.
Aşağıdaki komut ile "admin" realm i olan "firat" isminde bir kullanıcı yaratıyoruz.
saslpasswd2 -f qpidd.sasldb -u admin firat
Yaratılan kullanıcılar qpidd.sasldb dosyasında binary bir şekilde tutulmaktadır. bu dosyaya erişmek için debian sistemlerde;
sasldblistusers2 -f /etc/qpidd/qpidd.sasldb
komutu kullanılır. Bu komutta yaratılan kullanıcılar ve ait olduğu realm leri görülebilir.
root@debian-1gb-fra1-01:~/# sasldblistusers2 -f /etc/qpid/qpidd.sasldb
admin@QPID: userPassword
firat@admin: userPassword
Authentication safhasında farklı modları desteklemektedir. Bu modlar; md5, ssl, plain,kerberos olabilmektedir.
Bu çalışmada authentication modunu PLAIN olarak kullanacağız. PLAIN modunda veriler görülebilir ve sadece kullanıcı adı, şifre ile broker üzerinde mesajlaşma yapılabilir.
authentication modunu seçmek için
/etc/sasl2/qpidd.conf
içindeki mech_list parametresine PLAIN değeri verilir.
.
.
pwcheck_method: auxprop
auxprop_plugin: sasldb
sasldb_path: /etc/qpid/qpidd.sasldb
mech_list: PLAIN
.
.
Bu kullanıcıyı yarattıktan sonra authorization aşamasından geçmek için /etc/qpid klasöründeki qpid.acl dosyasına erişilir.
Kısaltmasından anlaşıldığı gibi bu bir access control list dosyasıdır.
# QPID policy file
.
.
.
# Group definitions
group admin admin@QPID
group firat firat@admin
# Admin is allowed to do everything
acl allow admin all
acl allow firat all
# Deny everything else by default
acl deny all all
Yarattığımız kullanıcıyı "sorunsuz" bir şekilde kullanmak için root ile eş değer acl allow firat all deyimini giriyoruz.
qpid broker ı üzerinde kullanıcımızı test etmek için
qpid-config -b kullaniciadi/şifre@host:port
komut taslağını takip edilir.
qpid-config -b firat/XXXXXX@XXX.XXX.XXX.XXX:5672
broker üzerinde topic yaratmak aşağıdaki komut kullanılır.
qpid-config -b firat/XXXXXX@XXX.XXX.XXX.XXX:5672 add exchange topic helloTopic
helloTopic isimli bir topic yaratmış olduk.
topic e subscribe olmak için ilk başta topic e bağlı bir kuyruk yaratılır. Kuyruk mantığı amqp protokolünün sağladığı bir yapıdır.
mqtt den farklı olarak bu kuyruklar dinamik olarak yaratılabilir ve birden fazla topic e atanabilir.
qpid-config -b firat/XXXXXX@XXX.XXX.XXX.XXX:5672 add queue helloQueue
helloQueue isminde bir kuyruk yaratmış olduk. yaratılan bu kuyruk topic ile ilişkilendirilir
qpid-config -b firat/XXXXXX@XXX.XXX.XXX.XXX:5672 bind helloTopic helloQueue
topic yaratıldıktan sonra aşağıdaki python un qpid kütüphanesi ile sunucumuza yarattığımız topic te mesaj publish edelim
#!/usr/bin/env python
import sys
from qpid.messaging import *
broker = "firat/XXXXXX@XXX.XXX.XXX.XXX:5672"
address="helloTopic"
mes="Hello world"
connection = Connection(broker)
try:
connection.open()
session = connection.session()
sender = session.sender(address)
receiver = session.receiver(address)
sender.send(Message(mes));
message = receiver.fetch()
print message.content
session.acknowledge()
except MessagingError,m:
print m
connection.close()
sunucuda çalıştırılan python scripti ile sunucuda yarattığımız helloTopic, parametre verilerek bu topic e gelen mesajlar görüntülenir.
import optparse, sys, traceback
from qpid.messaging import *
from qpid.util import URL
from subprocess import Popen, STDOUT, PIPE
broker = "firat/XXXXXX@XXX.XXX.XXX.XXX:5672"
addr="helloTopic"
conn = Connection(broker)
def dispatch(msg):
msg_type = msg.properties.get("type")
if msg_type == "shell":
proc = Popen(msg.content, shell=True, stderr=STDOUT, stdin=PIPE, stdout=PIPE)
output, _ = proc.communicate()
result = Message(output)
result.properties["exit"] = proc.returncode
elif msg_type == "eval":
try:
content = eval(msg.content)
except:
content = traceback.format_exc()
result = Message(content)
else:
result = Message("unrecognized message type: %s" % msg_type)
return result
try:
conn.open()
ssn = conn.session()
rcv = ssn.receiver(addr)
while True:
msg = rcv.fetch()
print msg
response = dispatch(msg)
print response
ssn.acknowledge()
except ReceiverError, e:
print e
except KeyboardInterrupt:
pass
conn.close()
Kaynaklar
kod örnekleri aşağıdaki linkten referans alınarak düzenlenmiştir.