Wednesday, November 6, 2013

VIM as an IDE

Why vim? There are lots of text-editors & IDEs out there.Over last 7 years I have used several text-editors & IDEs.But for me simply I'm not a fan of IDEs.

I love the ability of customization and the lightweight of VIM over other text-editors and IDEs. If you are a newbie to VIM, you might feel uncomfortable until you get familiar with basic commands. You can find number of VIM cheat sheets here[1] to learn all VIM commands.
 
You may feel few OOTB IDE features missing in VIM, once you start to code with VIM. BIG NOOOO !!! How to browse files, how to search, search and replace, how to work with multiple files etc. I will address those further within this post.

When I want to browse project directories(file system) while coding simply use the command :NERDTree. You can download this plugin from[2] and extract the downloaded content to .vim directory located under your home directory. I'm using nerdtree 4.2.0 latest version available at the moment.After extracting you can find several directories under .vim as in following screen shot.


Thats it. Now simply open a text file from your project directory, and type :NERDTree hit enter.


You can navigate between directories/files in file-system with the use of arrow keys or with the mouse and select files by hitting enter. This plugin is really helpful when you are working with a huge code base within your project.

Now lets move to the find/replace in VIM, following are few commands we can use.
/text      - search for text
?text      - search backward for text
n          - repeat search in same direction
:%s/old/new- replace all old with new throughout file
Lets talk about syntax highlighting ability of VIM now. At the moment I'm working on WSO2 Enterprise Store project which written on top of the WSO2 Carbon platform. If you browse though this product you can find that VIM needs to coupe with number of file types here. For eg :- .jag (jaggery.js file extention), .js, .hbs, .css etc.

For unknown(unknown to VIM) file types like .hbs you can enable syntax highlighting(as HTML in my scenario) by simply adding, au BufReadPost *.hbs set syntax=html  to your .vimrc. You can find .vimrc under your home directory.

Before enabling syntax highlighting for .hbs file format,


after enabling syntax highlighting,


And the best thing is that this VIM configuration is so portable, you only need to replace default .vimrc with your customized version in any distribution.

You can download and install VIM from here[3].

[1] http://www.worldtimzone.com/res/vi.html
      http://www.fprintf.net/vimCheatSheet.html
[2] http://www.vim.org/scripts/script.php?script_id=1658
[3] http://www.vim.org/download.php

Monday, November 4, 2013

image sprites- Optimize your webApp

What is an image sprite? If you need a number of images regularly to render your web-app on a browser, you can have those in a single image rather than having multiple images.This single image is known as a sprite image.

What you gain from this approach? It will take only one HTTP request to render all your images so you can reduce the time to load your web-app.This approach will give a better image compression also.

How to use image sprites,



Lets say you are going to develop a web-app with the use of above sample sprite.Lets assume this sample contains 60, 40X40 icons in a single 480X200 file.

If we require the facebook icon, we can use CSS to show the correct image by positioning the background:

#facebook{
left:80px;
width: 40px;
background: url("sprite.jpg") 0 0;
}

Friday, October 25, 2013

MongoDB - usage of Primary Key

Like other databases MongoDB also uses primary keys to distinguish documents.
We can provide our own, otherwise MongoDB will create itself a primary key for each document. This key is a Object which consists of time-stamp and information about the machine which document created.

How to provide our own primary key

$connection = new Mongo( "10.100.0.128:27017" );
$db = $connection->selectDB("primary_key_blog");
$collection = $db->blog_collection;
$collection.insert({ _id: 1, author: "UdaraR", blog: "http://udarakr.blogspot.com" });

else we can just say,

$collection.insert({author: "UdaraR", blog: "http://udarakr.blogspot.com" });

If we read the document we stored back,
 $collection->findone( array( "author" => "UdaraR" ) );
You can see that MongoDB itself added the 12 bytes ObjectId.

