Thursday 1 September 2011

Installing and configuring Kannel SMS Gateway


Kannel is an open source SMS and WAP gateway. It's freely available software used by operators, carriers, mobile aggregators and other users to send and receive SMS messages and mobile content.
Further details of Kannel can be found at Kannel's Website . There are many different ways to implement Kannel so it depends what your need is.

A lot of users setup Kannel to connect to HTTP and SMPP providers in order to send SMS messages. In this post I will show how to install, configure and send your first SMS using the gateway

For reference, the user guide can be found at http://www.kannel.com/userguide.shtml

1. Firstly ensure all software requirements are installed and then download the source from the Kannel Download site.

wget http://www.kannel.com/download/1.4.3/gateway-1.4.3.tar.gz

2. Extract the archive file to directory.

tar -xzvf gateway-1.4.3.tar.gz

3. Change to the directory to compile

cd gateway-1.4.3

We want to install to /usr/local so we complete the following steps


./configure  ---prefix=/usr/local/kannel
make
make install

4. Change to the new directory that has been created

cd /usr/local/kannel

5. All the files for kannel are now located in this directory. In order to get Kannel up and running quickly we need to create a new config file.

Refer the the user guide for all parameters available, however the following configuration file is useful for setting up a main 'bearerbox' with an 'smsbox' in which we can send messages to an SMPP carrier.
Substitute fields highlighted with you own details. Example files can also be found in the original source files.

vi kannel.conf

group = core
dlr-storage = internal
admin-port = 13000
admin-password = password
status-password = password
admin-allow-ip = ''
smsbox-port = 13001
log-level = 0
log-file = "/usr/local/kannel/logs/kannel.log"
box-allow-ip = "127.0.0.1"

group = smsbox
smsbox-id = BOX1
bearerbox-host = 127.0.0.1
sendsms-port = 13013
log-file = "usr/local/kannel/logs/smsbox.log"
log-level = 0
access-log = "usr/local/kannel/logs/access.log"

group = sendsms-user
username = user1
password = password1

group = smsc
smsc = smpp
smsc-id = SMSC1
host = 111.111.111.111
port = 12345
smsc-username = my smsc details
smsc-password = my smsc password
address-range = ""
system-type = ""
transceiver-mode = true


6. To start the gateway run the following command

/usr/local/kannel/sbin/bearerbox kannel.conf

ensure kannel.conf is replaced with the full path to you configuration file.

Start the sms box also

/usr/local/kannel/sbin/smsbox kannel.conf

8. You can view the status of the gateway by typing the following in a browser

localhost:13000/status?password=password

7. To test the functionality of the gateway, in a browser send a new sms message to the gateway using the following url:

http://localhost:13013/cgi-bin/sendsms?username=user1&password=password1&to=0123456789&from=4444&text=testmessage


 For further reference, the user guide can be found at http://www.kannel.com/userguide.shtml

Wednesday 31 August 2011

Installing Java JDK Linux Simple Steps

There are many of ways to install the Java Development kit onto Linux operating systems. This includes installing from yum repositories. However some of these versions of java my have components missing.

The following is one of the most simplest way and ensure all of the JDK components are installed:

1. Download the compressed binary from the Java site. For example

wget http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-x64.tar.gz


2. Once downloaded run tar -xzvf on the file

3. mv the directory to /usr/local/

4. Append a reference to the directory your local profile

e.g.  vi ~/.bash_profile

add the following:

export JAVA_HOME=/usr/local/jdk1.7.0
export PATH=$PATH:/usr/local/jdk1.7.0/bin


3. Log out and back in again. Run java -version to confirm installation

Wednesday 19 January 2011

Overview of technologies used so far

There are a number of application that work well on there own and are great for the purpose they are designed for. However everything links together some how and understanding how applications work on their own is only the start of things.

Whilst I have been learning about a number new applications, I have also been looking at how applications can work with each other to give an end to end feel of how certain Internet businesses or back end technologies really work.

There are hundreds or some times thousands of different way in which applications can link with each other within a business or over the Internet. Whether it be using a different storage database at the back end or it be writing a front end client in a different language, I have been documenting a number of working solutions already in my blog http://vidorsolutions.com

Some of the technologies I have learnt and experimented successfully with are as follows:

