Archive for the ‘Tutorial’ category

Install Google Wave Federation Prototype Server

October 7th, 2009

Below are instructions on how to install the Google Wave Federation Prototype Server. I used Ubuntu 9.04 (Jaunty Jackalope) and ejabberd as the Jabber/XMPP instant messaging server.

Step 1: Install Java
Java is necessary because the Wave Federation Prototype Server is delivered as a Java application that talks XEP-0114.

First make sure your repositories are set to multiverse:

vi /etc/apt/sources.list

This is what my sources.list looks like.

deb http://archive.ubuntu.com/ubuntu/ jaunty main restricted universe
deb-src http://archive.ubuntu.com/ubuntu/ jaunty main restricted universe

deb http://archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe
deb-src http://archive.ubuntu.com/ubuntu/ jaunty-updates main restricted universe

deb http://security.ubuntu.com/ubuntu jaunty-security main restricted universe
deb-src http://security.ubuntu.com/ubuntu jaunty-security main restricted universe

deb http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ jaunty main restricted multiverse

Second update you repositories

sudo apt-get update

Third install Java:

sudo apt-get install sun-java6-jdk sun-java6-fonts

You will also need to install Ant to build the Wave server:

sudo apt-get install ant

Step 2: Install ejabberd

sudo apt-get install ejabberd

Step 3: Configure ejabberd

First make a copy of your configuration file

cp /etc/ejabberd/ejabberd.cfg /etc/ejabberd/bu-ejabberd.cfg

Second edit the configuration file

sudo vi /etc/ejabberd/ejabberd.cfg

These following settings are basic configurations to get your ejabberd server up and running.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Options which are set by Debconf and managed by ucf

%% Admin user
{acl, admin, {user, “username”, “yourhostname.com”}}.

%% Hostname
{hosts, ["yourhostname.com"]}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%% When a user registers, send a notification to
%% these Jabber accounts.
%%
{registration_watchers, ["username@yourhostname.com"]},

{access, register,[{deny, all}] }

Up to this point we just specified the host name and identified who will be the admin of this server. It is important to understand that no user has been create. We will do that later.

Stop and start ejabberd:

sudo /etc/init.d/ejabberd stop
sudo /etc/init.d/ejabberd start

Create your user, make it match the user you specified as your admin (or create more than one):

ejabberdctl register username yourhostname.com password

Create a self signed certificate for ejabberd:

When we installed ejabberd, it automatically created a certificate for us.
The problem is it used the common name of ejabberd. This is not a huge problem but for some XMPP clients it will complain and warn users about the common name mismatch.
To fix this, we need to make the common name match our domain name (For example www.example.com).
During the process of creating your certificate, it will ask you for a password and then it will ask you to set the subject name of the certificate (which will have the common mame). Make the password be whatever you want.

For the subject name, just make sure the common name matches your domain name. The following block of text is an example of what the certificate creation process will look like while you generate your subject name. The only piece that matters is the Common Name.

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []: www.example.com
Email Address []:

Lets create your certificate:

sudo cp /etc/ejabberd/ejabberd.pem /etc/ejabberd/bu-ejabberd.pem
openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout privkey.pem -out server.pem
openssl rsa -in privkey.pem -out privkey.pem
cat privkey.pem >> server.pem
rm privkey.pem
sudo mv server.pem /etc/ejabberd/ejabberd.pem

Step 4: Install the Google Wave Federation Prototype Server:
First install Mercurial:
Mercurial
is a distributed version control system.

You can check and see if its already install by typing:

hg –version

If you need to install it just type:

sudo apt-get install mercurial

Second get the Google wave code:

hg clone https://wave-protocol.googlecode.com/hg/ wave-protocol

This command will add the Google Wave Federation Prototype Server source into a wave-protocol directory.

Third build the GWFPS using ant:
Move into the wave-protocol directory:

cd wave-protocol

Type the following command to build:

ant

Once the build is complete you should see all the .jar files you need in the dist directory.

Step 5: Configure ejabberd to reference the GWFPS

Add this to the listener section of your ejabberd.cfg file:

{8888, ejabberd_service, [{access, all}, {shaper_rule, fast},
{hosts, ["wave.yourhostname.com"],
[{password, "yourpassword"}]}
]}

Step 6: Start the wave (the ugly way)!
Make sure you edit the values of the arguments to match your settings:

java -jar dist/fedone-server-0.2.jar -client_frontend_hostname localhost –client_frontend_port 3456 –xmpp_component_name=wave –xmpp_server_hostname=yourhostname.com –xmpp_server_ip=127.0.0.1 –xmpp_server_port=8888 –xmpp_server_secret yourpassword –xmpp_server_ping=”" –certificate_domain=yourhostname.com –certificate_private_key=test/org/waveprotocol/wave/examples/fedone/crypto/test.key –certificate_files=test/org/waveprotocol/wave/examples/fedone/crypto/test.cert  –waveserver_disable_verification=true –waveserver_disable_signer_verification=true

