Default Method in Java

The default method in Interfaces was introduced in Java 8. It allows the interface to implement a method in the interface which is inherited by implementing classes.

What are default methods?

Before Java 8 methods in the interface could have only public and abstract modifiers for methods and public, static and for fields public and static or blank (blank means public and static field).

Java 5

Following are two interfaces in Java 5, the first one is valid and the second one is not.
Valid Interface in Java 5
interface Java5Interface {
	public static int four = 4;
	int five = 5; // implicitly public static

	public abstract void welcome();
	public void sayHi();
	void bye();
}
Invalid Interface in Java 5
interface Java5Invalid {
	private int six = 6;            //illegal only public static and final is permitted
	private void cleanuup(); // illegal only public and abstract is permitted
}
As you can see for fields only public, static, and final modifiers are allowed. If nothing is mentioned then also all fields in Java 5 is public static and final implicitly. For methods, we can have only public and abstract as modifiers.

Java 8 and onwards

Starting Java 8 methods in the interface can have the following modifiers public, private, abstract, default, static, strictfp. Nothing changes for fields, fields can still have public, static, final modifiers. In the following example, we have a Greetings Interface with two default methods greet and openDoor respectively. This interface also has one static method lockdoor.
Interface Greetings in Java 8
interface Greetings {
	
	public default void greet() {
		openDoor();
		sayHi();
		sayBye();
		closeDoor();
	}
	
	default void openDoor() {
		//open the door
	}
	
	void sayHi();
	
	void sayBye();
	
	private void closeDoor() {
		lockDoor();
	}

	static void lockDoor() {
		//lock door implementation
	}
}
The benefit of having a default method is that now the interface can provide a default implementation of methods through the default modifier. For instance, the interface Greetings provided a default implementation for method greet(). Also the later we can add more default, private or static methods to the Interface without breaking binary compatibility meaning implementing classes don't need to do any modification to be able to compile and run successfully.
Importat Points
  • default methods are public.
  • default methods are inherited by implementation classes.
  • default methods can be overridden by implementation classes.
  • a default method can add more functionality to the Interface without breaking binary compatibility.
  • static methods are also allowed which are Interface level methods and cannot be overridden by subclasses.
  • Java 8 methods can have public, private, abstract, default, static, and strictfp.

References

Convert Java Set to List

In this article, we will go through 4 different ways to convert java Set to Java List object.
Java Set Object
mySet is the Set object which contains 4 Strings.
Set  mySet = new HashSet(Arrays.asList("Red", "Yellow", "Green", "Blue"));
Using Constructor
List  myList = new ArrayList(mySet);
Using addAll
Using the addAll method we can add all the items in the set to list-objects.
List  myList2 = new ArrayList();
myList2.addAll(mySet);
Using for each
By using for each to loop though all the items in the Set we can add them one by one to the List.
List  myList3 = new ArrayList();
mySet.forEach(a->myList3.add(a));
Using Java Stream
List  myList4 = mySet.stream().collect(Collectors.toList());
Full source code
package myjava.work.general;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class JavaListFromSet {

	public static void main(String[] args) {
		Set<String> mySet = new HashSet<String>(Arrays.asList("Red", "Yellow", "Green", "Blue"));

		// Using Constructor
		List<String> myList = new ArrayList<String>(mySet);
		myList.forEach(a -> System.out.println(a));

		// Using addAll
		List<String> myList2 = new ArrayList<String>();
		myList2.addAll(mySet);
		myList2.forEach(a -> System.out.println(a));

		// Using For Each
		List<String> myList3 = new ArrayList<String>();
		mySet.forEach(a -> myList3.add(a));
		myList3.forEach(a -> System.out.println(a));

		// Using Stream
		List<String> myList4 = mySet.stream().collect(Collectors.toList());
		myList4.forEach(a -> System.out.println(a));

	}
}


In this article, we will examine different ways to write Comparators in java to sort the multidimensional arrays. Comparator is a functional interface in java.
java.util.Arrays class contains various utility methods to manipulate arrays one of the important methods is Sort. This method takes two parameters the array that needs to be sorted and the optional Comparator. If we don't pass the Comparator then the array will be sorted based on the natural ordering of the elements.

Sorting Array

Our Array
Let's say we want to represent multiple points with x,y coordinates in an array. The following represents one such example.
{ { 20, 25 },{ 10, 15 }, { 10, 25 }, { 20, 15 }}
We want to sort the array based on x and y-axis values.