1. Grails application deployed into Glassfish application server, using PostgreSQL as a database. Then using tools such as PGAdmin to connect to my databases locally on my machine.

2. Ejabberd Instant Messaging server installed on a server instance in the cloud, configured to use postgreSQL as a data source. Then using PSI Desktop chat client to connect with Ejabberd account. Tools such as PGAdmin can also be used here to view the back end database, tables and structure.

To further extend this learning experience I then created a basic Android XMPP client application that could also connect to the Ejabberd Server instance.

A lot of different technologies going on here and a lot to learn about the applications alone if you've never used any of these. However once you see how all these work together you get a greater appreciation of how the end to end user experience works.

Remember for some instructions on how to use these check out my previous posts
http://vidorsolutions.com

Tuesday 18 January 2011

Writing a basic XMPP/Jabber chat application for Android

There are many chat applications for android open source that you can use to connect to an XMPP or Jabber server instance. This could be you own server such as Ejabberd or one such as Facebook / yahoo etc.

I have started to look at how to write a basic android XMPP client that I can use to connect to my Ejabberd server. I have pulled a number of sources available to gain knowledge in android, initially stating with Professional Android 2 Application Development.
There are a number other sample applications in this book that will aid in learning the android programming language.

However to understand how to create an XMPP application I started looking at Smack, an XMPP client library.
This is the library you will need to import and refer to when writing your android XMPP client. Google no longer has it's own native XMPP library.

Smack has be heavily patched to work with android devices, re-badged asmack, library downloads are available from http://code.google.com/p/asmack/
.

Once you have this imported into your project workspace you can now write a basic chat client. I used the following example code for my first point of call:

http://davanum.wordpress.com/2008/12/29/updated-xmpp-client-for-android/

After understanding what each bit of code here meant I was able to write my own similar app. Initially the original sample I'm going to show is very similar to the link above, so I cannot take full credit, I'm just sharing resources.
I have now heavily added to the app with shared preferences custom views and content providers etc, I may share the source in later posts.

You will need to write xml layouts to go with the code but the code behind the main application is as follows:

notice the org.jivesoftware.smack imports:

ChatClient.java:

import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;

public class ChatClient extends Activity {
   
    private ArrayList<String> messages = new ArrayList();
    private Handler handler = new Handler();
    private xmppsettings settings;
    private EditText recipient;
    private EditText text;
    private ListView list;
    private XMPPConnection connection;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        recipient = (EditText) this.findViewById(R.id.recipient);
        text = (EditText) this.findViewById(R.id.text);
        list = (ListView) this.findViewById(R.id.messageList);
        setListAdapter();
       
        //Window for getting settings
        settings = new xmppsettings(this);
       
        //Listener for chat message
        Button send = (Button) this.findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {
           
            @Override
            public void onClick(View v) {
                String to = recipient.getText().toString();
                String text1 = text.getText().toString();
               
                Message msg = new Message(to, Message.Type.chat);
                msg.setBody(text1);
                connection.sendPacket(msg);
                messages.add(connection.getUser() + ":");
                messages.add(text1);
                setListAdapter();               
            }
        });       
    }
   
    //Called by settings when connection is established
   
    public void setConnection (XMPPConnection connection) {
        this.connection = connection;
        if (connection != null) {
            //Packet listener to get messages sent to logged in user
            PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
            connection.addPacketListener(new PacketListener() {
                public void processPacket(Packet packet) {
                    Message message = (Message) packet;
                    if (message.getBody() != null) {
                        String fromName = StringUtils.parseBareAddress(message.getFrom());
                        messages.add(fromName + ":");
                        messages.add(message.getBody());
                        handler.post(new Runnable(){
                            public void run() {
                                setListAdapter();
                            }
                        });
                    }
                }
            }, filter);
        }
    }
   
    private void setListAdapter() {
        ArrayAdapter<String> adapter = new ArrayAdapter<String>
            (this, R.layout.list, messages);
        list.setAdapter(adapter);
    }
   
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }
   
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
        case R.id.settings:
            settings.show();
            return true;
        case R.id.quit:
            finish();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
   
    }
}




xmppsettings.java: (I have made this a menu item)


import android.app.Dialog;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;

