How to get Git information in Java Application

In this post, we are going to see how to get the GIT information in a Java application.

To do that, we have to use the maven-git-commit-id-plugin plugin. Refer it @maven-git-commit-id-plugin

Now let’s see how we gonna do that.

1. Include the below plugin configuration in your Maven POM file.


  <plugin>
                <groupId>pl.project13.maven</groupId>
                <artifactId>git-commit-id-plugin</artifactId>
                <version>2.1.13</version>
                <executions>
                    <execution>
                        <id>populate-git-commit-information</id>
                        <goals>
                            <goal>revision</goal>
                        </goals>
                        <configuration>
                            <verbose>true</verbose>
                            <dateFormat>MM/dd/yyyy HH:mm:ss Z</dateFormat>
                            <abbrevLength>8</abbrevLength>
                            <generateGitPropertiesFile>true</generateGitPropertiesFile>
                            <generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
                        </configuration>
                    </execution>
                </executions>
                <configuration>
                    <dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
                </configuration>
            </plugin> 
            

2. Then do maven install (mvn install). You can set the verbose as false if you don’t want to see the git commit id plugin log.

3. After the build is done, then go to target/classes folder. You will see git.properties contains the git related information. You can read this properties file in your application and use it.

Sample code is given below.


 static Properties properties = new Properties();
    static{
        try (InputStream is = this.class.getClassLoader()
                .getResourceAsStream("git.properties")) {
            properties.load(is);
        }
        catch (IOException io) {
            io.printStackTrace();
        }
    }

File Name: git.properties
File Path: /target/classes/git.properties
Sample properties are given below.



#Generated by Git-Commit-Id-Plugin
#Fri Nov 17 09:49:44 EST 2017
git.tags=
git.commit.id.abbrev=8ef4712a
git.commit.user.email=dkbalachandar@gmail.com
git.commit.message.full=Update Dockerfile
git.commit.id=8ef4712acd077d89b875c5bf67c20af1dbb8bb24
git.commit.id.describe-short=8ef4712-dirty
git.commit.message.short=Update Dockerfile
git.commit.user.name=Balachandar
git.build.user.name=Balachandar
git.commit.id.describe=8ef4712-dirty
git.build.user.email=dkbalachandar@gmail.com
git.branch=master
git.commit.time=09/19/2017 18\:25\:16 -0400
git.dirty=true
git.build.time=11/17/2017 09\:49\:44 -0500
git.remote.origin.url=https\://github.com/dkbalachandar/java-rest-docker.git


Refer my code @java-rest-docker

Advertisements

Curl Commands – Example

Curl command to fetch the response and HTTP status code


Command: 
curl -s -w '%{http_code}' -X GET ${SERVICE_URL}

s flag denotes silent output and w flag denotes write out the http_code in the output data.

Example:
curl -s -w '%{http_code}' -X GET 'https://openlibrary.org/api/books?bibkeys=ISBN:0201558025,LCCN:93005405&format=json'

Sample output:

curl -s -w '%{http_code}' -X GET 'https://openlibrary.org/api/books?bibkeys=ISBN:0201558025,LCCN:93005405&format=json'
{"LCCN:93005405": {"bib_key": "LCCN:93005405", "preview": "noview", "thumbnail_url": "https://covers.openlibrary.org/b/id/240726-S.jpg", "preview_url": "https://openlibrary.org/books/OL1397864M/Zen_speaks", "info_url": "https://openlibrary.org/books/OL1397864M/Zen_speaks"}, "ISBN:0201558025": {"bib_key": "ISBN:0201558025", "preview": "restricted", "thumbnail_url": "https://covers.openlibrary.org/b/id/135182-S.jpg", "preview_url": "https://archive.org/details/concretemathemat00grah_444", "info_url": "https://openlibrary.org/books/OL1429049M/Concrete_mathematics"}}200


To fetch the HTTP header alone.


curl -I -X GET 'https://openlibrary.org/api/books?bibkeys=ISBN:0201558025,LCCN:93005405&format=json'

To print the CURL version information along with the response.


curl -v -X GET 'https://openlibrary.org/api/books?bibkeys=ISBN:0201558025,LCCN:93005405&format=json'

To extract out the HTTP status code


curl -I -s -X GET 'https://openlibrary.org/api/books?bibkeys=ISBN:0201558025,LCCN:93005405&format=json' | grep 'HTTP/1.1' | awk '{print $2}'

How to use HK2 injection in a Standalone Java Application

In this post, we are going to see how we can use the HK2 injection framework in a standalone Java application.