Comparators

Comparator Implementation as a Class
Here we are implementing a Comparator called MultiDimArrayComparator and then we can use this comparator to sort Array
class MultiDimArrayComparator implements Comparator {
	@Override
	public int compare(int[] m, int[] n) {
		return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
	}
}

Arrays.sort(arr, new MultiDimArrayComparator());
Comparator as an anonymous class
Here we are implementing Comparator as an anonymous class and providing a definition of compare method.
Arrays.sort(arr, new Comparator() {
	@Override
	public int compare(int[] m, int[] n) {
		return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
	}
});
Comparator as lambda expression (Java 8+)
Here we are implementing Comparator as a lambda function.
Arrays.sort(arr, (m, n) -> m[0] == n[0] ? m[1] - n[1] : m[0] - n[0]);

Full Example


public class ArraysSort {

	public static void main(String[] args) {
		int arr[][] = { { 20, 25 },{ 10, 15 }, { 10, 25 }, { 20, 15 }};

		int arr1[][] = arr;
		
		Arrays.sort(arr1, new MultiDimArrayComparator());
		System.out.println("Sorted Result");
		for (int[] x : arr1) {
			System.out.println(x[0] + " " + x[1]);
		}
		
		arr1 = arr;
		Arrays.sort(arr1, new Comparator<int[]>() {
			@Override
			public int compare(int[] m, int[] n) {
				return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
			}
		});
		System.out.println("Sorted Result");
		for (int[] x : arr1) {
			System.out.println(x[0] + " " + x[1]);
		}

		arr1 = arr;
		Arrays.sort(arr1, (m, n) -> m[0] == n[0] ? m[1] - n[1] : m[0] - n[0]);
		System.out.println("Sorted Result");
		for (int[] x : arr1) {
			System.out.println(x[0] + " " + x[1]);
		}
	}

}

class MultiDimArrayComparator implements Comparator<int[]> {
	@Override
	public int compare(int[] m, int[] n) {
		return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
	}
}

Running the code

Sorted Result 10 15 10 25 20 15 20 25 Sorted Result 10 15 10 25 20 15 20 25 Sorted Result 10 15 10 25 20 15 20 25

Conclusion

Here we implemented the same Comparator to sort two-dimensional arrays in three different styles.

Aws lambda handlers

While implementing AWS lambda functions in java we need to implement a Handler interface . The lambda environment will invoke the implementation of the Handler interface.
The Handler interface is a functional interface It has just one method that needs to be implemented. Broadly speaking AWS supports two different types of handlers. Following are the two interfaces that can be chosen to implement the handler.
The aws-lambda-java-core library defines two interfaces for handler methods.
com.amazonaws.services.lambda.runtime.RequestHandler
com.amazonaws.services.lambda.runtime.RequestStreamHandler

Choosing the right handler

Choosing the right Handler depends on the use cases. If we are working with simple Objects as input like String, Integer, Map, etc then RequestHandler is a good choice. If we want to work with more complicated input/output objects or we want to control the way the input and output get converted to String then RequestStreamHandler is the option.
RequestHandler
This interface is a generic interface. The handleRequest method takes two objects as input and also returns an object. The java runtime in the lambda environment deserializes and serializes input event and returned object from the method
public interface RequestHandler {
    /**
     * Handles a Lambda Function request
     * @param input The Lambda Function input
     * @param context The Lambda execution environment context object.
     * @return The Lambda Function output
     */
    public O handleRequest(I input, Context context);
}
RequestStreamHandler
This handler works with InputStream and OutputStream. It gives more control over how we want to perform the serialization/deserialization etc.
public interface RequestStreamHandler {
    /**
     * Handles a Lambda Function request
     * @param input The Lambda Function input stream
     * @param output The Lambda function output stream
     * @param context The Lambda execution environment context object.
     * @throws IOException
     */
    public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException;
}
Summary
  • RequestStreamHandler : If we need to customize the serialization and deserialization process then RequestStreamHandler is the choice.
  • RequestHandler: It is the most suitable handler in most cases.

References

How to download source for maven artifacts

Maven builds a project using its project object model (POM) and a set of plugins. Dependencies used by the project are mentioned in the pom.xml file. We can also get the dependencies artifact from maven along with source codes.