//settings get input and then connection is established

public class xmppsettings extends Dialog implements android.view.View.OnClickListener  {
    private ChatClient chatClient;
   
    public xmppsettings(ChatClient chatClient){
        super(chatClient);
        this.chatClient = chatClient;
    }
   
    protected void onStart() {
        super.onStart();
        setContentView(R.layout.settings);
        setTitle("Connection Settings");
        Button ok = (Button) findViewById(R.id.ok);
        ok.setOnClickListener(this);
    }
   
    public void onClick(View v) {
        String host = getText(R.id.host);
        String port = getText(R.id.port);
        String service = getText(R.id.service);
        String username = getText(R.id.userid);
        String password = getText(R.id.password);
       
        // Create connection
       
        ConnectionConfiguration connectionConfig =
            new ConnectionConfiguration(host, Integer.parseInt(port), service);
        XMPPConnection connection = new XMPPConnection(connectionConfig);
       
        try {
            connection.connect();
        } catch (XMPPException ex) {
            chatClient.setConnection(null);
        }
        try {
            connection.login(username, password);
           
            // Set status to online / available
            Presence presence = new Presence(Presence.Type.available);
            connection.sendPacket(presence);
            chatClient.setConnection(connection);
        } catch (XMPPException ex) {
            chatClient.setConnection(null);
        }
        dismiss();
    }
   
    private String getText(int id) {
        EditText widget = (EditText) this.findViewById(id);
        return widget.getText().toString();
    }
}



After these initial files I then when one to create a shared preferences which will save the settings that a user inputs.
Also then when on to write a separate array adapter within the chatclient.java class which then aided in the creation of a content provider to store the messages in a db.

This is the application at the most basic, but will get you started in developing any high end chat app.

Monday 17 January 2011

Adding Modules to Ejabberd Installation, Linux Statsdx

Ejabberd XMPP messaging server comes with a few modules with the initial installation. Some of these are useful however you can extend the features of the server a lot more by using additional modules.

There are a number of modules that can be downloaded from https://svn.process-one.net/ejabberd-modules/  , also there are a number of custom modules on the net, or you can even write your own; if you know erlang.

For example if you wanted some more useful user statistics for your server, rather than just the basic Statistics tab from the web admin page, that just gives you the following details:

Registered Users
Online Users
Outgoing s2s Connections
Outgoing s2s Servers

Why not install the statsdx module that gives you a lot more information.

All modules are installed into the /opt/ejabberd-2.1.5/lib/ejabberd-2.1.5/ebin directory however each module will have it's own set-up requirements written in the README.txt available in each module trunk directory.

To install statsdx :

change to /opt/ejabberd-2.1.5/lib/ejabberd-2.1.5 directory

run svn co https://svn.process-one.net/ejabberd-modules/ to get the latest modules

cd ejabberd-modules/mod_statsdx/trunk


run ./build.sh

copy generated beam file(s) from trunk/ebin directory to
/opt/ejabberd-2.1.5/lib/ejabberd-2.1.5/ebin


edit /opt/ejabberd-2.1.5/conf/ejabberd.cfg:

Scroll down to the section headed modules, this is where you enable each module on your server.


Append the following the the end of the enable modules:

{mod_statsdx, [{hooks, true}]}
(as instructed in the README.txt available with the module src files)

run ./opt/ejabberd-2.1.5/bin/ejabberdctl restart to restart the server instance

Browse to http://localhost:5280/admin/ to see you have more stats available under the Statistics DX tab, such as:

Registered Users
Roster Details
User details
MUC information
Sessions per client, OS, connection type, Languages

There are a lot more modules you can use to extend your basic Ejabberd installation, depending on what you want to do or know.

Sunday 2 January 2011

Installing GlassFish application Server cluster on Linux

GlassFish is a Java EE open source application server. The following instructions demonstrate how to install GlassFish 2.1.1 on any Linux platform.

http://glassfish.java.net/javaee5/build/GlassFish_LB_Cluster.html contains full information on downloading and installing glassfish clusters and load balancer plugin.

I am going to explain the steps I took to install glassfish clusters as I didn't require load balance support.

Please note all commands will require elevated privileges.

