Pet Store Part 1
Pet Store is a sample application that demonstrates how an AS3 client can communicate with a remote application written in Erlang. It exemplifies the usage of AMQP as remoting technology and Cotton as an object serialization protocol. The Cotton Over AMQP library is a high level wrapper around the low level AMQP and Cotton libraries. This provides a Flex client with a very simple programming interface. The interaction with the server is an asynchronous RPC mechanism using the RabbitMQ broker.
Introduction
This article demonstrates:
- How to start the Pet Store server;
- How to connect to the server using the AS3 client.
As the server is written in Erlang and uses the RabbitMQ AMQP broker, some knowledge of these technologies is useful, but not essential. The section describing how to start the server is quite straightforward and does not require any specific experience, apart from general OS administration skills.
If you would prefer to just read about what the AS3 client looks like, and don't want to run the application yourself, you can skip over the section about the server.
You can get the source code for this article from the Cotton Over AMQP repository. To access this, you will need to have Mercurial installed. Once you have Mercurial, begin by cloning the repository:
$ hg clone http://freehg.org/u/0x6e6562/cotton-over-amqp/
The source tree is split into two parts, one for the server, which is in the erlang subdirectory, and one for the client, which is in the as3 subdirectory.
Starting The Pet Store Server
The Pet Store server has been packaged as a supervised OTP application. It uses an AMQP client to connect to the AMQP broker and the Cotton serialization library in order to decode the data it receives from the AS3 application.
The pre-requisites for running the server are:
- RabbitMQ server, version 1.3.0 or higher;
- The Erlang client for AMQP;
- The Cotton Erlang library, version 0.3.3 or higher;
- The Pet Store OTP application contained in the tree you checked out from the repository;
If you do not already have Erlang OTP installed on your system, the RabbitMQ installers can provide this dependency for you. The Pet Store application was tested with version R12B-2 of OTP.
When you have OTP and RabbitMQ installed, you can compile and link both the AMQP client and Cotton libraries to the lib directory of your OTP installation. To do this, unpack both packages and run the make command inside the respective root directories. This will compile the source code.
To link these two libraries into your OTP installation, create symbolic links from the lib/erlang/lib directory of your OTP installation to the root of the directories where you built the AMQP and Cotton libraries:
$ pwd
OTP_HOME/lib/erlang/lib
$ [sudo] ln -fhs PATH_TO_LIBS/amqp_erlang/ amqp-client-0.1
$ [sudo] ln -fhs PATH_TO_LIBS/cotton/ cotton-0.3.3
Once this has been successfully completed, go back to directory where you cloned the Cotton Over AMQP Pet Store repository. Change into the erlang directory and compile the Pet Store server using the supplied Makefile. Then start an Erlang shell from the same directory using the following command line arguments, making sure that the RabbitMQ broker is running beforehand:
$ erl -pa ebin -s petstore
To check whether this was successful, use the which_applications/0 function and you should see something like this:
1> application:which_applications().
[{petstore,"Cotton AMQP Pet Store Demo","0.1.1"},
{stdlib,"ERTS CXC 138 10","1.15.2"},
{kernel,"ERTS CXC 138 10","2.12.2"}]
If the Pet Store application is listed, then the application has been started correctly. Now you test it using the AS3 client.
Setting Up The AS3 Client
The AS3 client is made up out of two parts:
- A core library that provides connectivity and serialization to the server. This is located in the root of the as3 directory;
- A test project that provides the Pet Store specific interface as well as a test class to demonstrate how to invoke the Pet Store from within a Flex application. This is located in the as3/test directory.
As there are currently no build scripts, you will to create separate projects for the core and the test project in Flexbuilder. Both projects include their own dependencies in their respective lib directories, so make sure to include these on the project build path. In addition to this,
- Download the latest swc libraries for AMQP and Cotton and add them to the library path of the core project;
- Add the core project as a dependency to the test project.
Once this has been setup, you don't really need to look into the core project, unless you are interested in the mechanics of the library.
Our attention can now be focussed on the main test class which has been implemented in MXML script.
Running The AS3 Test Client
To gain an appreciation of how asynchronous RPCs are handled using Cotton, it might be useful, but not necessary, to refer to this article.
The layout of the test project has been split up into three parts:
- The src directory, which contains the client definitions of the Pet Store business domain. This is located in the src/org/freehg/petstore directory;
- An application context file, which defines the dependencies that will be injected into the client using the prana DI framework;
- The cotton-over-amqp-test.mxml file, which is the main runnable script.
The Petstore class provides the client interface definition to the remote Pet Store server. The interface currently provides three operations that have been implemented on the server side:
- listAllPets - lists all of the pets in the store;
- buyPet - buys a pet from the store based on the pet's name;
- sellPet - sells a pet to the store.
The Pet class is a domain object that represents a pet.
I chose to orchestrate all of the dependencies using the Prana dependency injection framework, which is a simple yet powerful library that provides functionality similar to Spring. Using DI improves the clarity and flexibility of the client code by taking a declarative approach to wiring in all of the bits and pieces needed to make the Pet Store work. This helps the overall goal of the Cotton Over AMQP library to be as simple as possible for somebody wanting to concentrate on producing Flex UI applications rather than low level code glue in AS3. For anybody interested in gaining a deeper understanding of DI in AS3, Christoph Herreman's blog provides some useful insights.
The application context file provides all of the configuration details you will need to connect to the Pet Store server via AMQP:
<object id="petstore"
class="org.hessian.transport.ProxyFactory"
factory-method="createProxy">
<constructor-arg value="org.freehg.petstore.Petstore"
type="Class"/>
<constructor-arg ref="delegate"/>
</object>
<object id="delegate" class="org.freehg.amqp.RpcDelegate">
<constructor-arg ref="connectionState"/>
<constructor-arg ref="brokerState"/>
</object>
<object id="connectionState" class="org.amqp.ConnectionState">
<property name="username" value="guest"/>
<property name="password" value="guest"/>
<property name="vhostpath" value="/"/>
<property name="serverhost" value="localhost"/>
</object>
<object id="brokerState" class="org.freehg.amqp.BrokerState">
<property name="realm" value="/data"/>
<property name="exchangeName" value="petstore_exchange"/>
<property name="exchangeType" value="direct"/>
<property name="routingKey" value="org.freehg.petstore"/>
</object>
In this context you can see:
- That the Petstore interface is being proxied by a Cotton specific proxy that handles object serialization transparently to the application;
- That this serialization proxy uses an AMQP based asynchronous RPC delegate that handles all of the communication to the server;
- Various configuration parameters to connect to the RabbitMQ broker.
When the main MXML is run, it initializes the Prana container in the onCreationComplete callback function:
function onCreationComplete():void {
ctx = new XMLApplicationContext("applicationContext.xml");
ctx.addEventListener(Event.COMPLETE,
onApplicationContextComplete);
ctx.load();
}
When the Prana container has been loaded, the Petstore interface is ready to be used. This is as simple as obtaining a reference to the Petstore proxy interface from the application context and invoking the particular business method you require:
function onApplicationContextComplete(event:Event):void {
petstore = ctx.getObject("petstore");
var handle:AsyncHandle = petstore.listAllPets();
handle.addResponseListener(onPetList);
}
To process the result of the listAllPets call, this callback handler is used:
function onPetList(event:BottomHalfEvent):void {
var pets:Array = event.result as Array;
trace("-----Original Pet List---------")
for each (var pet:Pet in pets) {
trace(pet);
}
}
This is the quintessence of how an RPC is invoked and handled using the Cotton Over AMQP library. This article provides a more depth description of the AsyncHandle mechanism, but this is not required to get quick and simple results from the high level library.
To see further examples of using the Pet Store API, refer to the source code of the main MXML script. If you are to run the script successfully, you should see the following trace output (if run in debug mode):
-----Original Pet List---------
Pet: {name=Phil,breed=fish,cost=12}
-> Franca has been sold
-----Pet List: After Selling Franca---------
Pet: {name=Franca,breed=siamese,cost=34}
Pet: {name=Phil,breed=fish,cost=12}
-> Bought Pet: {name=Franca,breed=siamese,cost=34}
-----Pet List: After Buying Franca Back---------
Pet: {name=Phil,breed=fish,cost=12}
Here you can see these three operations executed sequentially:
- Call listAllPets. This returns a single entry, i.e. Phil the Fish;
- Create a new pet cat called Franca and sell her. If you call listAllPets again, you will see that Phil and Franca are available in the Pet Store;
- Buy Franca back. After that you will see the original list of pets in the store.
Discussion
This article demonstrates the first cut of a simple Pet Store application. The main goal behind the Cotton Over AMQP abstraction is to provide a very simple client interface for Flex development. Although the article discussed all of the client- and server-side details in order to get the application up and running, future versions of the Pet Store could contain more sophisticated packaging to make the install process even easier.
In realistic project scenarios, the Flex code and the server side code may be implemented by different developers. In that situation, the Flex developer does not need to worry about the server at all.
If you look at the amount of actual code in the client, you will see that it is quite concise, because all of the low level details are being handled by upstream libraries and are wired together using dependency injection.
Finally, it should be noted that whilst the Pet Store is implemented in Erlang, this doesn't necessarily need to be the case. AMQP and Cotton provide language neutral remoting and object serialization protocols, so it is possible to implement the Pet Store on platforms that understand these two protocols.
References (1)
-
Response: Rabbitmq BookmarksBookmarked your page with keywords rabbitmq!

Reader Comments