In the following section, we will cover two use cases
1) How to generate source code for third-party artifacts that my project is using
2) How to generate source code for my project
Download sources for third party artifacts
Executing the following command from the terminal will download the sources for all the artifacts for the project and will attach it to Eclipse IDE.
mvn eclipse:eclipse -DdownloadSources=true
Executing the following command from the terminal will download the sources for all the artifacts only, attaching the sources in the IDE with the binaries needed to be done seperately..
mvn dependency:sources -Dsilent=true
Generate source code for project
This command will generate the sources jar under the target folder for the project.
mvn source:jar install

Generating Random Number in Java

This article summarizes different ways to use the Random() class in java to generate bounded or unbounded random numbers. It also shows another important feature of the class that is using seed to generate same set of random numbers.
java.util.Random used used to generate bounded or unbounded random numbers. It supports specifying a seed which is used to set the internal state of the pseudorandom number generator. Random(): creates new random generator Random(long seed): creates new random generator using specified seed
Unbounded generate 5 random numbers
Following code prints 5 random numbers unbounded without any seed
public static void generateRadom() {
	System.out.println("\nPrinting 10 Random Numbers");
	Random generator = new Random();
	for (int i = 0; i < 5; i++) {
		System.out.print(generator.nextInt() + " ");
	}
}
Invocation 1
Printing 5 Random Numbers -1937915077 75383412 -901884443 1725835531 1371480362
Invocation 2
Printing 5 Random Numbers -1261854044 328673857 -1787159304 446964878 -283294822
Notice that in both the invocations the generated numbers are different. This is because we have not set any seed in the Random Class.
Random Bounded Number
Following method will generate 5 random numbers between 0 and 99
public static void generateRadomBounded() {
	System.out.println("\nPrinting 5 Random Numbers Between 0 and 99");
	Random generator = new Random();
	for (int i = 0; i < 5; i++) {
		System.out.print(generator.nextInt(100) + " ");
	}
}
Invocation 1
Printing 5 Random Numbers Between 0 and 99 25 95 13 60 67
Invocation 2
Printing 5 Random Numbers Between 0 and 99 17 10 21 96 15
Generate Random number bounded with a seed
Bellow function will generate bounded 5 random numbers but since we are setting a seed, if the seed is same on multiple invocation then each invocation will generate the same set of random numbers.
public static void generateRadomWithSeed(long seed) {
	System.out.println("\nPrinting 5 Random Numbers Between 0 and 99 with seed");
	Random generator = new Random(seed);
	for (int i = 0; i < 5; i++) {
		System.out.print(generator.nextInt(100) + " ");
	}
}
Invocation 1
Printing 5 Random Numbers Between 0 and 99 with seed 4 62 52 3 58 67
Invocation 2
Printing 5 Random Numbers Between 0 and 99 with seed 4 62 52 3 58 67
Summary
  • If we want to generate the same set of random numbers, we can set seed.
  • Test cases can use seed to make sure it gets same set of random numbers.
  • We can have bounded or unbounded random numbers.

Change Project Explorer tree view font size in Eclipse

This article shows how to change the Project Explorer text size and style.
Starting with Eclipse 4.17, Eclipse now supports additional options to change the font and style of the IDE.  Bellow sections shows few examples.

Project Explorer
Change the font of the Project Explorer
Window > Preferences > General > Appearance > Colors and Fonts > View and Editor Folders > Tree and Table font for views

Setting the font size

Result of the Project Explorer




Java Editor
Change the font of the Java Editor
Window Menu -> Preferences -> General > Appearance > Color and Fonts > Java > Java Editor Text Font > Edit & Apply

Editor Font Size Setting


Editor Content



Remove Git from a Repo

Sometimes we want to remove the reference to existing repository details, such as cloned from github so that we can check the code in a different git repository or a different version control system. This article covers the steps that we can take to remove git references. If we clone a repo or fork a repo from git, the newly created repository will have git references as version control. If we want to remove the git references from the new repository then we need to delete all the git references. Once we remove the git references then it will not have any reference to old repository and we can use this project folder to create a brand new repository in git or any other version control system. This article talks about how to remove
The good thing is that all the git related information is stored in a folder .git . Normally we would have only one .git folder in the root of the repository, but we might have more than one .git folder based on how the repository is configured. Apart from .git folder we might have following git specific files, .gitignore: allows to include/exclude files to be synced to git remote server
.gitkeep: allows us to include an empty directory to be synced to git remote server
. gitattributes: allows us to ensure consistent git settings across the machine.
Essentially we need to delete all these git related folder/files that will make our repository clean and without any git version details. The following sections show how to achieve the same in a Windows environment and Mac environment

