:: if you never try you never know ::

software development and best practice

Messaging and Event Driven Architecture Example


Berdasarkan postingan sebelumnya mengenai Messaging and Event Driven Architecture. Sekarang saat nya aku membahas bagaimana cara mengimplementasikanya. Contoh aplikasi kali ini aku ambil dari ChatDownloader Aplication yang aku post sebelum nya. Namun sebelum masuk membendah contoh aplikasi tersebut ada hal-hal yang perlu aku jelaskan.

Service Oriented Architecture

Kebanyakan orang mengalihkan bahwa SOA itu berhubungan dengan Application Integration, Platform Independent, ada component software yang bisa diakses ecara remote either itu Webservice, REST, atau dalam Bentuk BPEL. Namun fokus SOA sebenarnya bukan di sisi itu.

SOA itu merupakan architectural concept dalam software development dimana software tersebut di bangun berdasarkan service service yang saling berkolaborasi untuk melakukan specific business capability.

Layaknya Object Oriented Programming yang merupkakan konsep pengembangan software dimana software tersebut dibangun berdasarkan object object yang saling berkolaborasi.

Apakah service itu ? Berdasarkan tulisan Udidahan:

A service is the technical authority for a specific business capability.

Any piece of data or rule must be owned by only one service.


Karekteristik service itu adalah

  1. sesuatu yang memiliki technical authority untuk melakukan specific business capability berdasarkan context nya masing2, contohnya: Purchase Order Service, Shopping Service, Chat Service, Download Service, dll
  2. Service harus memiliki data dan rule sendiri.
  3. Service saling berkomunikasi via message (command dan event)

Application Breaking Down

Aplikasi ChatDwonloader dibagi menjadi dua service, yaitu Chat Service dan Downloader Service. Tiap service bekerja sesuai dengan context kerjaan masing masing. Fitur aplikasi ChatDownloader hanya ada dua, Download File dan Remove Downloaded File.

  1. Chat Service: Listen incoming chat message melalui GTalk. Filtering message apakah incoming message sesuai dengan download ataupun remove specification. Sending DownloadFile command message ke queue, dan RemoveFile command message ke queue. Chat service juga menghandle Event FileDownloaded event message dan FileRemoved event message dari Queue. Dan mengirimkan chat notifikasi ke account requester.
  2. Downloader Service: Menghandle DownloadFIle command, dan dan mendownload file berdasarkan URL Dan mempublish FileDownloaded Event ke queue. Downloader Service juga menghandel RemoveFile command message, meremove file dan mempublish FileRemoved Event message ke queue.

Chat Listener Flow

Google Talk menggunakan protokol XMPP, salah satu API XMPP di Java adalah Smack. Pertama yang harus dilakukan adalah membuat chat manager untuk melisten incoming message, dan mempublish message ke Message filter, apakah message tersebut message download atau message remove.

public class ChatManager {
	//ChatManager attribute
	...

	@PostConstruct
	public void startUp() throws XMPPException {
		Thread chatManagerThread = new Thread() {
			@Override
			public void run() {
				try {
					//connect and login to chat server ...

					PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class));
					connection.addPacketListener(downloadChatListener, filter);
					connection.addPacketListener(removeChatListener, filter);
					log.info("listening message ...");

					System.in.read();

					// set presence status to unavailable when thrad end
					....
				} catch (Exception e) {
					log.error(e.getMessage(), e);
				}
			}
		};

		//start chatManagerThread daemon thread ...
	}
}

Message Filter : DownloadChatListener dan RemoveChatListener akan memfilter message tersebut dan memproses message apakah sesuai dengan spesifikasi message download atau message remove.

Download Flow

DownloadChatListener memfilter incoming chat message, jika sesuai dengan spesifikasi download message maka dicreate FileDownload Command Message dan di kirim ke queue melalui JMS.

public class DownloadChatListener implements PacketListener {
	//attribute ...

	private JmsTemplate simpleDownloadTemplate;
	private DownloadRequestSpecification spec;