We need to include the below hk2 dependencies in our pom file. Here is the pom file.


 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <name>Hk2 Java standlaone application</name>
    <version>1.0.0</version>
    <artifactId>hk2-java-sample</artifactId>
    <groupId>com</groupId>
    <properties>
        <commons-lang3-v>3.6</commons-lang3-v>
        <maven-compiler-plugin-v>3.7.0</maven-compiler-plugin-v>
        <hk2-v>2.5.0-b36</hk2-v>
        <junit-v>4.12</junit-v>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3-v}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit-v}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.hk2</groupId>
            <artifactId>hk2</artifactId>
            <version>${hk2-v}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.hk2</groupId>
            <artifactId>hk2-junitrunner</artifactId>
            <version>${hk2-v}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin-v}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.glassfish.hk2</groupId>
                <artifactId>hk2-inhabitant-generator</artifactId>
                <version>${hk2-v}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate-inhabitants</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Consider that, we have a standalone application which will be used for adding, deleting, updating the employee details and the back end is a HashMap.

We have two interfaces(EmployeeService and EmployeeDao) and its implemetation classes(EmployeeServiceImpl and EmployeeDaoImpl) in this application.

To make use of HK2 injection, All our interfaces should be annotated with @Contract and all the implementation classes should be annotated with @Service.

Refer the below code to know how to do that.


package com.service;

import com.model.Employee;
import org.jvnet.hk2.annotations.Contract;

@Contract
public interface EmployeeService {
    public Employee fetch(String id);
    public Employee add(Employee employee);
    public void delete(String id);
    public Employee update(Employee employee);
}



package com.service.impl;

import com.dao.EmployeeDao;
import com.model.Employee;
import com.service.EmployeeService;
import org.jvnet.hk2.annotations.Service;

import javax.inject.Inject;
import java.util.UUID;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    private EmployeeDao employeeDao;

    @Inject
    public EmployeeServiceImpl(EmployeeDao employeeDao){
        this.employeeDao = employeeDao;
    }

    @Override
    public Employee fetch(String id) {
        return employeeDao.fetch(id);
    }

    @Override
    public Employee add(Employee employee) {
        employee.setId(UUID.randomUUID().toString());
        return employeeDao.add(employee);

    }

    @Override
    public void delete(String id) {
        employeeDao.delete(id);
    }

    @Override
    public Employee update(Employee employee) {
        return employeeDao.update(employee);
    }
}



package com.dao;

import com.model.Employee;
import org.jvnet.hk2.annotations.Contract;

@Contract
public interface EmployeeDao {

    public Employee fetch(String id);
    public Employee add(Employee employee);
    public void delete(String id);
    public Employee update(Employee employee);
}


package com.dao.impl;

import com.dao.EmployeeDao;
import com.model.Employee;
import org.jvnet.hk2.annotations.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class EmployeeDaoImpl implements EmployeeDao {

    private static Map empLocalCache = new HashMap();

    public Employee fetch(String id) {
        return empLocalCache.get(id);
    }

    public Employee add(Employee employee) {
        empLocalCache.put(employee.getId(), employee);
        return empLocalCache.get(employee.getId());
    }

    public void delete(String id) {
        empLocalCache.remove(id);
    }

    public Employee update(Employee employee) {
        empLocalCache.put(employee.getId(), employee);
        return empLocalCache.get(employee.getId());
    }
}


Below is my main class which will use the Employee service class to perform add, update and delete operations with Employee Object.


package com;

import com.model.Employee;
import com.service.EmployeeService;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;

public class Application {

    public static void main(String[] args) {

        ServiceLocator serviceLocator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
        EmployeeService employeeService = serviceLocator.getService(EmployeeService.class);
        Employee employee = new Employee();
        employee.setFirstName("First Name");
        employee.setLastName("Last Name");

        System.out.println("Add employee details");
        Employee employeeAddResponse = employeeService.add(employee);
        System.out.println("The employee details after it has been added Employee: "+employeeAddResponse);

        System.out.println("Now fetch the employee details with ID");
        Employee employeeFetchResponse = employeeService.fetch(employee.getId());
        System.out.println("Employee :"+employeeFetchResponse);

        System.out.println("Now update the employee details");
        employee.setFirstName("Bala");
        employee.setLastName("Samy");
        Employee employeeUpdateResponse = employeeService.update(employee);
        System.out.println("Employee After Updation:"+employeeUpdateResponse);

        System.out.println("Now delete the employee details");
        employeeService.delete(employee.getId());
        System.out.println("Employee After Deletion:"+ employeeService.fetch(employee.getId()));

    }
}


To initialize all the HK2 dependencies, we have to call the ServiceLocatorUtilities.createAndPopulateServiceLocator() which will perform the initialization and return the ServiceLocator object.

We can make use of ServiceLocator object for getting the Object instance like below

EmployeeService employeeService = serviceLocator.getService(EmployeeService.class);