Windows

The rmdir or rd command will not delete/remove any hidden files or folders within the directory you specify, so we should use the del command to be sure that all files are removed from the .git folder. Open the command prompt Navigate to the project directory, i.e. - cd path_to_your_repository
del /F /S /Q /A .git

rmdir .git

Mac

Open a terminal and navigate to the directory of your project, i.e. - cd path_to_your_repository. And run the following commands
rm -rf .git
rm -rf .gitkeep
rm -rf .gitignore
rm -rf .gitattributes
Checking if you have any .git folder left
Go to the directory of your project and run the following command which finds the only the folder with the name .git and prints its path in the console.
find . | grep -i .git

Microservices Registration and Discovery using Spring Cloud, Eureka

This blog post drives though an implementation pattern and a working setup with multiple microservices where they get registered with Eureka and the client can discover them and invoke them

What is Eureka

Eureka is a REST-based service that provides support for discovering other services so that clients can use the Eureka service to discover services and calling those services.

Why we need Discovery Service

In a Microservices architecture where we have multiple services running, we need a mechanism to know what are the services and how to invoke them. Each service typically will have a different URL or IP address to reach out to. Also, clients of those microservices need to know when a new


microservice is added or an existing microservice was taken down for maintenance. Discovery service provides that mechanism, where services can register themself in the discovery service and clients, can query the discovery service to know more about the available microservices.

Project achievement

In this project, we will go through an end to end use case where we will have a client microservice calling another microservice utilizing Eureka discovery service. Essentially we want to find existing services by looking up in discovery service and then invoking the target service without knowing about their whereabouts like URL, or IP or port, etc. For that, we will build a discovery server one service microservice and one client microservice.
Project Contents
  • Eureka Discovery Service: Provides the registration and discovery
  • Article Microservice: Provides REST services for Article CRUD operation
  • Client Microservice: Invokes the article microservice



Above pictures show what we are going to achieve in very high level
1) We will deploy a Discovery service
2) We will deploy Article Service which registers itself with discovery service with a unique name.
3) We will deploy a consumer application which is another spring boot application which will invoke the
     Article Service by its name.

Technology Used

Java 11
Apache Maven 3.5.0
Spring Boot 2.2.6
Spring Cloud Hoxton.SR1
Netflix Ribbon 2.3.0
Open Feign
JSON

Discovery Server

The following section highlights the important code related to Eureka Server. The details can be looked into in the git repo. Mainly we need to add the maven dependency for Eureka Discovery Server, in the spring boot properties file add the server port and defaultZone and annotate the SpringBoot Application class with @EnableEurekaServer.
We need to include the Netflix Eureka Server dependency in the maven pom file.
pom.xml
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
application.properties
server.port=8761

##Eureka Related
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/
eureka.client.healthcheck.enabled=true
The Eureka Discovery Server is a Spring Boot application that is very simple. We need to annotate the application with @EnableEurekaServer. @EnableEurekaServer allows this application to run as a Eureka server, aided by Spring Boot to instantiate Eureka-related beans based on configuration properties.
ServiceDiscovery.java
package com.bootng.service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class ServiceDiscovery {
  public static void main(String[] args) {
    SpringApplication.run(ServiceDiscovery.class, args);
  }
}
Now when we build and start the discovery server and access the server through http://localhost:8761 we would see something like bellow. Notice the following screenshots shows no entries under applications because no other services are up yet.


Discovery Service UI


Article Service

Now we will build and deploy the Article microservice which is another spring boot application that registers itself with the discovery service. The name with which this service is registered is "article-service" and is defined in bootstrap.properties file.
pom.xml
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.properties
## Server Related
server.port=9051
## Eureka Related
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false
eureka.vipAddress=article-service
bootstrap.properties
spring.application.name=article-service
Following is the main application class representing Article Microservice.
ArticleMicroservice
@ComponentScan({ "com.siddb" })
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class ArticleMicroservice {
	public static void main(String args[]) {
		SpringApplication.run(ArticleMicroservice.class, args);
	}
}
This Spring Boot Application exposes the following REST endpoints through the ArticleController.java class. And registers itself with the service discovery with the name "article-service"
ArticleController.java
@RestController
@RequestMapping("/api")
public class ArticleController {
  private static final Logger log = LoggerFactory.getLogger(ArticleController.class);
  @Autowired
  ArticleService articleService;

