Showing posts with label java8. Show all posts
Showing posts with label java8. Show all posts

Sunday, August 18, 2019

Microservices: Service Registry and Discovery


In my previous blog, I have already talked about Netflix Hystrix Circuit Breaker Microservices and explained it by creating two applications i.e. Product Service and Price Service.
In this post, I’ll use both applications to explain what is the Service Registry and Discovery Server.

What is Service Registry and Discovery and why do we need it in the first place?

In our monolithic application, mostly service invoke one another through language methods or procedure calls and even in traditional distributed system deployment, services run at fixed, well-known locations (hosts and ports) and so can easily call one another using HTTP/REST. Over here the network locations of service instances are relatively static.

With the microservice architecture system, this is a much more difficult problem as service instances have dynamically assigned network locations. Service instances change dynamically because of auto-scaling, failure or upgrade. So, you can see that it’s not possible to hard code the locations (hosts and ports) of service instances in our application.

Apart from that, most of the time we have to deploy the same instance on multiple hosts (E.g. During Big billions day sale where 1000’s of instances is running to support high demand) which will be again a tedious task for the load balancer to register and deregister itself for all these services.
 

What is Service Registry and Discovery?

Service Registry is the server instance where all the service provider register itself when it starts up and deregisters itself when it leaves the system. The service instance’s registration is typically refreshed periodically using a heartbeat mechanism.

Whenever a client has to communicate with other service instances, it has to first query to Service registry to get the network location and then uses a load-balancing algorithm to select one of the available service instances and invoke a request. 

The above instance discovery pattern is called a Client-Side discovery pattern and this can be easily implemented using Netflix Eureka as a Service Registry. It provides a REST API for managing service‑instance registration and for querying available instances.

Netflix also provides Netflix Ribbon which is an IPC client that works with Eureka to load balance requests across the available service instances.


Implementation

As we already have two microservices product-service and price-service and we know product-service is internally invoking price-service to get the price detail of the products. We will do minor changes with these two applications to support service registry.

Discovery Server Implementation

  • Create a spring boot application and Eureka Server starter dependency to your pom.xml file 

  • Add @EnableEurekaServer annotation to Enable Eureka Server.
  • By default, Each Eureka Server is also a Eureka Client which needs at least one service URL to locate service registry. We have to disable this feature as we are creating single node Eureka Server. 
  • Add below properties to application.properties file.

  • Now start the discovery-server application and access http://localhost:8761 which will display the UI similar to below screenshot. 

  • As of now, no application is registered with the Eureka Server. 

2. Registering product-service and price-service to Eureka Clients

  • Let’s make out product-service and price-service as Eureka Client which should register to Eureka Server itself on starts up.
  • Add Eureka Client dependency on both pom.xml files.

  • Configure eureka.client.service-url.defaultZone property in application.properties to automatically register with the Eureka Server. 

  • Now start product-service and price service application and hit http://localhost:8761. We will see product-service and price-service is registered with SERVICE ID as PRODUCT-SERVICE and PRICE-SERVICE respectively. We can also notice the status as UP(1) which means the services are up and running and only one instance of product and price-service are running. 

3. Update hard code URL with application name in product-service and restart the application. 


4. Now open browser and hit product URL and you will get the below response.


Congratulation!!! Our application is perfectly working with Discovery Service. 

Spring-boot microservices can be downloaded from GITHUB

Happy Coding...!!!

Saturday, April 20, 2019

Java 8 - Optional


Java 8 - Optional

In this blog, I’ll discuss about Optional class which was introduced in JDK8 under java.util.package. Optional class is used to represent a value is present or absent.

With Optional class, developers have to less worry about NullPointerException and can work on neat and clean code. It contains at most one value.


Advantages:
· No need to check for null
· No more NullPointerException at runtime

Public final class Optional<T> extends Object {
}
Let’s understand all its usage with the help of example

1. Optional.empty()

To create an empty Optional object we simply need to write

// How to create empty Optional
             Optional<String> optional = Optional.empty();
             System.out.println("1. Optional: " + optional);
    Output:
            1. Optional: Optional.empty