The greatest thing in the second method is that you can extract created-time without storing it separately. You can simply use ObjectId.getTimestamp() method to get this done.
ObjectId("507c7f79bcf86cd7994f6c0e").getTimestamp();
Other than the above usage, as in all other databases the primary usage will be to query using the ObjectId.

$id = new MongoId("507c7f79bcf86cd7994f6c0e");
$collection->findone( array( "_id" => $id ) );
Keep in mind this is not equal to string "507c7f79bcf86cd7994f6c0e".

Other than findone, we can provide this ObjectId with find, remove, update etc.

Tried this sample on linux environment with the use of mongo driver.

Friday, October 4, 2013

Git push requires username and password ??

This post will help to overcome Github username password request during every git push. Instead of using SSH we use HTTPS to clone the repo and then every time you try to push to Github it will ask for your username and password for https://github.com.









To overcome this situation you can change the URL of your origin remote by using,

git remote set-url origin git@github.com:username/repo.git
In my scenario its,

git remote set-url origin git@github.com:wso2/enterprise-store.git
You can find the "git@github.com:username/repo.git" by browsing the Github repository and copying the SSH clone URL.


Thursday, September 12, 2013

ActiveMQ with PHP

First you need to download and configure ActiveMQ, You can find latest ActiveMQ release from[1].

Download latest release from http://www.apache.org/dyn/closer.cgi?path=/activemq/apache-activemq/5.8.0/apache-activemq-5.8.0-bin.tar.gz


Step1 : svn co http://svn.apache.org/repos/asf/activemq/tags/activemq-x.x.x

At the date of writing this post , ActiveMQ 5.8.0 is the latest release. So here after lets replace x.x.x with 5.8.0.


Step 2 : go to the activemq directory cd activemq-5.8.0/

Step 3 : Run mvn clean install to build ActiveMQ from source. This step will take a while.

Step 4 :  Edit <ACTIVEMQ_HOME>/conf/activemq.xml and add following transport connector.

 <transportConnector name="stomp" uri="stomp://localhost:61613"/>
Step5 : Start ActiveMQ: <ACTIVEMQ_HOME>/bin/activemq console
Step6 : Install PHP stomp extension pear install stomp.If you don't have pear package installed, run sudo apt-get install php-pear first.

Lets move to the PHP side now, we need to write two snippets one to publish messages another one to subscribe previously published messages.

First the publisher, create publisher.php inside /var/www/activemqsample/ directory with following content.

<?php
$queue  = 'ActiveMQ';
$msg    = 'ActiveMQ with PHP';

try {
    $stomp = new Stomp('tcp://localhost:61613');
    while (true) {
      $stomp->send($queue, $msg);
      sleep(1);
    }
} catch(StompException $e) {
    die('Connection error: '.$e));
}
?>
 Then the subscriber, create subscriber.php inside /var/www/activemqsample/ directory with following content.
<?php
$queue  = 'ActiveMQ';

try {
    $stomp = new Stomp('tcp://localhost:61613');
    $stomp->subscribe($queue);
    while (true) {
       if ($stomp->hasFrame()) {
           $frame = $stomp->readFrame();
           if ($frame != NULL) {
               print "Received: ".$frame->body;
               $stomp->ack($frame);
           }
       }

    }
} catch(StompException $e) {
    die('Connection error: ' . $e);
}
?>
Now you can test the sample php application by running,
php publisher.php and php subscriber.php within /var/www/activemqsample/ directory.


[1] http://activemq.apache.org/download.html

Wednesday, September 11, 2013

How to overcome WSO2 message broker OutOfMemory error

You many face difficulties when running WSO2 Message Broker with in-built Cassandra server as you are unable to allocate min memory requirement.

TID: [0] [MB] [2013-09-10 07:31:15,892] ERROR {org.wso2.andes.transport.network.mina.MinaNetworkHandler} - Exception caught by Mina {org.wso2.andes.transport.network.mina.MinaNetworkHandler} java.io.IOException: An established connection was aborted by the software in your host machine at sun.nio.ch.SocketDispatcher.read0(Native Method) at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:25) at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:198) at sun.nio.ch.IOUtil.read(IOUtil.java:171) at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:243) at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:218) at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:198) at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$400(SocketIoProcessor.java:45) at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:485) at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51) at java.lang.Thread.run(Thread.java:662)
TID: [0] [MB] [2013-09-10 07:33:59,226] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@3daf57b4 {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,226] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@42a70a0f {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@648580f8 {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@78d64d56 {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@3d6f8714 {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@650d518e {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@4d657576 {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@4002bdac {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@73f28808 {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@37c100b0 {org.wso2.andes.server.queue.QueueEntryImpl} TID: [0] [MB] [2013-09-10 07:33:59,242] WARN {org.wso2.andes.server.queue.QueueEntryImpl} - Requesting rejection by null subscriber:org.wso2.andes.server.queue.QueueEntryImpl@60143f68 {org.wso2.andes.server.queue.QueueEntryImpl}


TID: [0] [MB] [2013-09-10 07:55:59,188] ERROR {org.wso2.andes.server.protocol.AMQProtocolEngine} - IOException caught in/192.168.2.84:50034(admin), session closed implictly: java.io.IOException: An existing connection was forcibly closed by the remote host {org.wso2.andes.server.protocol.AMQProtocolEngine} TID: [0] [MB] [2013-09-10 08:12:15,079] INFO {org.wso2.andes.server.stats.PerformanceCounter} - PerfCountFDAutoRenewalWriteQueue_1:14000/0 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], tot=15035/5751 {org.wso2.andes.server.stats.PerformanceCounter} TID: [0] [MB] [2013-09-10 08:20:22,065] ERROR {org.wso2.andes.server.cassandra.QueueDeliveryWorker} - Error running Cassandra Message FlusherJava heap space {org.wso2.andes.server.cassandra.QueueDeliveryWorker} java.lang.OutOfMemoryError: Java heap space at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:39) at java.nio.ByteBuffer.allocate(ByteBuffer.java:312) at org.wso2.andes.server.store.CassandraMessageStore$StoredCassandraMessage.<init>(CassandraMessageStore.java:4122) at org.wso2.andes.server.store.CassandraMessageStore$StoredCassandraMessage.<init>(CassandraMessageStore.java:4106) at org.wso2.andes.server.store.CassandraMessageStore.getMessagesFromNodeQueue(CassandraMessageStore.java:873) at org.wso2.andes.server.cassandra.QueueDeliveryWorker.run(QueueDeliveryWorker.java:241) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662



So the best practice is to have an external Cassandra server configured with WSO2 Message Broker, where you can have at least "2048M" for MAX_HEAP_SIZE or more if you face OutOfMemory exceptions.

You can find the complete installation guide [1].

[1] http://docs.wso2.org/display/MB210/Standalone+Deployment+on++External+Cassandra+Server

Tuesday, September 10, 2013

Query cassandra within jaggery.js

jaggery.js at 0.9.0-ALPHA-3 does not have Cassandra database engine support out of the box.

So you need to place cassandra connector libs within {JAGGERY_HOME}/carbon/repository/components/lib/ directory or use Cassandra feature enabled carbon product.

I'm going to use enterprise-store[1] from the branch social to develop this sample script.

Create jaggery file select.jag inside your jaggery app.

and put the following script inside select.jag,

<%
var db = new Database("jdbc:cassandra://localhost:9160/EVENT_KS","admin","admin",{"driverClassName":"org.apache.cassandra.cql.jdbc.CassandraDriver"});
var result;
db.query("USE EVENT_KS");
result = db.query("SELECT * FROM org_wso2_bam_phone_retail_store_kpi");
print(result);

%>

This[2] might help to publish data into Cassandra within jaggery.

[1] https://github.com/wso2/enterprise-store
[2] http://udarakr.blogspot.com/2013/09/publish-data-to-cassandra-from.html