Using your XMPP client you can do a service directory look up and see if the GWFPS is running (I used Psi):

Google_Wave_PSI

Step 7: Configure and run the server (the prettier way):
First copy the run-config.sh.example to run-config.sh found in your wave-protocol directory.

cd /etc/ejabberd/wave-protocol/
cp run-config.sh.example run-config.sh

Second configure this file using the values you passed in Step 6:

vi run-config.sh

Here is the run-config.sh file with the values that I edited marked in bold:

#!/bin/bash

# Configuration for the FedOne run scripts.
#
# Copy this file to run-config.sh and configure the variables there.
# Please see http://code.google.com/p/wave-protocol/wiki/Installation for
# instructions on how to configure the flags.
#

# Remove this line after configuring
#echo “You must configure the run-config.sh script” ; exit 1

### Variables common to the server, clients, and agents
###

# Domain name of the wave server
WAVE_SERVER_DOMAIN_NAME=yourservername.com

# Host name and port the wave server’s client frontend listens on
WAVE_SERVER_HOSTNAME=localhost
WAVE_SERVER_PORT=3456

# The version of FedOne, extracted from the build.properties file
FEDONE_VERSION=`grep ^fedone.version= build.properties | cut -f2 -d=`

### Server-specific variables
###

# These will probably need to be changed
XMPP_SERVER_SECRET=yourpassword
PRIVATE_KEY_FILENAME=test/org/waveprotocol/wave/examples/fedone/crypto/test.key
CERTIFICATE_FILENAME_LIST=test/org/waveprotocol/wave/examples/fedone/crypto/test.cert

# These should be okay to leave alone
CERTIFICATE_DOMAIN_NAME=$WAVE_SERVER_DOMAIN_NAME
XMPP_SERVER_HOSTNAME=$WAVE_SERVER_DOMAIN_NAME
XMPP_SERVER_PORT=5275

# Set XMPP_SERVER_IP to localhost if the XMPP and FedOne servers are
# running on the same host
XMPP_SERVER_IP=$XMPP_SERVER_HOSTNAME

# Set true to disable the verification of signed deltas
WAVESERVER_DISABLE_VERIFICATION=false

# Set true to disable the verification of signers (certificates)
WAVESERVER_DISABLE_SIGNER_VERIFICATION=true

Run the server from within the wave-protocol directory:

./run-server.sh

Open another terminal, run client from within the wave-protocol directory:

./run-client-console.sh yourusername

To see a really nice example of how you can play with the client make sure you check out the screen cast at dambalah.com. In his screencast Luc does an excellent job of showing us how to get the GWFPS up and running with OpenFire

Resources:
These are the resources and instructions I followed to write this entry:

  • Share/Bookmark

XMPP Part 2, Get your feet wet…

June 17th, 2009

On my last post I gave you a very basic introduction to XMPP. Now, since I know it was a big snoozer, lets get to the good stuff: the code. On this post you will find a simple Ruby script that lets you use an IM (Instant Messaging) client to update your Twitter account by leveraging XMPP and the XMPP4R gem.

Things you will need:


  • Jabber server
  • IM client
  • XMPP4R
  • Twitter account
  • Twitter gem

Jabber server
There are several Jabber servers that you can download and install for free. Two of the most common ones are Openfire and ejabbered.

Once you have the server installed please create two users. For the purpose of this tutorial one of these users will be a bot. I called mine localbot.

What is a bot?
A bot is just a account on the Jabber server that will be used to perform actions or services. It is not controlled by another human.

IM client:
I use iChat as my client, but again there are many other really good products out there that you can use. Take a look at Pidgin or Psi.

Once you have your IM client installed, please connect to the Jabber server with both of the user accounts you created during the server installation. Finally make sure you add each of the newly created accounts as as a contact for one and another.

Why do we have to make them buddies/contacts?
Simply put, if they are not contacts, they won’t be able to send each other messages. This prevents unauthorized users from sending spam.

XMPP4R:
As the XMPP4R team describe it,

“XMPP4R is an XMPP/Jabber library for Ruby. Its goal is to provide a complete framework to develop Jabber-related applications or scripts in Ruby.”

Their site has several different ways for installing this library. If you want to use RubyGems, simply type in your terminal:

gem install xmpp4r

Twitter:
Really? You don’t have a Twitter account? Go ahead get an account and add me!

Twitter gem:
To install with RubyGems type in your terminal:

gem install twitter

Just give me the code:


