Java @ Desk

Java @ Desk

Breaking

Thursday, March 29, 2018

Find Maximum LocalDateTime From ArrayList In Java 8

11:43 PM 0
Maximum date can be fetched from the List using the Collections interface.

Collections interface provide the methods to find the maximum value out of a collection of dates.

In this case we will pass ArrayList of LocalDateTime object that contains the dates.

Below is a sample implementation that retrieves the maximum date from a ArrayList -

package com.learning;

import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class FindMaxLocalDateTimeArrayList {

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

  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
  LocalDate ld = LocalDate.parse("2018-03-22T18:02:32.000Z", formatter);
  LocalDateTime ldt = LocalDateTime.of(ld, LocalDateTime.now().toLocalTime());

  List<LocalDateTime> localDateTimes = new ArrayList<>();
  localDateTimes.add(ldt);
  localDateTimes.add(LocalDateTime.of(LocalDate.parse("2018-03-25T18:02:32.000Z", formatter),
    LocalDateTime.now().toLocalTime()));
  localDateTimes.add(LocalDateTime.of(LocalDate.parse("2018-03-16T18:02:32.000Z", formatter),
    LocalDateTime.now().toLocalTime()));

  System.out.println(Collections.max(localDateTimes));
 }
}

Wednesday, March 28, 2018

Implement And Or Conditions in Drools Decision Table

3:02 AM 0
Implement And Or Conditions in Drools Decision Table

Drools rules can be defined in various formats one of which is in Decision Tables. Decision Tables rules are configured in an excel sheet in .xls format.

Decision Table is primarily used when there are rules that need to be configured for similar properties. For example, there is a rule implementation on age property of a user. Below are the examples:
If age > 18 && age < 22 then Do X
If age > 22 && age < 28 then Do Y
If age > 28 && age < 32 then Do Z
If age > 32 && age < 36 then Do A
If age > 36 && age < 48 then Do B
If age > 48 && age < 56 then Do C

If such rules are implemented in DRL files, then there will be lot of redundant code. Instead the same are configured in a decision table.

There are different components of a Decision table as mentioned below. The structure is similar to DRL file itself
1) Ruleset - Its similar to package from DRL file.
2) Import - To import comma separated Java packages that are used in rules.
3) Sequential - If set to true, rules will be fired in sequence from top to bottom.
4) Variables - One of more Global variables.
5) Functions - Functions used if any in rules.
6) Queries - Queries used if any in rules.

Rules configuration consists of below :
1) Rule Name
2) Description
3) CONDITION
4) ACTION

By default, there is a AND condition between the CONDITION columns in between the table. AND condition can also be implemented using conditions with comma seperated as shown below. OR condition is implemented using || between the conditions as shown in below screenshot Here is the snapshot of Decision Table that is used in the example.









User.java - Pojo used for rules
package com.pojo;

public class User {

 private String name;

 private String address;

 private Integer age;

 private boolean adult;

 private Integer rateOfInterest;
 
 private String bankAccounts;
 
 public String getBankAccounts() {
  return bankAccounts;
 }

 public void setBankAccounts(String bankAccounts) {
  this.bankAccounts = bankAccounts;
 }

 @Override
 public String toString() {
  return "Name - " + this.name + "\nAddress -" + this.address + "\nAge" + this.age + "\nAdult - " + this.adult
    + "\nRate Of Interest - " + this.rateOfInterest;
 }

 public Integer getRateOfInterest() {
  return rateOfInterest;
 }

 public void setRateOfInterest(Integer rateOfInterest) {
  this.rateOfInterest = rateOfInterest;
 }

 public Integer getAge() {
  return age;
 }

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

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public boolean isAdult() {
  return adult;
 }

 public void setAdult(boolean adult) {
  this.adult = adult;
 }
}


Client File
package com.drools;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

import com.pojo.User;

public class DecisionTableClient {

 public static final void main(final String[] args) throws InterruptedException {
  KieSession kieSession = new DecisionTableClient().execute();

  User user = new User();
  user.setName("Andy");
  user.setAge(62);
  user.setAddress("Japan");
  user.setBankAccounts("Axis");
  kieSession.insert(user);
  kieSession.fireAllRules();
  System.out.println("\n");
  System.out.println(
    "User Object After Firing Rules - \n"
      + user.toString());
  kieSession.dispose();
 }