  @RequestMapping(value = {"/articles"}, method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<List<Article>> getArticles() throws AppException {
    List<Article> articles = articleService.getArticles();
    return new ResponseEntity<List<Article>>(articles, HttpStatus.OK);
  }

  @RequestMapping(value = {"/articles/{id}"}, method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<Article> getArticle(@PathVariable(value = "") String id)
      throws AppException, NotFoundException {
    Article articles = articleService.getByID(id);
    return new ResponseEntity<Article>(articles, HttpStatus.OK);
  }
 //other methods for POST and Deleted removed from here for readability.
}
REST Endpoints
  • GET http://localhost:9051/api/articles
  • GET http://localhost:9051/api/articles/ARTICLE_ID
  • POST http://localhost:9051/api/articles PAYLOAD
  • DELETE http://localhost:9051/api/articles/ARTICLE_ID

Sample Response

GET http://localhost:9051/api/articles
[
  {
    "id": "America-Travel",
    "name": "America Travel",
    "description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum",
    "category": "Travel"
  }
]
GET http://localhost:9051/api/articles
Sample Response: [ { "id": "America-Travel", "name": "America Travel", "description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", "category": "Travel" } ]
[ { "id": "America-Travel", "name": "America Travel", "description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum", "category": "Travel" } ]

Article Client Service

Now we will build and deploy the Client Service application which is another Spring Boot application that consumes the REST services deployed by Article Service. Most interesting part
pom.xml
<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-loadbalancer</artifactId>
	</dependency>
	<!--ribbon related -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-openfeign</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>
application.properties
hostname=localhost
logging.level.org.springframework=info
logging.level.root=info
spring.main.banner-mode=off
server.port=9053

##Management
management.endpoint.health.show-details
management.health.key.ping=enabled
management.endpoints.web.exposure.include=info,health,mappings

##Eureka Related
eureka.instance.leaseRenewalIntervalInSeconds=1
eureka.instance.leaseExpirationDurationInSeconds=90
eureka.instance.hostname=${hostname}
eureka.instance.hostname.metadataMap.instanceId=${spring.application.name}:${server.port}
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/
eureka.client.healthcheck.enabled=true

##Eureka Ribbon
article-service-consumer.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
article-service-consumer.ribbon.DeploymentContextBasedVipAddresses=article-service
Following is the Consumer Application Class. We have annotated it with @EnableDiscoveryClient so that it can discover other services registered with the Discovery Server.
ConsumerApplication
@ComponentScan({"com.siddb", "com.siddb.controller"})
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
  public static void main(String args[]) {
    SpringApplication.run(ConsumerApplication.class, args);
  }
}
Following is the main controller which uses the discovery service internally and invokes services on the service article-service using ribbon. From the ribbon configuration in (application.properties), it knows article-service-consumer is tied to a service with VIP Address (name) article-service.
RibbonController.java
@RestController
public class RibbonController {

  @Autowired
  private RestTemplate restTemplate;

  /**
   * This method calls the microservice GET article-service/api/articles using Ribbon to get a list of
   * Articles and returns the same. it uses RestTemplate to make the API calls.
   * @return
   * @throws Exception
   */
  @RequestMapping(value = {"render"}, method = RequestMethod.GET,
      produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<String> renderArticles() throws Exception {
    JsonNode repos =
        restTemplate.getForObject("http://article-service-consumer/api/articles", JsonNode.class);

    int counter = 1;
    StringBuilder result = new StringBuilder("\n List of Articles");
    if (repos.isArray()) {
      for (JsonNode jsonNode : repos) {
        result.append("\n Repo ").append(counter++).append("::");
        result.append(jsonNode.get("name").asText());
      }
    }
    return new ResponseEntity<String>(result.toString(), HttpStatus.OK);
  }
}
The Consumer Controller uses the ribbon configuration that we have added in the property file to invoke the article service by the ribbon name "article-service-consumer". This is where the Consumer controller will discover the actual API for the corresponding service name. And call GET http://article-service-consumer/api/articles will be actually to http://localhost:9051/api/articles. This is how using the Eureka Discovery service the client becomes independent of the service (IP address, port, etc.). The client simply can refer to the service with its published name.

Start Microservices

Now the fun part, start all the microservices and invoke the /render REST API. We need to start all services (discovery service, article service, consumer service). For that, we first need to check out the repo from git and build/run each project.
1) git clone https://github.com/siddharthagit/spring-boot-sdc.
2) go to the root folder that contains this repo.
3) open 3 Terminals one for each subproject (eureka-service-discovery, ms-article-service, ms-consumer-service).
4) build each project and start the services.
mvn clean install
mvn spring-boot:run
5) Check the status of each service on the discovery server http://localhost:8761
6)Invoke the REST API on consumer service http://localhost:9053/render
This API internally will use the discovery server to resolve the service and will route the call to http://localhost:9051/api/articles.
http://localhost:9053/render
List of Articles Repo 1::America Travel Repo 2::Asia Travel Repo 3::Europe Travel Repo 4::Road Trip Repo 5::Winter Travel Repo 6::Japan Travel

Discovery Server UI with all services running


Conclusion

In this article, we've covered how to use Spring Cloud Eureka for service discovery in the microservice/cloud environment. We created two simple REST services that communicate with each other without hardcoding any hostname/port while making REST calls. Though in this article we have shown how the client can invoke the article service with ribbon, the git repo also contains a Feign client that uses Feign and will be covered in a different article.

References


Integer to Binary

In This Article we will see how we can convert Integer to Binary number. We will see some built in options that Java provides as well as two different custom implementation.
Using Integer.toBinaryString
Using Integer.toBinaryString() method we can convert a integer to Binary String very easily
private static String toBinary1(Integer i) {
    return Integer.toBinaryString(i);
}
Using Integer.toString()
We can also use Integer.toString() and pass the number and radix to convert the integer to String. In this case we pass 2 as radix to convert the Integer to Binary Number String.
 private static String toBinary2(Integer i) {
    return Integer.toString(i, 2);
  }
Using BigInteger
BigInteger also provides a toString() method where we can pass 2 as radix to convert it to Binary Number String.
private static String toBinary2(Integer i) {
    BigInteger bigInt = new BigInteger(String.valueOf(i));
    return bigInt.toString(2);
  }
By Dividing.
Following code is a custom method to convert an Integer to Binary.
private static String toBinary_divide(Integer i) {

    StringBuilder ret = new StringBuilder();

    while (i > 0) {
      
      if (i % 2 == 1) {
        ret.insert(0, "1");
      }
      else {
        ret.insert(0, "0");
      }
      i = i / 2;
    } 

    return ret.toString();
  }
By using Bit masking
This is another custom method to convert Integer to Binary String. This Algorithm works by masking each bit in the original number and creating a char array. And finally converting the char array to String.
private static String toBinary_mask(Integer num) {
    char ret[] = new char[32];

    for (int i = 0; i < 32; i++) {
      int mask = 1 << i;
      ret[31 - i] = (num & mask) != 0 ? '1' : '0';
    }
    return new String(ret);
  }

Full Code

IntegerToBinaryConverter.java
import java.math.BigInteger;

public class IntegerToBinaryConverter {

  public static void main(String[] args) {
    System.out.println("Convert to Binary 2020 = " + toBinary1(2020));
    System.out.println("Convert to Binary 2020 = " + toBinary2(2020));
    System.out.println("Convert to Binary 2020 = " + toBinary3(2020));
    System.out.println("Convert to Binary 2020 = " + toBinary_divide(2020));
    System.out.println("Convert to Binary 2020 = " + toBinary_mask(2020));
  }

  private static String toBinary1(Integer i) {
    return Integer.toBinaryString(i);
  }

  private static String toBinary2(Integer i) {
    return Integer.toString(i, 2);
  }

  private static String toBinary3(Integer i) {
    BigInteger bigInt = new BigInteger(String.valueOf(i));
    return bigInt.toString(2);
  }

  private static String toBinary_divide(Integer i) {
    StringBuilder ret = new StringBuilder();
    while (i > 0) {
      if (i % 2 == 1) {
        ret.insert(0, "1");
      }
      else {
        ret.insert(0, "0");
      }
      i = i / 2;
    } 
    return ret.toString();
  }