1        #!/bin/env ruby
2        require ‘rubygems’
3        require ‘xmpp4r’
4        require ‘twitter’
5
6        #Set to true of you want to see the logs
7        Jabber::debug = true
8
9        #Log into Jabber server with your bot
10        jid = Jabber::JID.new(”localbot@box.local/twitter”)
11        client = Jabber::Client.new(jid)
12        client.connect
13        client.auth(”password”)
14
15        #Announce your presence to your contacts
16        client.send(Jabber::Presence.new.set_status(”What you doing right now?”))
17
18        #Listen for incoming messages and process them
19        client.add_message_callback do |t|
20            puts “Got a message need to tweet it!”
21             httpauth = Twitter::HTTPAuth.new(’username’, ‘password’)
22            base = Twitter::Base.new(httpauth)
23            puts t.body.to_s
24            base.update(t.body)
25        end
26
27        Thread.stop

Wait, what? Explain the code:


Lets start at line 7. This line is simply asking if you want to print out the XMPP logs on the terminal. I have it set to true but you might want to set it to false since it can be overwhelming.

The next section to discuss includes lines 10 through 13. This is the code that will connect a user or account to the Jabber server. Line 10 is creating a JID which stands for JabberID. This JID is essentially the user’s identity on the network. In my script I am passing in localbot@box.local/twitter and as you can tell it looks very similar to an email address except for that /twitter section at the end. This is called the resource identifier and it is used to identify a specific connection by the user. Please replace my full JID with your own full JID. The resource identifier can be called anything.

The JID structure:
node @ domain / resource

Bare vs Full JID:
bare JID: localbot@box.local
full JID: localbot@box.local/twitter

Lines 11 and 12 create the connection with the Jabber server. At this point we should all take some time to thank the XMPP4R team for making our lives so simple. As to be expected, there is a lot more magic happening in the background. First of all, the XMPP4R library is negotiating an “always on” connection. This connection will allow for the negotiation and creation of the XML stream. You can image this stream as a XML document that just gets bigger as communication between the client and server goes back and forth. The XML stream, plus the always on connection are some of the reasons why XMPP communication is instant.

Lets look at this a different way:

1. First the connection is made.

XMPP connection

XMPP connection

2. The XML stream is negotiated and opened from the client to the server. Another stream is also created from the server to the client.

xmpp_open_streams

Once the negotiation is complete, the client and the server will only be exchanging a variation of XML stanzas. There are three main XML stanzas that are passed and these are, <message>, <presence> and <iq>.

xmpp_stanzas

On line 16 we send our first XML stanza. If you run the script, you will notice that the status of your bot will reflect whatever the string is that you are passing in the set_status method. In my case it says What you doing right now? This is the presence stanza.

Presence is the way we can tell our contacts about our availability on the network. At the start of this tutorial you were asked to manually subscribe each user to one and another. This was done so that each user could see each other’s presence. The process of authorizing users to see each other’s presence is called presence subscription.

Here is a sample of a presence stanza:

<presence xmlns=’jabber:client’>
<show>chat</show>
<status>What you doing right now?</status>
</presence>

You can pass different values in the show element to change your presence status:
1. away = Your are away.
2. chat = Ready to chat
3. dnd = Don’t bother
4. xa = Extended away
5. if you dont include a <show>, then it means you are available

Lines 19 to 25 sets a message call back. XMPP4R has several of these callback methods that essentially sit and wait for something to happen. In this case when the script is ran, a message callback is set. Now, if I send a message, or a XML stanza of type <message>, from my client to my localbot account, the add_message_callback will catch that message and process it. In this case it will use the Twitter library to update my Twitter status (Lines 21 – 24).

Sample from the logs of my message stanza:

<message from=’guille@box.local/K-TI’ type=’chat’ to=’localbot@box.local’>
<body>This is my message that I typed in from iChat</body>
</message>

Notice the type attribute. Message stanzas can have several different values:
chat = If for real time communication, as in a chat!
normal = This is more like an email. In this case a response is not necessarily expected.
groupchat = This is used in for chat room with many users.
headline = Headlines are used for notifications were a response is not expected.
error = When a problem occurs, the device that catches the error will return a error message to the device that sent the message.

The third of the XML stanzas is <iq> or Info/Query stanza. This is very similar to HTTP in that it gives us a way of performing request and response actions through XMPP. I will talk more about these stanzas in my next XMPP post.

Line 27, although not XMPP or XMPP4R related is important to this script. Without it, the script would just continue on to the next line and finish the script.

So there you go, a simple script that lets you send messages from your IM client to your Twitter account. Plus now you know the basics of XMPP and how the servers communicate.

Other resources:

1. XMPP: The Definitive Guide

2. NFJS, The Magazine – Check out Brian Sletten’s article titled XMPP for the People: Openfire and the Smack API

  • Share/Bookmark

