Monday, April 28, 2014

How to pass parameters to your webstart?

Add properties in the JNLP file itself, like so

<resources> 
<j2se version="1.7+" />  
... 
...  
<property name="prop1" value="value1"/> 
<property name="prop2" value="value2"/>  
</resources>

and then call it in your code, like so

System.getProperty("prop1"); 

Where am I?

While calling something like

FileInputStream stream = new FileInputStream("myfile.properties");

you might see Filenotfound exception... But it used to work before, you might say. Well, it probably did before you called this method from a different directory. Use following statement to get user's current working directory.

System.getProperty("user.dir")

Sunday, April 13, 2014

Connecting to the Accumulo using Java

Now that our Accumulo is set up, let’s connect to it through Java App so we can create our first table and write some data into it.

(I am going to assume that you have maven installed on your machine… If not, see this)

Create simple maven project.
mvn archetype:generate -DgroupId=org.mytest.accexample -DartifactId=simple -Dpackage=org.mytest.accexample -Dversion=1.0-SNAPSHOT

Accept all defaults.

Since we will be connecting to Accumulo, it comes to no surprise that we would need jars to support Accumulo, Zookeeper and Hadoop. So add this to your pom.xml file

  <dependency>
   <groupId>org.apache.accumulo</groupId>
   <artifactId>accumulo-core</artifactId>
   <version>1.4.4</version>
  </dependency>
  <dependency>
   <groupId>org.apache.hadoop</groupId>
   <artifactId>hadoop-core</artifactId>
   <version>1.2.1</version>
  </dependency>
  <dependency>
   <groupId>org.apache.zookeeper</groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.4.5</version>
  </dependency>

Now it is time to write a program to connect to our Accumulo instance and put some records in!

package org.mytest.accexample;

import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.Instance;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.ZooKeeperInstance;
import org.apache.accumulo.core.client.admin.TableOperations;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.ColumnVisibility;
import org.apache.hadoop.io.Text;

public class App {

 public static void main(String[] args) throws AccumuloException, AccumuloSecurityException,TableNotFoundException, TableExistsException {
        // Constants
        String instanceName = "default";
        String zooServers = ""; // Provide list of zookeeper server here. In our case, we had just one so localhost:2181 should do
        String userName = ""; // Provide username
        String password = ""; // Provide password
        // Connect
        Instance inst = new ZooKeeperInstance(instanceName,zooServers);
        Connector conn = inst.getConnector(userName, password);
       // Let’s create our new table
        String tableName = "myTable";
        TableOperations ops = conn.tableOperations();
         if (ops.exists(tableName)) {
            ops.delete(tableName);
        }
        ops.create(tableName);
        // Use batch writer to write demo data
        BatchWriter bw = conn.createBatchWriter(tableName,1000000, 60000, 2);
        // set values
        Text rowID = new Text("row1");
        Text colFam = new Text("colFam");
        Text colQual = new Text("colQual");
        // set value
        Value value = new Value("some-value".getBytes());
        // create new mutation and add rowID, colFam, colQual, and value
        Mutation mutation = new Mutation(rowID);
        mutation.put(colFam, colQual, value);
        // add the mutation to the batch writer
        bw.addMutation(mutation);
        // close the batch writer
        bw.close();
    }
}

Run it… Congratulations you just wrote your first record into Accumulo! Now let’s view it in the table just to make sure it is indeed there.

Let’s take a different approach and access Accumulo through bash shell.
$ACCUMULO_HOME/bin/accumulo shell -u [username]

Then provide your password.

Type ‘tables’ to see a list of available tables. You should see myTable in the list.
Type ‘table myTable’ to access it. Now execute simple scan to view your records.
root@default myTable> table myTable
root@default myTable> scan
row1 colFam:colQual []    some-value

Success!

Now, what’s that security level stuff in Accumulo everyone is talking about? Well, it is a way to ensure that only rows that fit your authorization will be shown to you. That’s it in the nutshell, for more in details explanation please refer to this.

Let’s add this to our Java App Accumulo writer. Add ColumnVisibility variable and add it to the mutation object. Here is the complete example with changes highlighted in red:

package org.mytest.accexample;

import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.BatchWriter;
import org.apache.accumulo.core.client.Connector;
import org.apache.accumulo.core.client.Instance;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.ZooKeeperInstance;
import org.apache.accumulo.core.client.admin.TableOperations;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.ColumnVisibility;
import org.apache.hadoop.io.Text;

