Monthly Archives: September 2015

Getting Started with vSphere EXSi — The Missing Tutorial

Getting Started with vSphere

Today, I got an opportunity to work with vSphere. The plan for the day was to install vSphere on one of our machine and then connect to it using a Python API so that we can launch virtual machines. The official documentation lacked clarity and it was not easy for a newbie like me to get started with vSphere. Throughout the day we faced numerous problems, stumbled across many blogs and vmware forum posts, and finally managed to create our first VM via the official vSphere Python API — pyvmomi. In this detailed blog, I will go over all the steps required to get started with vSphere. We will start with how to install vSphere on a machine, then look at how to install command-line client on a linux machine, and finally learn how to talk to the vSphere host using Python. This blog is a work in progress and I will continue updating it as I learn more about vSphere. Continue reading

GSON tip: Setting ISO 8601 Date Time format with nano second precision

Today, I had to parse an ISO 8601 date that was returned as part of a JSON response from a REST service. With default settings GSON can’t parse the date like 2015-09-22T17:21:32.70856998Z. To make it work, use the code shown below.

Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
                .setPrettyPrinting()
                .create();

Word count example in Java 8

Following code snippet shows how you can write a word count program using Java 8 Stream API.

public class WordCountExample {

    public static void main(String[] args) throws IOException {
        Path path = Paths.get("src/main/resources/book.txt");
        Map<String, Integer> wordCount = Files.lines(path)
           .flatMap(line -> Arrays.stream(line.trim().split(" ")))
           .map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
           .filter(word -> word.length() > 0)
           .map(word -> new SimpleEntry<>(word, 1))
           .sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
            .reduce(new LinkedHashMap<>(), (acc, entry) -> {
               acc.put(entry.getKey(), acc.compute(entry.getKey(), (k, v) -> v == null ? 1 : v + 1));
               return acc;
            }, (m1, m2) -> m1);

        wordCount.forEach((k, v) -> System.out.println(String.format("%s ==>> %d", k, v)));
    }
}

The better solution is using toMap collector as shown below.

public static void main(String[] args) throws IOException {
   Path path = Paths.get("src/main/resources/book.txt");
   Map<String, Integer> wordCount = Files.lines(path).flatMap(line -> Arrays.stream(line.trim().split("s")))
           .map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
           .filter(word -> word.length() > 0)
           .map(word -> new SimpleEntry<>(word, 1))
           .collect(toMap(e -> e.getKey(), e -> e.getValue(), (v1, v2) -> v1 + v2));

   wordCount.forEach((k, v) -> System.out.println(String.format("%s ==>> %d", k, v)));
}

Even better version can be written using grouping and counting collector as shown below.

public static void main(String[] args) throws IOException {
    Path path = Paths.get("src/main/resources/book.txt");
    Map<String, Long> wordCount = Files.lines(path).flatMap(line -> Arrays.stream(line.trim().split("\s")))
            .map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
            .filter(word -> word.length() > 0)
            .map(word -> new SimpleEntry<>(word, 1))
            .collect(groupingBy(SimpleEntry::getKey, counting()));

    wordCount.forEach((k, v) -> System.out.println(String.format("%s ==>> %d", k, v)));

}

GSON tip: @JsonProperty equivalent

Jackson has a very useful annotation @JsonProperty that gives developer the option to provide a name that will be used to map data from JSON to the value object. This is very useful when REST API you are interacting with does not follow conventions like some fields are caps, some camel case, and other using underscore. Today, I had a similar need but I was working with GSON library instead of Jackson. The solution in Gson is a similar annotation called @SerializedName that you can use to provide names that match the source JSON. A simple example is shown below.

public class Message{
    @SerializedName("ID")
    private String id;
    @SerializedName("NFd")
    private int fileDescriptors;
}

Gradle tip: Using gradle plugin from local maven repository

Today, I was trying to use a Gradle plugin that was currently not published to Bintray or any other public repository. I performed following actions to use that plugin in my project.

Step 1: Build the gradle plugin

Clone the gradle plugin to your local machine and run the following command to publish plugin to your local Maven repository.

$ ./gradlew clean build
$ ./gradlew publishToMavenLocal

Step 2: Add plugin to your project build.gradle

Once you have published your plugin to local Maven repository then you need to add the plugin to your project so that you can execute it. Add the following to your build.gradle.

apply plugin: 'my-demo-plugin'

buildscript{
  repositories {
      mavenLocal()

      dependencies{
        classpath 'io.shekhar.gradle.plugins:my-demo-plugin:0.1-SNAPSHOT'
      }
  }
}

In the build.gradle shown above we are applying our plugin my-demo-plugin using the apply plugin command. Then we used buildscript method to add our plugin to classpath. Also, we used local maven repo using mavenLocal() Gradle function.

Gson Tip: Using a different FieldNamingPolicy

Today, while write a client for a REST API I had the need to use a different field naming strategy than the default one. By default, when Gson tries to convert a JSON String to an object it expects field names in JSON to be same as field name in the converting object. For example, you can convert following JSON String to Message object as shown below.

{
"message": "hello world!"
}
public class Message{
private String message;
// setters and getters
}

To convert to message JSON to Message object you can use following code.

// String json
Message message = new Gson().fromJson(json, Message.class);

This will not work if JSON has different naming policy(first letter upper case) as shown below.

{
"Message": "hello world!"
}

To make it work, you can use GsonBuilder to create Gson with UPPER_CAMEL_CASE as field naming policy. This is shown below.

Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
Message message = gson.fromJson(json, Message.class);

Building Reactive Apps with RxJava and Java 8

Reactive programming is a programming paradigm geared around propagation of change. In other words, a program is expressed as a reaction to asynchronous event stream. Multiple consumers subscribe to an event stream and whenever there is a new event it is propagated to all the interested parties which can then react to the event. The canonical example of reactive programming is the modern spreadsheet like Microsoft Excel. In spreadsheet, you can set formulas such as “C1=A1*B1” to calculate product of values at cell A1 and B1. Whenever values of either A1 or B1 cell changes, the product will be recalculated and new value will be shown at cell C1. This is something that we can’t do natively in Java using just the core Java SDK. You can read the full blog at http://blog.xebia.in/2015/09/01/day1-building-an-application-from-scratch-using-rxjava-and-java8/