Friday, February 21, 2014

Integrating an Akka.io actor system with Play framework (A distributed message classifier with Akka.io and Play framework)


Recently we developed a distributed message classifier. This can process rapid burst of text (email, twitter feeds, etc) and get results.


To implement the processing part we used Akka.io which is an event based distributed framework. Currently to analyse messages we use a web service. But any other processing mechanism (local or remote) can be easily plugged to this.
After implementing the core we needed to publish messages to the applications using REST. To do that we integrated it with Play Framework. Also I developed an admin panel using MVC features provided by it.
While integrating the existing actor system with play framework several conflicts occurred. One reason for this was Play framwork internally uses an actor system too. So I had to do several tweaks and change some configurations. I am not going to discuss each of them here because it will be too lengthy. This is the URL to our git-hub repo https://github.com/Buddhima/MessageClassifier. You can fork it and see those by your self. It has a very descriptive user guide and wiki which explains from architecture to UI. Hope this will be useful to starters who are trying to get familiarized with Akka.io and Play framework.

Thursday, November 14, 2013

Enable access from other hosts to a MySQL server

Recently I deployed a MySQL server. But there was a problem that I could not access the data base from a application which was hosted in another server. The reason for this is by default MySQL server does not accepts requests from other hosts except the localhost.
To solve this problem we have to do two tasks.


  • Create a user which has permissions to read and write to a database from a different host
GRANT ALL PRIVILEGES
ON database.*
TO ‘user’@'yourremotehost'
IDENTIFIED BY 'newpassword';

As an exmaple following query enables root user to access all the databases from any host.

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password';

  • Bind the ip adress
To do this you have to edit the MySQL configuration file. In Ubuntu this is /etc/mysql/my.cnf
There you can find an entry like
bind-address = 127.0.0.1 

If you want to enable access from all the host just remove it. If you want to limit the hosts you can add entries like
bind-address = your ip

After doing that you have to restart the MySQL server. In Ubuntu you can do that like below.
sudo /etc/init.d/mysql restart


Saturday, November 2, 2013

Install Oracle Java Development Kit on Ubuntu

Installing Java SDK is very straight forward in Windows. Download Java installer double click it and follow the steps. But installing Java in Ubuntu is not easy like that. In Ubuntu we can easily install Open JDK by providing following command. 

sudo apt-get install openjdk-6-jdk

 But this installs Open JDK not Oracle JDK. This is not a problem for entry level Java developers. But if you work in a production environment you cannot use Open JDK since most products use Oracle Java. Until recently the method I followed to install Oracle Java was downloading the tar.gz file form Oracle site and install it using the terminal. But this is very time consuming and there are lot of configurations has to be followed. But here is a very easy way to install the latest Oracle JDK in you machine without not needing to do any additional configurations. Just issue following three commands in the terminal to install Oracle JDK in your Ubuntu machine.


sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update 
sudo apt-get install oracle-java7-installer



Monday, July 15, 2013

How to connect to WSO2 BAM with NodeJs using REST

Recently I wanted to use WSO2 BAM REST API to with NodeJs. After playing sometime with NodeJs API I was able to POST a stream definition to BAM using NodeJs with following method.

var https = require('https');

var auth = "Basic " + new Buffer('admin:admin').toString("base64"); //You  need to replace admin:admin with your username and password

// prepare the header
    var postheaders = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        "Authorization": auth
    };

// the post options
    var optionspost = {
        host: '127.0.0.1',
        port: '9443',
        path: '/datareceiver/1.0.0/streams/',
        method: 'POST',
        rejectUnauthorized: 'false',
        headers: postheaders

    };

doPOSTRequest=function(optionspost,jsonObject){
    // do the POST call
    var reqPost = https.request(optionspost, function(res) {
        console.log("statusCode: ", res.statusCode);
        // uncomment it for header details
//  console.log("headers: ", res.headers);

        res.on('data', function(d) {
            console.info('POST result:\n');
            process.stdout.write(d);
            console.info('\n\nPOST completed');
        });
    });

    // write the json data
    reqPost.write(jsonObject);
    reqPost.end();
    reqPost.on('error', function(e) {
        console.error(e);
    });
}

An important ramark is you need to put rejectUnauthorized: 'false' if you are using NodeJs default Cas. Otherwise you may get an error saying [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]. This is because NodeJs rejects the certificate provided by BAM in default configuration. This tweak can be applied to any situation where you get the [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE] when try to send a https request using NodeJs.