  private static String toBinary_mask(Integer num) {
    char ret[] = new char[32];
    for (int i = 0; i < 32; i++) {
      int mask = 1 << i;
      ret[31 - i] = (num & mask) != 0 ? '1' : '0';
    }
    return new String(ret);
  }
}
Console Output
Convert to Binary 2020 = 11111100100 
Convert to Binary 2020 = 11111100100 
Convert to Binary 2020 = 11111100100 
Convert to Binary 2020 = 11111100100 
Convert to Binary 2020 = 00000000000000000000011111100100

Summary

This article shows different ways to convert the Integer to Binary String. The Bit masking is very efficient and in fact the builtin methods like Integer.toString() uses Bit masking internally. For more information on Bit masking the links provided in Reference section is very useful.

References

JavaScript Data Types

This article covers the datatypes available for JavaScript. The latest ECMAScript standard defines nine types: 7 Primitive types and 2 Structural Types.

Primitive Types

The six primitive types are Boolean, Null, Undefined, String, Number, BigInt, and Symbol.

Boolean type

Boolean represents a logical entity and can have two values: true and false. The Boolean object will be with the initial true only if the parameter passed is an object, array, or true. Else the Boolean object will be false.
Following code shows the different values the Boolean object will have when passed different parameters.
var b1 = new Boolean(); 
console.log(b1); //false

var b2 = new Boolean(false); 
console.log(b2);//false

var b3 = new Boolean(0); 
console.log(b3);//false

var b4 = new Boolean(NaN); 
console.log(b4);//false

var b5 = new Boolean(undefined); 
console.log(b5);//false

var b6 = new Boolean(null);
console.log(b6); //false

var b7 = new Boolean({}); 
console.log(b7);//true

var b8 = new Boolean(true); 
console.log(b8);//true

var b9 = new Boolean([]); 
console.log(b9);//true

Null type

The Null type has exactly one value: null. Every Object is derived from null value, and therefore typeof operator returns object for it.
The following code shows one important feature of null, it is of type object.
var n1 = null; 
console.log(n1); //null
console.log(typeof n1); //object

Undefined type

A variable that has not been assigned a value has the value undefined.
The following code shows one example where a variable u1 is defined but not assigned any value.
var u1 ;
console.log(typeof u1);//undefined
console.log(u1);//undefined

String

The string type is used to represent textual data. JavaScript strings are immutable. This means that once a string is created, it is not possible to modify it
Strings can be created as primitives, from string literals, or as objects, using the String() constructor. In case of primitive typeof returns "string" otherwise it returns "object". String object can be converted to string primitives using valueOf() method on the String object.
const string1 = "A string primitive";
const string2 = new String("A String object");
console.log(typeof string1); //string
console.log(typeof string2); //object
console.log(typeof string2.valueOf());//string 

Number

The Number type is a double-precision 64-bit binary format IEEE 754 value (numbers between -(2^53 − 1) and 2^53 − 1). In addition to representing floating-point numbers, the number type has three symbolic values: +Infinity, -Infinity, and NaN ("Not a Number"). Number.MAX_VALUE or Number.MIN_VALUE represents the maximum and minimum values possible using numbers.
console.log(Number.MAX_VALUE); //1.7976931348623157e+308
console.log(Number.MIN_VALUE); //5e-324
console.log(1/0); //Infinity

BigInt type

The BigInt type is a numeric primitive in JavaScript that can represent integers with arbitrary precision. A BigInt is created by appending n to the end of an integer or by calling the constructor. BigInts cannot be operated on interchangeably with Numbers. Instead, a TypeError will be thrown.
Following code shows how to find the value of 2^53, we have choosen 53 because then the product value will be beyond the capacity of numbers. If you
const xbig = 2n ** 53n;
console.log(xbig); //9007199254740992n

Symbol type

A Symbol is a unique and immutable primitive value and may be used as the key of an Object property (see below).
The following example shows how to create a Symbol object.
let sym1 = Symbol()
let sym2 = Symbol('foo')
let sym3 = Symbol('foo')

Structural Types

Object and Functions are two structural data types.
typeof operator shows that for object and function the operator returns "object" and "function" respectively.
var o1 = {}; 
console.log(typeof o1);//object

var f1 = function () {}; 
console.log(typeof f1);//fuction