2. isPresent()

You can also check whether any value present in Optional or not
          System.out.println("2. Optional: " + optional.isPresent());
Output:
          2. Optional: false

3. Of() method

We can also use Static Of method to create an Optional Object.
      //Can create Optional using Static Of method
      Optional<String> name = Optional.of("WaheedTechblog.com");
      System.out.println("3. Name: " + name.toString());
Output:
       3. Name: Optional[WaheedTechblog.com]

Note: Make sure you are not passing any null value to Of() method else it would throw a NullPointer Exception.

Optional<String> nullValue = Optional.of(null);
             System.out.println("4. Name: " + nullValue.toString());
Output:
             Exception in thread "main" java.lang.NullPointerException
       at java.base/java.util.Objects.requireNonNull(Objects.java:221)
       at java.base/java.util.Optional.<init>(Optional.java:107)
       at java.base/java.util.Optional.of(Optional.java:120)
       at com.waheedtechblog.optional.OptionalExample.main(OptionalExample.java:20)

4. OfNullable()

If you are not sure about the object you must use OfNullable API.

       //Can accept NUll value as well
       Optional<String> isNull = Optional.ofNullable("WaheedTechblog.com");
       System.out.println("5. Name: " + isNull.toString());
Output:
       5. Name: Optional[WaheedTechblog.com]

If we pass a null reference, it does not throw an exception but returns an empty Optional object.


5. isPresent()

We can use isPresent() method to check whether the Optional object is empty or contains some value.

Optional<String> isNull = Optional.ofNullable("WaheedTechblog.com");
       //check isNull object contains some value
       if(isNull.isPresent()) {
                    System.out.println("6. Optional object contains some value: " + isNull.toString());
             }
Output:
       6. Optional object contains some value: Optional[WaheedTechblog.com]


6. isEmpty()

Similarly , we can use isEmpty method to check whether the Optional object is empty or not

//Check whether object is empty or not
             Optional<String> nullValue = Optional.ofNullable(null);
             if (nullValue.isEmpty()) {System.out.println("7. Is Optional empty? " + nullValue.toString());
       }
Output:
7. Optional object contains some value: Optional.empty


7. ifPresent()
It enables us to run some code if Optional Object is not empty. Most of the time, we normally do something like this in our application.
 If(user != null) {
       String name = user.getName();
}
Over here, we are performing some operation based on if condition. This approach is lengthy and there are chances to miss such null checks which can result in a NullPointerException at runtime.

ifPresent() accepts Consumer functional Interface.

//Execute if Optional object exist.
             Optional<String> name = Optional.of("WaheedTechblog.com");
             name.ifPresent(value -> System.out.println("8. Length of name: " + value.length()));
Output:
8. Length of name: 18


8. orElse()

We can use orElse() method to set some default value incase if Optional object is Empty.

      //Set Default value if Object is empty
             String nullString = null;
             String testOrElse = Optional.ofNullable(nullString).orElse("This is default value");
             System.out.println("9. Print testorElse value: " + testOrElse);
Output:
9. Print testorElse value: This is default value


9. orElseGet()

This API is very similar to orElse() method except that instead of taking default value, you can pass Supplier functional interface which returns response based on some operation.

//Invoke Functional Interface if Optional Object is empty
String testOrElseGet = Optional.ofNullable(nullString).orElseGet(() -> "waheedtechblog");
             System.out.println("10. Print orElseGet value: " + testOrElseGet);
Output:
            10. Print orElseGet value: waheedtechblog

Note: At the very first glance, it looks like orElse and orElseGet method are very similar and either one of them can be used to get the default value but this is not very true. There is a subtle but very important difference between the two.

Let’s understand this with Example
       private String getDbConnection() {
             System.out.println("13. Invoking Default fucntion");
             return "Create db Connection";
       }

// Checking the diff between orElse Vs orElseGet
String testOrElseDiff = Optional.ofNullable("waheedtechblog").orElse(optionalExample.getDbConnection());
             System.out.println("11. Print testorElse value: " + testOrElseDiff);