Saturday, June 15, 2013

Facebook SDK for android - How to share Session throughout all activities

A problem which I faced when using Facebook SDK for android was in my app login happens through one activity and posting to Facebook happens through another activity. So I had to retrieve the session which is opened in the LoginActitvity. Actually solution was simpler than I thought. To get the session from an another activity you can use the below method.

private void getSession() {
     Session.openActiveSession(this, false, callback);
}

private Session.StatusCallback callback = new Session.StatusCallback() {
     public void call(Session session, SessionState state,
              Exception exception) {
         if (session.isOpened()) {
             //Do something
         }
     }
};


Friday, May 3, 2013

Adding a Foursquare, Google+ like sliding drawer to your android app


Currently Android SDK does not support such a feature. But this kind of designs are very popular between the users. But there are many open source libraries which facilitates sch omplementation. https://github.com/jfeinstein10/SlidingMenu is an open sorce sliding drawer library which is used many poplar android applications. Using this is prettry simple. This video explains how to integrate with your android project. After the integration is done you can create a sliding drawer like this.



Add the following code to onCreate() method of your activity.

    menu = new SlidingMenu(this);
    menu.setMode(SlidingMenu.LEFT);
    menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
    menu.setShadowWidth(5);
    menu.setFadeDegree(0.0f);
    menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
    menu.setBehindWidth(150); //change width according to your device
    menu.setMenu(R.layout.menu_frame);

Here menu_frame is the layout of the sliding drawer. It has to be a frame layout and you can add any other layout to the frame layout.

If your application has a actionbar you may need to link sliding drawer to the app icon like in Google+ and Youtube Android applications. What is usually happen is toggling the sliding drawer when the app icon is clicked. It can be implemented like this.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
       case android.R.id.home:
               menu.toggle();
               return true;
   }
   return true;
 }



Wednesday, November 28, 2012

Create new Java Class files at runtime

When we write programs usual method is to write all the code compile it and run. But when we try to complex things some times we may want to generate a new class and use it at runtime. As an example I wanted to create a class which parse a xml message and create a new Java object from that data. This is used in web server. So that result object varies according to the web service which is deployed. The solution was to inspect the service at deployment time and create a new parser class according to that in the service deployment time. It has to be noted that this parser had to be generated as a .class file and dynamically added to the classpath. So the result was to use a bytecode manupulation library. There are few bytecode manuplulation libraries available as ASM and JavaAssist.
I used JavaAssist for this. The reason for using JavaAssist is it is simple to create a new class from the scratch using JavaAssit. When we create new class files using JavaAssit we have to create all the methods in the new class as Strings and the pass them to Java Assist. As a example if we have to add amethod called sayHellow() to new class we can create it as a String like this.
String s="public void sayHello(){ System.out.println("Hello"); }

/**
     * @param c   Any class which can be used to get the class loader                          (c.getClassLoarder()) can be passed using object.getClass() methood
     * @param name
     *            Name of the to be generated class
     * @param methods
     *            Methods to be created as Strings
     * @param interfaces
     *            interfaces to be implemented as Strings
     * @param directory
     *            the directory generated class files has to be written
     */
    public static void createClass(Class<?> c, String name, List<String> methods,
            List<String> interfaces, String directory) {
        String temp = null;
        try {
            ClassPool pool = ClassPool.getDefault();
            pool.insertClassPath(new ClassClassPath(c));
            CtClass cc = pool.makeClass(name);
            if (interfaces != null) {
                for (String s : interfaces) {
                    CtClass anInterface = pool.get(s);
                    cc.addInterface(anInterface);
                }
            }
            for (String s : methods) {
                temp = s;
                CtMethod m = CtNewMethod.make(s, cc);
                cc.addMethod(m);
            }
            cc.writeFile(directory);
        } catch (Exception e) {
            // TODO throw
            System.out.println(temp);
            e.printStackTrace();
        }
    }

To add this class to the classpath following method can be used.

//Here directory is the path which class files were written

 public static Class loadClass(String className,String directory, ClassLoader loader) throws Exception {
        File f = new File(directory);
        java.net.URL[] urls = new java.net.URL[] { f.toURI().toURL() };
        ClassLoader cl = new URLClassLoader(urls, loader);
        Class cls = cl.loadClass(className);
        return cls;
    }

Note - JavaAssist does not support generics. If we use genarics java assist throws an exception. We have to use fully qualified names for types. As an example we have to use java.util.List for List type.