 public KieSession execute() {
  KieServices ks = KieServices.Factory.get();
  KieContainer kc = ks.getKieClasspathContainer();
  KieSession kieSession = kc.newKieSession("DecisionTableKIESession");
  return kieSession;
 }

}

Friday, March 23, 2018

Spring Boot Configure Server Port and Context Path

5:53 AM 0
Spring Boot Configure Server Port and Context Path

By default, in Spring Boot the context path is "/" and server port is 8080.

In order to configure the context path or server port, application.properties need to be configured.

applicatin.properties is located in src/main/resources folder. Following entries are required to configure.

server.port=8088
server.contextPath=/myContectPath

There is one more way to update the context path while running the application from command line. Below is the code for the same -

java -jar -Dserver.contextPath=/myContectPath mySpringBoot.jar

Wednesday, March 21, 2018

Activation Group in Decision Table in Drools CSV Example

8:20 AM 0
Activation Group in Decision Table in Drools CSV Example

Drools rules can be defined in various formats one of which is in Decision Tables. Decision Tables rules are configured in an excel sheet in .xls format.

Decision Table is primarily used when there are rules that need to be configured for similar properties. For example, there is a rule implementation on age property of a user. Below are the examples:
If age > 18 && age < 22 then Do X
If age > 22 && age < 28 then Do Y
If age > 28 && age < 32 then Do Z
If age > 32 && age < 36 then Do A
If age > 36 && age < 48 then Do B
If age > 48 && age < 56 then Do C

If such rules are implemented in DRL files, then there will be lot of redundant code. Instead the same are configured in a decision table.

There are different components of a Decision table as mentioned below. The structure is similar to DRL file itself
1) Ruleset - Its similar to package from DRL file.
2) Import - To import comma separated Java packages that are used in rules.
3) Sequential - If set to true, rules will be fired in sequence from top to bottom.
4) Variables - One of more Global variables.
5) Functions - Functions used if any in rules.
6) Queries - Queries used if any in rules.

Rules configuration consists of below :
1) Rule Name
2) Description
3) CONDITION
4) ACTION

Along with above attributes, an Activation Group is added between the CONDITION and ACTION. Activation Group makes sure only one rule should fire under the activation group. In the below example, we will see the usage of Activation group in decision tables to create rules.

Here is the snapshot of Decision Table that is used in the example.






User.java - Pojo used for rules
package com.pojo;

public class User {

 private String name;

 private String address;

 private Integer age;

 private boolean adult;

 private Integer rateOfInterest;
 
 private String bankAccounts;
 
 public String getBankAccounts() {
  return bankAccounts;
 }

 public void setBankAccounts(String bankAccounts) {
  this.bankAccounts = bankAccounts;
 }

 @Override
 public String toString() {
  return "Name - " + this.name + "\nAddress -" + this.address + "\nAge" + this.age + "\nAdult - " + this.adult
    + "\nRate Of Interest - " + this.rateOfInterest;
 }

 public Integer getRateOfInterest() {
  return rateOfInterest;
 }

 public void setRateOfInterest(Integer rateOfInterest) {
  this.rateOfInterest = rateOfInterest;
 }

 public Integer getAge() {
  return age;
 }

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

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public boolean isAdult() {
  return adult;
 }

 public void setAdult(boolean adult) {
  this.adult = adult;
 }
}


Client File
package com.drools;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

import com.pojo.User;

public class DecisionTableClient {

 public static final void main(final String[] args) throws InterruptedException {
  KieSession kieSession = new DecisionTableClient().execute();

  User user = new User();
  user.setName("Andy");
  user.setAge(62);
  user.setAddress("Japan");
  user.setBankAccounts("Axis");
  kieSession.insert(user);
  kieSession.fireAllRules();
  System.out.println("\n");
  System.out.println(
    "User Object After Firing Rules - \n"
      + user.toString());
  kieSession.dispose();
 }

 public KieSession execute() {
  KieServices ks = KieServices.Factory.get();
  KieContainer kc = ks.getKieClasspathContainer();
  KieSession kieSession = kc.newKieSession("DecisionTableKIESession");
  return kieSession;
 }

}

Monday, March 19, 2018

Drools Decision Table CSV Example

5:40 AM 0
Drools Decision Table CSV Example

Drools rules can be defined in various formats one of which is in Decision Tables. Decision Tables rules are configured in an excel sheet in .xls format.

