Dozer Mapping

Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. Typically, these Java Beans will be of different complex types.

This mapper helps us to avoid unnecessary mapping code in our application. Internally it uses reflection.

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

Assume that we have a “Person” Bean class which contains the first name, last name, age and address fields. We want to map it into another bean class PersonVO. In addition to that, we want to map the name details into NameVO and address details into AddressVo. Let’s look at below to know how we can do that with Dozer.

Here is our Person Bean class.

Person.java


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class Person {

    private String id;

    private String firstName;

    private String lastName;

    private int age;

    private String streetAddress;

    private String city;

    private String state;

    private String zip;

    private String phoneNumber;

    public String getId() {
        return id;
    }

    public void setId(String 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 int getAge() {
        return age;
    }

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

    public String getStreetAddress() {
        return streetAddress;
    }

    public void setStreetAddress(String streetAddress) {
        this.streetAddress = streetAddress;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }
}

We want to map the Person Bean into PersonVO bean and also the first name and last name fields are mapped to NameVO and address are mapped to AddressVO.

Here is the PersonVO Bean class contains the person id, age and NameVo and AddressVo fields.

PersonVO


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class PersonVO {

    private String id;

    private int age;

    private NameVO nameVO;

    private AddressVO addressVO;

    public String getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

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

    public NameVO getNameVO() {
        return nameVO;
    }

    public void setNameVO(NameVO nameVO) {
        this.nameVO = nameVO;
    }

    public AddressVO getAddressVO() {
        return addressVO;
    }

    public void setAddressVO(AddressVO addressVO) {
        this.addressVO = addressVO;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }
}


Here is the NameVO Bean contains the first and last name fields.
NameVO


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class NameVO {

    private String firstName;

    private String lastName;

    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;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

}

Here is the AddressVO Bean contains the stress address, city, state, zip and phone number fields.
AddressVO


package com.dozerExample;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class AddressVO {

    private String streetAddress;

    private String city;

    private String state;

    private String zip;

    private String phoneNumber;

    public String getStreetAddress() {
        return streetAddress;
    }

    public void setStreetAddress(String streetAddress) {
        this.streetAddress = streetAddress;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }
}

We have to include the below dependency in your pom.xml file.
pom.xml


<dependency>
            <groupId>com.github.dozermapper</groupId>
            <artifactId>dozer-core</artifactId>
            <version>6.1.0</version>
 </dependency>

Then, we need to define the bean mapping field details in an XML. Here is the dozer mapping XML.


<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd">
    <mapping wildcard="true" map-null="false">
        <class-a>com.dozerExample.Person</class-a>
        <class-b>com.dozerExample.PersonVO</class-b>
        <field>
            <a>firstName</a>
            <b>nameVo.firstName</b>
        </field>
        <field>
            <a>lastName</a>
            <b>nameVo.lastName</b>
        </field>
        <field>
            <a>streetAddress</a>
            <b>addressVo.streetAddress</b>
        </field>
        <field>
            <a>city</a>
            <b>addressVo.city</b>
        </field>
        <field>
            <a>state</a>
            <b>addressVo.state</b>
        </field>
        <field>
            <a>zip</a>
            <b>addressVo.zip</b>
        </field>
        <field>
            <a>phoneNumber</a>
            <b>addressVo.phoneNumber</b>
        </field>
    </mapping>
</mappings>

Now, Let’s use the above mapping file and convert Person into PersonVO and vice versa.



package com.dozerExample;

import org.dozer.DozerBeanMapperBuilder;
import org.dozer.Mapper;

import java.util.UUID;

public class DozerApp {

    public static final String PERSON_DOZER_MAPPING_XML = "dozer-mapping.xml";

    private static Mapper mapper = DozerBeanMapperBuilder.create().withMappingFiles(PERSON_DOZER_MAPPING_XML).build();;

    public static void main(String[] args) {
        Person person = new Person();
        person.setId(UUID.randomUUID().toString());
        person.setFirstName("Michael");
        person.setLastName("Keller");
        person.setAge(45);
        person.setStreetAddress("102 walker st");
        person.setCity("Delaware");
        person.setState("OH");
        person.setZip("45454");
        person.setPhoneNumber("614-434-4535");
        PersonVO personVO = mapper.map(person, PersonVO.class);
        System.out.println("Converting from person to personVO" + personVO);
        Person newPerson = mapper.map(personVO, Person.class);
        System.out.println("Converting from personVO to person" + newPerson);
    }
}

The following is the output of the above program.


Converting from person to personVOcom.dozerExample.PersonVO@467aecef[id=bd993f0e-48f6-4bf7-a942-f902c156ffd4,age=45,nameVO=com.dozerExample.NameVO@5bfbf16f[firstName=Michael,lastName=Keller],addressVO=com.dozerExample.AddressVO@25af5db5[streetAddress=102 walker st,city=Delaware,state=OH,zip=45454,phoneNumber=614-434-4535]]
Converting from personVO to personcom.dozerExample.Person@5f3a4b84[id=bd993f0e-48f6-4bf7-a942-f902c156ffd4,firstName=Michael,lastName=Keller,age=45,streetAddress=102 walker st,city=Delaware,state=OH,zip=45454,phoneNumber=614-434-4535]

Advertisements

OpenStack CURL API Commands

I have recently worked with OpenStack and used the OpenStack API to create/delete container and upload objects.

In this post, I am going to give the commands used for that.

You would need to get an auth token first to use the Openstack API’s. To get the Auth token you again need an API call but for which you would need to pass username and password. I am not going to give that API call here. If you want, please refer the openstack documentation. Same goes for getting the OPENSTACK_OBJECT_STORE_URL. The Openstack auth token response header contains both the auth token and object store(Swift) public URL. Get those details and replace it in the below command.

Creating a container


curl -X PUT ${OPENSTACK_OBJECT_STORE_URL}/${CONTAINER_NAME} -H "X-Auth-Token: ${OPENSTACK_AUTH_TOKEN}"

Deleting a container


curl -X DELETE ${OPENSTACK_OBJECT_STORE_URL}/${CONTAINER_NAME} -H "X-Auth-Token: ${OPENSTACK_AUTH_TOKEN}"

 

Uploading an object


curl -X PUT \
"${OPENSTACK_OBJECT_STORE_URL}/${CONTAINER_NAME}/${FILE_NAME}" \
-H "X-Auth-Token: ${OPENSTACK_AUTH_TOKEN}" \
--data-binary "@${LOCAL_FILE_PATH}/${FILE_NAME}"
 

Deleting an object


curl -X DELETE \
"${OPENSTACK_OBJECT_STORE_URL}/${CONTAINER_NAME}/${FILE_NAME}" \
-H "X-Auth-Token: ${OPENSTACK_AUTH_TOKEN}" 

 

JUnit4 Exception testing

In this post, I am going to show how we can write a JUnit test case to test a method which throws an exception.

We can follow any one of the below approaches to test the method throws an exception. Here, I am using JUnit 4.

1. @Test annotation with “expected” attribute
2. try-catch and fail()
3. ExpectedException

Here is my class and contains a method “validateUserData” which has logic to validate the userName and name. If anyone of this has either null or blank then it will throw a RuntimeException with the appropriate message.


import org.apache.commons.lang3.StringUtils;

public class UserDataValidator {

    public void validateUserData(String userName, String name){
        if(StringUtils.isBlank(userName)){
            throw new RuntimeException("userName is null or blank");
        }
        if(StringUtils.isBlank(name)){
            throw new RuntimeException("name is null or blank");
        }
    }
}

Let’s write a JUnit test case to test this method with the above approaches.

@Test annotation with “expected” attribute

Here is the JUnit test to test the “validateUserData” method. I am passing the “userName” as null. So as expected the method throws a RuntimeException.


import org.junit.Test;

public class UserDataValidatorTest {

    @Test(expected = RuntimeException.class)
    public void testValidateUserData_userNameIsNull(){
        UserDataValidator userDataValidator = new UserDataValidator();
        userDataValidator.validateUserData(null, "test");
    }
}

try-catch and fail()

if we want to assert the exception message, then we can follow this approach.


import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class UserDataValidatorTest {
    
    @Test
    public void testValidateUserData_userNameIsNull(){
        UserDataValidator userDataValidator = new UserDataValidator();
        try{
            userDataValidator.validateUserData(null, "test");
            fail();
        }catch (Exception e){
            assertEquals("userName is null or blank", e.getMessage());
        }

    }
}

ExpectedException

The ExpectedException rule is used to test the exception type and also the exception message.


import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class UserDataValidatorTest {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void testValidateUserData_userNameIsNull(){
        thrown.expect(RuntimeException.class);
        thrown.expectMessage("userName is null or blank");
        UserDataValidator userDataValidator = new UserDataValidator();
        userDataValidator.validateUserData(null, "test");
    }
}

Setting the build description for a jenkins job

If you want to set the build description for a Jenkins job, then follow the below steps.

1. Make sure that the “Description Setter Plugin” installed on the Jenkins server.
2. Go to your Jenkins job configuration page.
3. Go to Post-Build Actions section.
4. On the “Set the build description” section, provide the regular expression to look for it and also the regular expression for failed builds.

Refer the below snippet from my Jenkins job.

setBuildDesc

 

I have given the regex as “project tag number is (\d*)”. So Jenkins will look for this string in my job console output and retrieve the number and use that value as build description. If in case, the job is failed, then it will use “failed” text as the build description.

My Jenkins job sample console output is as given below,


....
....
....
Project has been built successfully.
project tag number is 20180330
job finished Date: Fri Mar 30 03:22:13 EDT 2018
[description-setter] Description set: 20180323
....

The build history looks like below,

buildhistory