Groovy + Ant = GANT

December 3rd, 2008

gantVenkat Subramaniam has a theory about XML. He says:

Like humans, XML starts out cute when it’s small and gets annoying when it becomes larger.

If you have the same sentiment as Venkat, you will appreciate Gant. Gant is a powerful tool for scripting Ant task by writing Groovy code instead of XML. Below you will find samples from a Gant script and a explanation on what the code does. I wont go through the entire script but you can get it here.

Notice: The script calls a property file that you will need to create. The property file specifies locations for different directories. If you downloaded the script and you want to run it, make sure you change the file name to build.gant. To run the script, navigate to the location of the file and type gant.

In a nutshell, you write a Gant script by:

1. Declaring a target:

target ( ‘nameOfTarget’ : ‘ Description of Target ‘ ) {

}

2. Adding tasks inside the target:

targer ( ’sampleTarget’ : ‘This is a sample target’) {

ant.doSomething(more code)

ant.doSomething(more code)

}

Lets start examining and explaining the script:

First two lines of the script:

Ant.property(file: ‘build.properties’)
def antProperty = Ant.project.properties

These are the first two lines of the script and they are simply saying, “Hey! I have a file called build.properties that I will be using during this process and I will refer to it with the word antProperty. So whenever you see the word antProperty, I want you to look inside the build.properties file for the value”. This is the file that you will need to create in order to build your project.

First target definition in the script:

target( ‘build’ : ‘This target build the project’) {
ant.echo(’Hello I am starting the build process now please be patient’)
depends(resources)
depends(webcontent)
depends(compile)
depends(war)
}

This is the first target of many for the script. This section of code simply creates a target called build. The first task in this target is to print out a line. This is done with the echo command, ant.echo. Just like Ant, it simply prints out the statement declared inside the quotes. Finally we are saying, “Hey! This target depends on the completion of other targets called resources, webcontent, compile and war!”

First path definition in the script:

target( ‘resources’ : ‘Grabs resources such as the property files’) {
ant.echo(”I am grabbing all the resources”)
ant.mkdir(dir: antProperty.’dumpPropertiesHere’)
ant.copy(todir: antProperty.’dumpPropertiesHere’) {
path(refid: ‘properties’)
}
}
def properties = ant.path(id: ‘properties’) {
fileset(dir: antProperty.’getPropertiesFiles’) {
include(name: ‘*.properties’)
}
}

This piece of code has another target and a extra path definition. The resources target is going to copy some files into a specified location. Again, the first line simply prints the string inside the quotes.

The second line is simply creating a directory with the ant.mkdir task. The name for the directory is specified by calling the properties file.

The third line is going to copy files into the directory we created with the ant.mkdir task. The ant.copy(todir: antProperty.’dumpPropertiesHere’) is saying, “Yoooo machine, dump some stuff in here! You can find the files I need in a place called properties

Finally we define where this properties location is. We accomplish this by using the ant.path task. In the first line we give it an id. The fileset task is simply saying “The files that I want are in here and please include all files ending in .propeties“.

These tasks that I just described above cover about 70% of the code that you will find in my script. The following tasks will describe other important actions you will need to build your project.

Compiling your code:

ant.javac(srcdir: antProperty.’getSrc’, destdir: antProperty.’setClassesHere’) {
classpath() {
path(refid: ‘buildCP’)
}
}
}

The task ant.javac is the command you use to compile your Java code. In this task you are passing two parameters, the first parameter tells the system where to find the source code you want to compile, while the second parameter tells the application where to set the classes after they are compiled.

The classpath() task is basically just telling the system where you find the classes it will need in order to compile your code.

Creating a war file:

target ( ‘war’ : ‘Creates the .war’) {
ant.echo(’Starting a war!’)
ant.jar(destfile: antProperty.’gant.war.file’, basedir: antProperty.’buildWarWith’, includes: ‘**’)
}

Here we call the ant.jar task in order to create the war file. The first parameter is the name of the .war file. The second parameter points the system to the location where it will find all the files that it needs. Finally, we tell the system to include all the files in that base directory.

setDefaultTarget(build)

Finally setDefaultTarget tells the system which target to start with.

As you probably noticed, one of the advantages of using Gant over basic Ant is the expressiveness you can achieve by using Groovy instead of XML. I originaly wrote this Gant script to begin my training in Groovy syntax, after a couple of minutes I found myself mostly copying and pasting the code since I had so many targets. So even thougth I think this is a good way of learning the basics of Groovy syntax the biggest benefit was being able to use this script on other projects and not having to look at XML. Please let me know know if you have any questions or comments about the script, or if you have any feedback on how I could make it better.

  • Share/Bookmark