Decision Table is primarily used when there are rules that need to be configured for similar properties. For example, there is a rule implementation on age property of a user. Below are the examples:
If age > 18 && age < 22 then Do X
If age > 22 && age < 28 then Do Y
If age > 28 && age < 32 then Do Z
If age > 32 && age < 36 then Do A
If age > 36 && age < 48 then Do B
If age > 48 && age < 56 then Do C

If such rules are implemented in DRL files, then there will be lot of redundant code. Instead the same are configured in a decision table.

There are different components of a Decision table as mentioned below. The structure is similar to DRL file itself
1) Ruleset - Its similar to package from DRL file.
2) Import - To import comma separated Java packages that are used in rules.
3) Sequential - If set to true, rules will be fired in sequence from top to bottom.
4) Variables - One of more Global variables.
5) Functions - Functions used if any in rules.
6) Queries - Queries used if any in rules.

Rules configuration consists of below :
1) Rule Name
2) Description
3) CONDITION
4) ACTION

In the below example, we will see the usage of decision tables to create rules.

Here is the snapshot of Decision Table that is used in the example.




User.java - Pojo used for rules
package com.pojo;

public class User {

 private String name;

 private String address;

 private Integer age;

 private boolean adult;

 private Integer rateOfInterest;
 
 private String bankAccounts;
 
 public String getBankAccounts() {
  return bankAccounts;
 }

 public void setBankAccounts(String bankAccounts) {
  this.bankAccounts = bankAccounts;
 }

 @Override
 public String toString() {
  return "Name - " + this.name + "\nAddress -" + this.address + "\nAge" + this.age + "\nAdult - " + this.adult
    + "\nRate Of Interest - " + this.rateOfInterest;
 }

 public Integer getRateOfInterest() {
  return rateOfInterest;
 }

 public void setRateOfInterest(Integer rateOfInterest) {
  this.rateOfInterest = rateOfInterest;
 }

 public Integer getAge() {
  return age;
 }

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

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public boolean isAdult() {
  return adult;
 }

 public void setAdult(boolean adult) {
  this.adult = adult;
 }
}


Client File
package com.drools;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

import com.pojo.User;

public class DecisionTableClient {

 public static final void main(final String[] args) throws InterruptedException {
  KieSession kieSession = new DecisionTableClient().execute();

  User user = new User();
  user.setName("Andy");
  user.setAge(62);
  user.setAddress("Japan");
  user.setBankAccounts("Axis");
  kieSession.insert(user);
  kieSession.fireAllRules();
  System.out.println("\n");
  System.out.println(
    "User Object After Firing Rules - \n"
      + user.toString());
  kieSession.dispose();
 }

 public KieSession execute() {
  KieServices ks = KieServices.Factory.get();
  KieContainer kc = ks.getKieClasspathContainer();
  KieSession kieSession = kc.newKieSession("DecisionTableKIESession");
  return kieSession;
 }

}

Friday, March 9, 2018

Spring Boot Executable Jar File

3:21 AM 0
Spring Boot Executable Jar File

In this post, we will learn how to create executable Jar file in Spring Boot through Maven. The Jar file that we create through Maven is not an executable jar file i.e. it does not contains nested jars or external jars added through pom.xml in maven.

The jar file created using maven is not compatible enough to run from command line. In order to run from command line, the jar must include all the nested jars too.

To create an executable jar, spring-boot-maven-plugin need to be added in pom.xml along with the execution configuration repackage goal as shown below
<plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 <version>1.4.0.RELEASE</version>
 <executions>
  <execution>
   <goals>
    <goal>repackage</goal>
   </goals>
  </execution>
 </executions>
</plugin>


The original structure of target folder includes the below structure. It clearly shows, the final jar that is created is only of 8KB i.e. it does not include any nested jars required by the developed classed.

Once the above execution is added, the structure will be changed as shown below


There will be a .jar.original file that is similar to JAR created through 1st mode. The second Jar file is the one that includes all the nested jars required to run the application.

If we open the Jar file using ZIP structure will contain below folders
1) BOOT-INF - It contains external libs and project classes.
2) META-INF
3) org.springframework.boot.loader - It includes all the load configuration.

The above execution needs to be manually added in plugin only if spring-boot-starter-parent is not included in the project POM. If spring-boot-starter-parent is added then spring-boot-maven-plugin can be configured without repackage goal.

Wednesday, March 7, 2018

Drools Get Inserted Facts in DRL File From Java Code after Firing Rules