	public DownloadChatListener() {
		spec = new DownloadRequestSpecification();
	}

	public void processPacket(Packet p) {
		Message msg = (Message) p;
		if (spec.isSatisfiedBy(msg.getBody())) {
			DownloadFile downloadRequest = new DownloadFile(getFrom(msg.getFrom()), getUrl(msg.getBody()));
			simpleDownloadTemplate.convertAndSend(downloadRequest);
		}
	}
}

Selanjutnya FileDownload Command Message di consume oleh DownloadFileHandler pada downloader service untuk mendownload file

public class DownloadFileHandler implements MessageListener {
	//attribute ..
	IDownloadManager downloadManager;

	public void onMessage(Message message) {
		ObjectMessage mapMessage = (ObjectMessage) message;
		try {
			DownloadFile downloadRequest = (DownloadFile) mapMessage.getObject();
			downloadManager.queueDownloadRequest(downloadRequest);
		} catch (JMSException e) {
			throw JmsUtils.convertJmsAccessException(e);
		}
	}
}

DownloadManager mendelegate SimpleDownloadTask untuk mendownload file, Kemudian SimpleDownloadTask mempublish FileDownloaded event message.

public class SimpleDownloadTask implements Runnable {
	private IFileDownloader _simpleFileDownloader;
	private DownloadFile _downloadFile;
	private JmsTemplate _downloadCompledTemplate;
	private JmsTemplate _errorOccurredTemplate;

	public void run() {
		try {
			_simpleFileDownloader.download(_downloadFile);
			String  downloadUrl =  _downloadUrl + _downloadFile.getFileName();
			FileDownloaded downloadCompleted = new FileDownloaded(_downloadFile.getFrom(), _downloadFile.getUrl(), downloadUrl);
			_downloadCompledTemplate.convertAndSend(downloadCompleted);
		} catch (Exception e) {
			ErrorOccurred downloadError = new ErrorOccurred(_downloadFile.getFrom(), _downloadFile.getUrl(), e.getMessage());
			_errorOccurredTemplate.convertAndSend(downloadError);
		}
	}
}

FileDownloaded event message di Handle oleh FileDownloadedHandler, lalu FileDownloaded mengconstruct FileDownloaded message dan mengirimkan message ke ChatManager untuk mengirimkan notifikasi ke requester.

public class FileDownloadedHandler implements MessageListener {
	//attribute ...
	private ChatManager chatManager;

	@Override
	public void onMessage(Message message) {
		ObjectMessage mapMessage = (ObjectMessage) message;

		try {
			FileDownloaded downloadCompleted = (FileDownloaded) mapMessage.getObject();
			String msg = String.format("[%s] Completed %s \n download url: %s", downloadCompleted.getTime().toString(), downloadCompleted.getUrl(), downloadCompleted.getDownloadUrl());
			chatManager.sendMessage(downloadCompleted.getFrom(), msg);
		} catch (JMSException e) {
			throw JmsUtils.convertJmsAccessException(e);
		}
	}
}

Struktur project

Untuk mengerti code ChatDownloader ini harus memiliki basic Spring, JMS, Thread Pool, Smack API.

Source code dapat download atau di clone Gitorious Repository

About these ads

3 responses to “Messaging and Event Driven Architecture Example

  1. Hermanto Hasibuan May 6, 2011 at 1:38 pm

    lek, Quote CODE nya emang kek gitu ya men…
    kasih indentasi lah lek… biar enak bacanya… :D

  2. Hermanto Hasibuan May 13, 2011 at 3:29 am

    Kang adi,
    ada yg silap disini kang:

    “Downloader Service juga menghandel RemoveFile command message, meremove file dan mempublish [FileDownloaded] Event message ke queue.”

    harusnya

    “Downloader Service juga menghandel RemoveFile command message, meremove file dan mempublish [FileRemoved] Event message ke queue.”

    iya gak seh? :D

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: