Saturday, 2 January 2016

UI for Zookeeper - zk-web

I have been using Zookeeper for the configuration management of my application. There are usually various configurations stored in zookeeper and sometimes it happens that we have to check the configuration values. Using zk-cli command line utility we can accomplish this however zk-cli is a command line tool and you need to learn commands in order get the information out of it.

So I was looking for a GUI Tool which would be simple and cleaner and luckily I found one known as zk-web (https://github.com/qiuxiafei/zk-web).

All the installation instruction can be found here (https://github.com/qiuxiafei/zk-web), However while installing it I faced some issues and thought it would be worth sharing all the steps to have a hassle free installation.

Prerequisites:
  • Java ( > Java 6 update 40 )
  • Git
  • Lien

Installing git:

sudo yum install git (My machine was amazon ec2 Linux)
sudo apt-get install git (If the machine is having ubuntu Linux)

NOTE: Make sure you are running on java version higher than java 6 update 40 If not upgrade the java version.

Cloning git repository for zk-web:

git clone git://github.com/qiuxiafei/zk-web.git

Configuration File:

cd zk-web/conf/

[ec2-user@ip-xx-xxx-x-xxx conf]$ cat zk-web-conf.clj
{
:server-port 8080
:users {"admin" "hello"}
:default-node ""
}

Installing lein:

wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
wget --no-check-certificate https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein

Move lein to ~/bin so that it will be available on PATH.

Grant execute permissions to lein:
cd ~/bin/
chmod 755 lein

To start zk-web run the below commands:
lein deps
lein run

Now the zk-web should be available at Your_IP:8080 URL.

Most of the time we want zk-web to run as a background process so that we can use it without the need to start it. In this scenario there is an option to generate a jar file using lein:

[ec2-user@ip-xx-xxx-x-xxx zk-web]$ cat project.clj
(defproject zk-web "0.1.0-SNAPSHOT"
     :description "FIXME: write this!"
     :dependencies [[org.clojure/clojure "1.4.0"]
       [noir "1.3.0-beta3"]
       [com.netflix.curator/curator-framework "1.1.16"]
       [com.netflix.curator/curator-test "1.1.16"]]
     :main zk-web.server)

Now using lein we have to build this clj(closure) file.
lein uberjar

This will build 2 jar files:
zk-web-0.1.0-SNAPSHOT.jar
zk-web-0.1.0-SNAPSHOT-standalone.jar

We have to use the second one which is a standalone jar. Below is command we can use to run this jar in background:
nohup java -jar target/zk-web-0.1.0-SNAPSHOT-standalone.jar &

As an alternative, we can put this command to /etc/rc.local file to start zk-web on machine reboot.

Monday, 7 December 2015

Writable redis slave

While working with redis, you may have a master redis running on a central server and all of your web application servers are running redis slaves. There may be some instances where you want to make these slaves writable for some testing purposes. Here is how we can accomplish this:

1. Load the data from master redis:
nohup /usr/bin/redis-server --port "slave port" --slaveof "Master Redis Machine IP" "Master Redis Port" > redis.out &

nohup /usr/bin/redis-server --port 7000 --slaveof 137.53.57.37 7000 > redis.out &

2. Kill the above redis process using kill command once the data is loaded.

3. Disconnect slave from master redis:
nohup /usr/bin/redis-server --port "slave port" --slaveof none "Master Redis Port" > redis.out &

nohup /usr/bin/redis-server --port 7000 --slaveof none 7000 > redis.out &

Now your slave is disconnected from master and you can write on it.

Monday, 16 November 2015

Grep/Search specific line number in linux/unix.

Today I had a situation where I had to search/grep for a specific line number in a file in linux. Here is the solution I found and thought it is worth sharing:

Uncompressed File:
cat test_file.csv | head -line_number | tail -1
cat test_file.csv | head -337930 | tail -1

Compressed File:
zcat test_file.gz | head -line_number | tail -1
zcat test_file.gz | head -337930 | tail -1

Above examples grep/search for line number 337930.

Tuesday, 3 November 2015

Webpage redirection

What happens if your visitors try to access a page that was recently renamed, deleted, or moved? By default they will get an error message, but you can change that. Instead of your visitors stumbling upon an error when trying to access such a page, you can set a redirection rule that will redirect them to a new page.

This page is about individual page redirection. For information on domain redirection check out our domain redirection tutorial.

NOTE: Redirection is very good for search engines. Search engines need to know when one of your files has changed locations to re-index your site properly.

301 and 302 redirects

There are two types of redirects - 301 and 302. These are actually HTTP status codes which specify the status of communication between the web browser and the web server.

The code samples below should be placed in the file you're redirecting from unless otherwise specified.

302 redirects

302 redirects are used when a page's location has been changed temporarily.

HTML

HTML 302 redirects work through the <meta> tag:

<meta http-equiv="refresh" content="10; url=http://www.site.com/newpage.html" />

In the content attribute, the number is the amount of seconds before redirecting to the new page specified by url.

Javascript

Javascript 302 redirects work through the window.location property:

<script type="text/javascript">
window.location="http://www.yahoo.com";
</script>

Set the window.location property equal to the URL you want to redirect to. Include this Javascript code in the head section of an HTML document. The redirect should occur right away.

PHP

PHP 302 redirects work through the header function:

<?php header("Location: http://www.site.com/newpage.html"); ?>

Inside the header() function, put Location: followed by the URL to redirect to.

.htaccess

Put this in your .htaccess file:

redirect 302 /oldfile.html http://www.yoursite.com/newfile.html

/oldfile.html is the location of the file you're redirecting from and http://www.yoursite.com/newfile.html is the location of the file you're redirecting to.

301 redirects

301 redirects are used when a page's location has been changed permanently.

PHP

PHP redirects are 302 redirects by default, but by putting the HTTP/1.1 301 code at the top, we create a PHP 301 redirect:

<?php
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://www.site.com/newpage.html");
?>


NOTE: When you use a PHP redirect make sure that the redirect code is the only thing on the page that you are redirecting from.

.htaccess

Put this in your .htaccess file:

redirect 301 /oldfile.html http://www.yoursite.com/newfile.html

/oldfile.html is the location of the file you're redirecting from and http://www.yoursite.com/newfile.html is the location of the file you're redirecting to.

Saturday, 17 October 2015

Imitating domain names in linux.

Sometimes we may have to simulate different domains in our local machine. For example If you want to use domain "awesome.com" in place of localhost you can do the following:

You must be having below entry in your /etc/hosts file:

  127.0.0.1 localhost

Change this entry as given below:

  127.0.0.1 awesome.com

And you are done. Hit "awesome.com" from your browser and the request will come to your localhost. Similarly you can do multiple entries in /etc/hosts to simulate multiple domains.

Thursday, 17 September 2015

isNumeric in Java.

Once in while in java we might have to check If a passed string to method is a valid numerical value. Below are some utility methods to accomplish this:

    Using java.text.NumberFormat.


    public static boolean isNumeric(final String str) {
        try {
            Double.parseDouble(str);
        } catch (final NumberFormatException | NullPointerException e) {
            return false;
        }

        return true;
    }

    JUnit Test Case:


        Assert.assertEquals(false, yourClass.isNumeric(null));
        Assert.assertEquals(false, yourClass.isNumeric(""));
        Assert.assertEquals(true, yourClass.isNumeric("2.74"));
        Assert.assertEquals(true, yourClass.isNumeric("2.745435E3"));
        Assert.assertEquals(true, yourClass.isNumeric("0"));
        Assert.assertEquals(true, yourClass.isNumeric("0.0f"));
        Assert.assertEquals(false, yourClass.isNumeric("NaN"));       


    Using Double.parseDouble.


     public static boolean isNumeric(final String string) {
        try {
            NumberFormat.getInstance().parse(string);
        } catch (ParseException | NullPointerException e) {
            return false;
        }

        return true;
    }

    JUnit Test Case:


        Assert.assertEquals(false, yourClass.isNumeric(null));
        Assert.assertEquals(false, yourClass.isNumeric(""));
        Assert.assertEquals(true, yourClass.isNumeric("2.74"));
        Assert.assertEquals(true, yourClass.isNumeric("2.745435E3"));
        Assert.assertEquals(true, yourClass.isNumeric("0"));
        Assert.assertEquals(true, yourClass.isNumeric("0.0f"));
        Assert.assertEquals(true, yourClass.isNumeric("NaN"));


As you guys might have noticed that I have an assert statement for both the methods which checks the method against string "NaN". The thing which makes this more interesting is that the method which uses NumberFormat returns false for this string while the method which uses Double.parseDouble(string) returns true.

You might say that the method which uses NumberFormat is correct because "NaN" is technically just a mere string value. Below is the description of how java treats "NaN" while doing floating-point operations :

"NaN" stands for "not a number". "Nan" is produced if a  floating point operation has some input parameters that cause the operation to produce some undefined result. For example, 0.0 divided
by 0.0 is arithmetically undefined. Taking the square root of a negative number is also undefined.


That's all for now folks stay tuned for new posts !!!!!!!!

 
 
 



Saturday, 5 September 2015

Jetty - Enabling request logs

Whenever you start jetty using jetty.sh shell script located inside jetty's bin folder, the jetty will start with the below logs enabled defined inside /opt/jetty/start.ini file (defined using xml files) by default:

etc/jetty.xml
etc/jetty-annotations.xml
etc/jetty-deploy.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml

Below is the snapshot of the /opt/jetty/start.ini file to show complete set of configuration files:

#===========================================================
# Configuration files.
# For a full list of available configuration files do
#   java -jar start.jar --help
#-----------------------------------------------------------
#etc/jetty-jmx.xml
etc/jetty.xml
etc/jetty-annotations.xml
# etc/jetty-ssl.xml
# etc/jetty-requestlog.xml
etc/jetty-deploy.xml
#etc/jetty-overlay.xml
etc/jetty-webapps.xml
etc/jetty-contexts.xml
etc/jetty-testrealm.xml
#===========================================================

As highlighted in the above configuration the request log xml file is commented by default. We just have to uncomment the same and restart jetty to enable request logs and you should be able to see the request logs generated in the below directory:

/opt/jetty/logs

$ ls -lt
total 48
-rw-rw-r-- 1 jetty jetty  165 Aug 21 13:54 2015_08_21.request.log