public class App {

 public static void main(String[] args) throws AccumuloException, AccumuloSecurityException,TableNotFoundException, TableExistsException {
        // Constants
        String instanceName = "default";
        String zooServers = "";
        String userName = "";
        String password = "";
        // Connect
        Instance inst = new ZooKeeperInstance(instanceName,zooServers);
        Connector conn = inst.getConnector(userName, password);
        String tableName = "myTable";
        TableOperations ops = conn.tableOperations();
         if (ops.exists(tableName)) {
            ops.delete(tableName);
        }
        ops.create(tableName);
        // Use batch writer to write demo data
        BatchWriter bw = conn.createBatchWriter(tableName,1000000, 60000, 2);
        // set values
        Text rowID = new Text("row1");
        Text colFam = new Text("colFam");
        Text colQual = new Text("colQual");
        // set visibility
        ColumnVisibility colVis = new ColumnVisibility("public");

        // set value
        Value value = new Value("some-value".getBytes());
        // create new mutation and add rowID, colFam, colQual, and value
        Mutation mutation = new Mutation(rowID);
        mutation.put(colFam, colQual, colVis, value);
        // add the mutation to the batch writer
        bw.addMutation(mutation);
        // close the batch writer
        bw.close();
    }
}

Run the example again… Now log into Accumulo shell and scan the myTable. You won’t see anything! What?

Well, you just wrote a record that would be shown only to users with authorization to view ‘public’ rows. What can you view right now for your user? Run ‘getauths’ command in the shell to find out.

‘public’ auth was probably not in the list, hence inability to see the freshly inserted record.

Let’s add ‘public’ to the list of authorizations. Run following command from the bash
root@default myTable> setauths -s public

Now run the scan and you should be able to see the row. Notice ‘public’ in square brackets
root@default myTable> scan
row1 colFam:colQual [public]    some-value

In summary, we were able to write a java client that would communicate with Accumulo instance and would insert a record. We used Accumulo bash shell to view the record. We also briefly touched on cell level security.

Reference:
1. Accumulo Shell Command Guide.
2. Accumulo Visibility.

Thursday, April 10, 2014

Run your jar as a server on Linux

Recently, I was experimenting with Apache Thrift. Then I decided to upload my server jar file onto RHEL server and connect to it with my client from my machine.

The set up was pretty simple. I generated jar file with NetBeans. This gave me actual jar file and a lib folder. I uploaded them to RHEL server and ran it

 java -cp AdditionThriftSample.jar com.blogspot.alkrinker.samples.thrift.server.MyServer

Saw

Starting the simple server on 9091...

and I was able to connect to it from my Thrift client.

Now... I wanted to go a step further and make my thrift server to be a service. Here is what I did:

Create the start and the stop script of your application. Make sure to chmod them so they can be executed. Put it on some directory, in our example is:
  • Start Script: /usr/local/bin/AdditionThriftSample-start.sh
  • Stop Script: /usr/local/bin/AdditionThriftSample-stop.sh
Sample of the AdditionThriftSample-start.sh content:
#!/bin/bash java -cp AdditionThriftSample.jar com.blogspot.alkrinker.samples.thrift.server.MyServer

Sample of the stop script:
#!/bin/bash
# Grabs and kill a process from the pidlist that has the word myapp
pid=`ps aux | grep AdditionThriftSample | awk '{print $2}'`
kill -9 $pid

Now make it a service! Create the following script (thriftserver) and put it on /etc/init.d.
/etc/init.d/thriftserver content:

#!/bin/bash
# thriftserver
#

case $1 in
    start)
        /bin/bash /usr/local/bin/AdditionThriftSample-start.sh
    ;;
    stop)
        /bin/bash /usr/local/bin/AdditionThriftSample-stop.sh
    ;;
    restart)
        /bin/bash /usr/local/bin/AdditionThriftSample-stop.sh
        /bin/bash /usr/local/bin/AdditionThriftSample-start.sh
    ;;
esac
exit 0

Put the script to start with the system (using SysV). Just run the following command (as root):

update-rc.d thriftserver defaults 
 
Credits:

Monday, April 7, 2014

Working Java REST Client Example to access CAS REST API

Ever wondered how to expose REST API in your CAS server? Well, the documentation is there, but I failed to find step-by-step guide... I ended up writing one and sharing it on stackoverflow website. Here is the link: Working Java REST Client Example to access CAS REST API . Enjoy and feel free to ask questions as always.