1. Download binary installer from http://glassfish.java.net/downloads/v2.1.1-final.html 
save to /opt directory.

2. Ensure JAVA_HOME variable is set to JDK directory

3. Within the /opt directory run java -Xmx256m -jar glassfish-installer-v2.1.1-b31g-linux.jar

INSTALLATION COMPLETE is displayed
This UN-bundles glassfish and installs under a new directory 'glassfish'

4. Change to glassfish directory cd glassfish/


5. Change permissions on lib/ant/bin sub directory using chmod -R +x lib/ant/bin


6. Run lib/ant/bin/ant -f setup-cluster.xml . If successful you get BUILD SUCCESSFUL displayed

7. From /opt/glassfish/bin run ./asadmin start-domain domain1 to start to default domain.
Domain [domain1] is running is displayed

8. Browse to http://localhost:8080/ to confirm Enterprise server is now running.

9. Browse to http://localhost:4848/ to access admin console. Default user name and password are username: admin, password: adminadmin . You can change this from the Application Server settings on the web admin interface page.

The server is now running and now we are going to look at creating a one machine cluster.

10. Change to directory /opt/glassfish/samples/quickstart/clusterjsp

Run /opt/glassfish/bin/asant setup-one-machine-cluster

This does the following:

Creates a cluster with name cluster1
Creates a node-agent with name cluster1-nodeagent
Starts the above
Creates two instances under the cluster

You can change these default values under /opt/glassfish/samples/quickstart/clusterjsp/cluster.properties before running

BUILD SUCCESSFUL is displayed

12. Start the cluster using glassfish/bin/asant start_cluster 

BUILD SUCCESSFUL is displayed again


13. View and confirm node with two instances is setup from http://localhost:4848/  select node agent then cluster1-nodeagent on the left pane




If you need to test the two instances you can simply deploy an application in glassfish and browse to the instance using http:localhost:PORT/appname 

If you continue reading the link below you can learn how to use the load balancer plugin and set up Sun Java System Web Server for this.


http://glassfish.java.net/javaee5/build/GlassFish_LB_Cluster.html


http://docs.sun.com/app/docs/doc/821-0186/aboaa?a=view - also a useful link for getting started

Using PostgreSQL database driver within your Grails applications

By default Grails uses an in-memory database that stores data for your apps within volatile RAM. You can leave this as it is but most programmers like to know that their database is more peristent.

In order to use your own data sources you need to be looking at the DataSource.groovy file within /grails-app/conf directory. Here you specify the database that your application will use.

There are three sections within this file so you can specify different data sources for different purposes: production, test and development. In the example I will demonstrate using a different PostgreSQL database for each purpose however you can use three entirely different products if you wish.


Before you start configuring anything in the DataSource.groovy file ensure that you have completed the following:

1. Ensure PostgreSQL is installed


2. Download PostgreSQL JDBC driver and save it into your applications lib folder.

3. Ensure you have a PostgreSQL user to use for the database connection. If you do not wish to use default user, create new user with createuser command.


4. Create the relevant databases in PostgreSQL that your grails application will use. This can be done simply though PGAdmin or using createdb commands as the PostgreSQL user.

5. Return to the Datasource.groovy config file and use the following settings:

dataSource {
        pooled = true
        driverClassName = "org.postgresql.Driver"
        username = "postgres"
        password = "password"
}
hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='org.hibernate.cache.EhCacheProvider
'
}
// environment specific settings
environments {
        development {
                dataSource {
                        dbCreate = "update" // one of 'create', 'create-drop','update'
                        url = "jdbc:postgresql://localhost:5432/devdb"
                }
        }
        test {
                dataSource {
                        dbCreate = "update"

                        url = "jdbc:postgresql://localhost:5432/testdb"
                }
        }
        production {
                dataSource {
                        dbCreate = "update"
                        url = "jdbc:postgresql://localhost:5432/proddb"
                }
        }
}


Please note that the following are examples of the different database purposes:

  • Development db is when you use grails run-app to launch you application
  • Test db is when you run grails unit and integration tests
  • Production db is used when you upload the application to an app server such as glassfish etc.
Now run you application in whatever environment you wish and view data in your own PostgreSQL databases. If you not a SQL savey then learn how to use PGAdmin to view tables and database structure.