String testOrElseGetDiff = Optional.ofNullable("waheedtechblog").orElseGet(optionalExample::getDbConnection);
System.out.println("12. Print orElseGet value: " + testOrElseGetDiff);

Output:
13. Invoking Default fucntion
11. Print testorElse value: waheedtechblog
12. Print orElseGet value: waheedtechblog


If you observe the output, you will realize that orElse() method is invoking getDBConnection() when the object is already present whereas orElseGet() method is not invoking the DB call.

So, I would suggest choose orElseGet over orElse as database query or any rest API call can cost to your application performance when there was no need of that.

10. orElseThrow()

Instead of calling any default method in case of Optional value not present, it throws an exception.

//Throw runtime exception if Optional value is not present
      String orElseThrowTest = Optional.ofNullable(nullString).orElseThrow(RuntimeException::new);
Output:
Exception in thread "main" java.lang.RuntimeException
       at java.base/java.util.Optional.orElseThrow(Optional.java:408)
       at com.waheedtechblog.optional.OptionalExample.main(OptionalExample.java:62)

11. get()

Get returns the value of Optional Object if not null or else throws no such element exception.
Optional<String> getTest = Optional.ofNullable("waheedtechblog");
      System.out.println("15. GetTest value: " + getTest.get());
Output:
        15. GetTest value: waheedtechblog

Note: get throws NoSuchElementException if Optional object is empty


12. Filter()

The concept of filter is very similar to stream API filter. It takes Predicate as an argument and returns an Optional object.

// filteration on Optional
             Optional<String> username = Optional.of("waheedtechblog");
boolean isLengthValid = username.filter(str -> str.length() > 5).isPresent();
             System.out.println("16. is Length Valid: " + isLengthValid);
 Output:
       16. is Length Valid: true

13. map()

Using map, we can transform the Optional value.

        // map to perform operation on Optional
        Optional<String> password = Optional.of("waheedtechblog");
        String encodedPassword = password.map(str ->                                  Base64.getEncoder().encodeToString(str.getBytes())).get();
System.out.println("17. Encoded Password: " + encodedPassword);

              Output:
            17. Encoded Password: d2FoZWVkdGVjaGJsb2c=


We can also merge filter and map together to get the result.

       // first do validation and then operation on Optional object
       String validatedEncodedPassword = password.filter(ps -> ps.length()
> 15)  .map(str ->  Base64.getEncoder().encodeToString(str.getBytes())).toString();
System.out.println("18. Validated Encoded Password: " + validatedEncodedPassword);

Output:
18. Validated Encoded Password: Optional.empty

Happy Coding…!!!







Sunday, April 7, 2019

Supplier Functional Interface - JAVA 8


Supplier Functional Interface


Supplier is an in-built functional interface introduced in Java 8 in the java.util.function package. Supplier does not expect any input but returns the output. This interface can be handy where you want to generate some data like OTP, currentTime or even GUID
The functional method of Supplier is get(T t).
Here is a simple source code of java.util.function.Supplier

@FunctionalInterface
public interface Supplier<T> {
    /**
     * Gets a result.
     * @return a result
     */
    T get();
}
Where T get () is an abstract method where T is the return type of the function.

Example 1:

import java.util.Date;
import java.util.function.Supplier;

public class SupplierExample {

       public static void main(String[] args) {

             // Calling Supplier Functional Interface without using Lambda Expression
             SystemDate date = new SystemDate();
             System.out.println("System Date: " + date.get());

             // Using Lambda Expression
             Supplier<Date> supplier = () -> new Date();
             System.out.println("Using lambda, System Date: " + supplier.get());
       }

}

class SystemDate implements Supplier<Date> {

       @Override
       public Date get() {
             return new Date();
       }
}

Output:
System Date: Sun Apr 07 17:37:49 IST 2019
Using lambda, System Date: Sun Apr 07 17:37:49 IST 2019


This interface doesn’t contains any default or static method

That’s it for Supplier Functional Interface, Will talk about other Predefined Functional Interface in my next blog.

Happy Coding…!!!

Consumer and BiConsumer Functional Interface - JAVA 8


Consumer and BiConsumer Functional Interface


Consumer<T> is an in-built functional interface introduced in Java 8 in the java.util.function package. It can be used in all contexts where an object needs to be consumed, i.e. taken as input, and some operation is to be performed on the object without returning any result.
Common example of such an operation is printing where an object is taken as input to the printing function and the value of the object is printed.

The functional method of Consumer is accept(T t).
@FunctionalInterface
Public interface Consume<T, > { …}

Here is a simple source code of java.util.function.Consumer
package java.util.function;
    
import java.util.Objects;
    
@FunctionalInterface
public interface Function<T> {
    public void accept(T t);
  }

Where accept (T t) is an abstract method where T is the type of the input to the Function.

Example 1:

import java.util.function.Consumer;

public class ConsumerExample {

       public static void main(String[] args) {

             // Calling Consumer Functional Interface without using Lambda Expression
             SendNotification notification = new SendNotification();
             notification.accept("Abdul");

             // Using Lambda Expression
             Consumer<String> consumer = username -> System.out.println("Send mail notification to : " + username);
             consumer.accept("Waheed");
       }
}

class SendNotification implements Consumer<String> {

       @Override
       public void accept(String user) {
             System.out.println("Send mail notification to : " + user);
       }
}

Output:
Send mail notification to : Abdul
Send mail notification to : Waheed



Example 2:
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample2 {

       public static void main(String[] args) {

             ConsumerExample2 consumerExample2 = new ConsumerExample2();

             Consumer<Student> consumer = student -> {
                    System.out.println("Name: " + student.getName());
                    System.out.println("Age: " + student.getAge());
                    System.out.println("================================");
             };

             List<Student> students = consumerExample2.populateStudentList();
             for (Student student : students) {
                    consumer.accept(student);
             }
       }

       public List<Student> populateStudentList() {
             List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
                           new Student("DummyUser", 20), new Student("Adam", 25));
             return studentList;
       }
}

class Student {
       private String name;
       private int age;

       public Student(String name, int age) {
             super();
             this.name = name;
             this.age = age;
       }

       public String getName() {
             return name;
       }

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

       public int getAge() {
             return age;
       }

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

       public boolean equals(Object obj) {
             Student student = (Student) obj;
             if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
                    return true;
             } else {
                    return false;
             }
       }
}

Output:
Name: Abdul
Age: 31
================================
Name: Waheed
Age: 29
================================
Name: DummyUser
Age: 20
================================
Name: Adam
Age: 25
================================

Example 3:

In this example, I’ll use Predicate, Function and Consumer for better understanding. Below Program will print Student detail with its grade (Generate Grade based on marks) who marks are greater than 60%.

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Function;

/**
 * Use of Predicate, Function and Consumer Functional Interface in one class;
 *
 * It will print name of the student who has marks greater than 60% with its
 * GRADE.
 *
 * @author Abdul Waheed
 *
 */
public class ConsumerExample3 {

       public static void main(String[] args) {

             ConsumerExample3 consumerExample3 = new ConsumerExample3();

             Predicate<Stud> p1 = student -> student.getMarks() > 60;

             Function<Stud, String> f1 = student -> {
                    int marks = student.getMarks();

                    if (marks > 80) {
                           return "A";
                    } else if (marks > 70) {
                           return "B";
                    } else if (marks > 60) {
                           return "C";
                    } else {
                           return "E";
                    }
             };

             // Internally invoking Function interface
             Consumer<Stud> c1 = student -> {
                    System.out.println("Name: " + student.getName());
                    System.out.println("Marks: " + student.getMarks());
                    System.out.println("Grade: " + f1.apply(student));
                    System.out.println("================================");
             };

             List<Stud> students = consumerExample3.populateStudentList();
             for (Stud stud : students) {
                    if (p1.test(stud)) {
                           c1.accept(stud);
                    }
             }
       }

       public List<Stud> populateStudentList() {
             List<Stud> studentList = Arrays.asList(new Stud("Abdul", 31, 60), new Stud("Waheed", 29, 90),
                           new Stud("DummyUser", 20, 80), new Stud("Adam", 25, 47));
             return studentList;
       }
}

class Stud {
       private String name;
       private int age;
       private int marks;

       public Stud(String name, int age, int marks) {
             super();
             this.name = name;
             this.age = age;
             this.marks = marks;
       }

       public String getName() {
             return name;
       }

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

       public int getAge() {
             return age;
       }

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

       public int getMarks() {
             return marks;
       }

       public void setMarks(int marks) {
             this.marks = marks;
       }

       public boolean equals(Object obj) {
             Student student = (Student) obj;
             if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
                    return true;
             } else {
                    return false;
             }
       }
}

Output:

Name: Waheed
Marks: 90
Grade: A
================================
Name: DummyUser
Marks: 80
Grade: B
================================

  



Apart from accept (T t) method, Consumer also has only one default method.

Modifier and Type
Method and Description
default Consumer<T>
andThen(Consumer<? super T> after)
Returns a composed Consumer that performs, in sequence, this operation followed by the after operation.


We can use andThen(Consumer<? super T> after) for Consumer Chaining i.e. we can call multiple Consumer Function at the same time.

C1.andThen(C2).andThen(C3).accept(“Student);

Over here, first C1 will be called then C2 and then C3.

Let’s understand with an example where if a new student register to a website, then data should be updated to database and send welcome mail to User as well.


Example 3:

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerChainning {

       public static void main(String[] args) {

             ConsumerChainning chainning = new ConsumerChainning();

             Consumer<Student> addToDB = Student -> {
                    System.out.println("Open Database Connection");
                    System.out.println("Write Record to DB");
                    System.out.println("Name: " + Student.getName() + ", Age: " + Student.getAge());
                    System.out.println("Close Connection");
                    System.out.println("================================");
             };

             Consumer<Student> sendMail = Student -> {
                    System.out.println("Configure Mail Server");
                    System.out.println("Send Mail to user " + Student.getName());
                    System.out.println("================================\n");
             };

             List<Student> students = chainning.populateStudentList();
             for (Student student : students) {
                    addToDB.andThen(sendMail).accept(student);
             }
       }

       public List<Student> populateStudentList() {
             List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
                           new Student("DummyUser", 20), new Student("Adam", 25));
             return studentList;
       }

}

Output:

Open Database Connection
Write Record to DB
Name: Abdul, Age: 31
Close Connection
================================
Configure Mail Server
Send Mail to user Abdul
================================

Open Database Connection
Write Record to DB
Name: Waheed, Age: 29
Close Connection
================================
Configure Mail Server
Send Mail to user Waheed
================================

Open Database Connection
Write Record to DB
Name: DummyUser, Age: 20
Close Connection
================================
Configure Mail Server
Send Mail to user DummyUser
================================

Open Database Connection
Write Record to DB
Name: Adam, Age: 25
Close Connection
================================
Configure Mail Server
Send Mail to user Adam
================================

 BiConsumer Functional Interface


It is very similar to Consumer Functional Interface. The only difference is just that it will accept two input arguments instead of one and will return nothing

@FunctionalInterface
public interface BiConsumer<T,U> {
            accept(T t, U u);
}


Let’s see an example

Example 4:

import java.util.function.BiConsumer;

public class BiConsumerExample {

       public static void main(String[] args) {

             BiConsumer<String, String> fullName = (fn, ln) -> System.out.println(fn.concat(" " + ln));

             fullName.accept("Abdul", "Waheed");
       }
}
 Output:
Abdul Waheed 

That’s it for Consumer and BiConsumer Functional Interface, Will talk about other Predefined Functional Interface in my next blog.

Happy Coding…!!!

How TOPT Works: Generating OTPs Without Internet Connection

Introduction Have you ever wondered how authentication apps like RSA Authenticator generate One-Time Passwords (OTPs) without requiring an i...