Before executing this, we need to do an important step which is to create the hk2 default file under our target/classes/META-INF folder. The hk2-inhabitant-generator plugin will help us to generate that file. Hence we need to include this plugin in our file. So we have to do maven install/package before we start executing our junit test cases.

The sample default file content will be like this,

#
# Generated on Thu Nov 09 17:04:57 EST 2017 by hk2-inhabitant-generator
#

[com.dao.impl.EmployeeDaoImpl]S
contract={com.dao.EmployeeDao}

[com.service.impl.EmployeeServiceImpl]S
contract={com.service.EmployeeService}

The output of my program is given below,



Add employee details
The employee details after it has been added Employee: Employee{id='f25b119a-820e-4162-af99-5c3580fe06f1', firstName='First Name', lastName='Last Name}
Now fetch the employee details with ID
Employee :Employee{id='f25b119a-820e-4162-af99-5c3580fe06f1', firstName='First Name', lastName='Last Name}
Now update the employee details
Employee After Updation:Employee{id='f25b119a-820e-4162-af99-5c3580fe06f1', firstName='Bala', lastName='Samy}
Now delete the employee details
Employee After Deletion:null


 

Refer the code @hk2-java-sample

 

 

Apache Commons CSV

Apache Commons CSV library is used for creating and reading CSV files.

In this post, we are going to see, how we can use this library with an example.

First thing is to include the below dependency in your maven pom file.


 <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-csv</artifactId>
            <version>1.5</version>
  </dependency>

Consider that the employee information is available in a CSV file called (employee.csv). The sample data are given below.

Id First Name Last Name Age
1 John Arthur 25
2 Sam Andrew 26
3 Hary Peter 26

Let’s see how we can read this CSV file in a Java Program with Commons CSV.



import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

public class ReadCSVFileMain {

    public static void main(String[] args) throws IOException {

        String filePath = "/tmp/employee.csv";
        List employeeList = new ArrayList();
        Reader reader = null;
        try {
            String[] headers = { "Id", "First Name", "Last Name", "Age" };
            reader = new FileReader(filePath);
            Iterable records = CSVFormat.DEFAULT.withHeader(headers).withFirstRecordAsHeader().parse(reader);
            records.forEach(csvRecord -> {
                Employee employee = new Employee();
                employee.setId(Integer.valueOf(csvRecord.get("Id")));
                employee.setFirstName(csvRecord.get("First Name"));
                employee.setLastName(csvRecord.get("Last Name"));
                employee.setAge(Integer.valueOf(csvRecord.get("Age")));
                employeeList.add(employee);
            });
        }

        finally {
            if (reader != null) {
                reader.close();
            }
        }
        System.out.println("Parsed Content: employeeList::" + employeeList);
    }
}



public class Employee {

    private Integer id;
    private String firstName;
    private String lastName;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Employee{");
        sb.append("id=").append(id);
        sb.append(", firstName='").append(firstName).append('\'');
        sb.append(", lastName='").append(lastName).append('\'');
        sb.append(", age=").append(age);
        sb.append('}');
        return sb.toString();
    }

}


The above program is used to parse the employee.CSV file and maps the contents into Employee object. I have created a string array which holds the header names and using that while parsing the file.

The output will be like below,


Parsed Content: employeeList::[Employee{id=1, firstName='John', lastName='Arthur', age=25}, Employee{id=2, firstName='Sam ', lastName='Andrew', age=26}, Employee{id=3, firstName='Hary', lastName=' Peter', age=26}]

Now lets see how we can create a CSV file with an example.



import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CreateCSVFileMain {

    public static void main(String[] args) throws IOException {

        String filePath = "/tmp/employee_new.csv";
        String[] headers = { "Id", "First_Name", "Last_Name", "Age" };
        List employeeList = new ArrayList();
        Employee employee1 = new Employee();
        employee1.setId(1234);
        employee1.setFirstName("fname1");
        employee1.setLastName("lname1");
        employee1.setAge(45);
        Employee employee2 = new Employee();
        employee2.setId(1234);
        employee2.setFirstName("fname1");
        employee2.setLastName("lname1");
        employee2.setAge(45);
        employeeList.add(employee1);
        employeeList.add(employee2);

        FileWriter writer = null;
        try {
            writer = new FileWriter(filePath);
            try (CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(headers))) {
                employeeList.forEach(employee -> {
                    try {
                        csvPrinter.printRecord(employee.getId(), employee.getFirstName(), employee.getLastName(),
                                               employee.getAge());
                    }
                    catch (IOException io) {
                        io.printStackTrace();
                    }
                });
            }
        }
        finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
}


If we don’t want the header then, don’t specify with header.
The content of the created employee_new.csv file is given below,


Id,First_Name,Last_Name,Age
1234,fname1,lname1,45
1234,fname1,lname1,45