2:49 AM 0
Drools Get Inserted Facts in DRL File From Java Code after Firing Rules

Drools flow is we insert Java objects into KieSession and fire rules on them. But sometimes while firing the rules, we insert new Java objects into KieSession.

There are 2 ways to retrieve the inserted facts in Java code -
1) Using kieSession.getObjects() method. Using this method, we get all the inserted objects. To use the specific object, we need to typecast that object to particular classes.
2) Using QueryResults. This method requires a change in DRL file. This requires a query need to be added in DRL file as shown below
query "getObjectsOfUser"
    $insertedUserObjectInDRLFile: User()
end


Java object is fetched using below code after firing rules
QueryResults results = kieSession.getQueryResults("getObjectsOfUser");
for (QueryResultsRow row : results) {
 User user = (User) row.get("$insertedUserObjectInDRLFile");
}


Complete Source Code-

User.java - Java Pojo Object
package com.pojo;

public class User {

 private String name;

 private String address;

 private Integer age;

 private boolean adult;

 @Override
 public String toString() {
  return "Name - " + this.name + "\nAddress -" + this.address + "\nAge" + this.age + "\nAdult - " + this.adult;
 }

 public Integer getAge() {
  return age;
 }

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

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public boolean isAdult() {
  return adult;
 }

 public void setAdult(boolean adult) {
  this.adult = adult;
 }
}


DRL File
package com.drools.user
 
import com.pojo.User;

rule "Check If User Object Exists"
salience 160
    when
    not User()
    then
        System.out.println(drools.getRule().getName() + " rule fired");
        System.out.println("User Object does not exists in KieSession. Insert new Object in DRL File");
        User user = new User();
        user.setName("Andy");
  user.setAge(32);
  user.setAddress("New York");
  insert(user);
        drools.halt();
end

query "getObjectsOfUser"
    $insertedUserObjectInDRLFile: User()
end




UserDroolsClient.java - Client File in which Inserted Facts are retrieved after firing Rules
package com.drools;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.QueryResults;
import org.kie.api.runtime.rule.QueryResultsRow;

import com.pojo.User;

public class UserDroolsClient {

 public static final void main(final String[] args) throws InterruptedException {
  KieSession kieSession = new UserDroolsClient().execute();
  kieSession.fireAllRules();
  System.out.println("\n");

  // Method 1 Using getObjects() method
  kieSession.getObjects().forEach(object -> {
   if (object instanceof User) {
    User user = (User) object;
    System.out.println("User Object Inserted in DRL File fetched from KieSession using getObjects() After Firing Rules - \n"
      + user.toString());
   }
  });
  
  System.out.println("\n");

  // Method 2 Using QueryResults
  QueryResults results = kieSession.getQueryResults("getObjectsOfUser");
  for (QueryResultsRow row : results) {
   User user = (User) row.get("$insertedUserObjectInDRLFile");
   System.out.println("User Object Inserted in DRL File fetched from KieSession using QueryResult Object After Firing Rules - \n"
     + user.toString());
  }

  kieSession.dispose();
 }

 public KieSession execute() {
  KieServices ks = KieServices.Factory.get();
  KieContainer kc = ks.getKieClasspathContainer();
  KieSession kieSession = kc.newKieSession("UserKIESession");
  return kieSession;
 }

}

Wednesday, November 29, 2017

Implement Scheduler in Spring Boot

12:26 AM 0
Implement Scheduler in Spring Boot

Scheduler is implemented in Spring Boot using org.springframework.scheduling.annotation.Scheduled annotation. It takes input as a cron expression along with the time zone.

The @Scheduled annotation is used with a method that performs specific tasks at regular intervals. The package of the scheduler class need to be provided in the Spring Boot main application using scanBasePackages property. During deployment, Spring scans the component provided in scanBasePackages and schedules based on cron provided in scheduler class.

Here is the sample code for the same.
import java.time.LocalDateTime;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyScheduler {

 final Logger logger = LoggerFactory.getLogger(MyScheduler.class);

 /* scheduled to run at every 5 minutes */
 @Scheduled(cron = "0 0/5 * * * *", zone = "Asia/Calcutta")
 public void run() {
  logger.debug("Scheduler Service Started at " + LocalDateTime.now());
 }

}


Spring Boot Main class
The main class must provide below annotation along with scanBasePackages.
@SpringBootApplication(scanBasePackages = { "com.scheduler" })