Uncategorized

Stack with O(1) push complexity

This is a stack program where the algorithm works on Last in First Out (LIFO) concept. This is a typical stack program with insertion complexity as O(1) i.e constant.


/**
*
*/
package java8pract.datastructures;

import java.util.ArrayList;
import java.util.List;

/**
* @author prabhukvn
*
*/
public class CustomStack<T extends Comparable> {
Node firstNode;
Node lastNode;
Node tempNode;
int stackSize = 0;

public void push(T element) {
Node node = null;
if (null == firstNode) {
node = new Node(null, element, null);
firstNode = node;
stackSize++;

} else {

Node middleNode = tempNode;
node = new Node(middleNode, element, null);
middleNode.next = node;
lastNode = node;
stackSize++;
}
tempNode = node;

}

public int getSize() {
return this.stackSize;
}

public T pop() {

T element = lastNode.element;
lastNode = lastNode.previous;
lastNode.next=null;
stackSize--;
return element;

}

/**
* Get all the elements in linked list
*
* @return
*/
public List<Node> getAll() {
List<Node> list = new ArrayList();
Node temp = firstNode;
while (temp != null) {
list.add(temp);
System.out.println(temp.element);
temp = temp.next;

}
return list;
}

}

Uncategorized

Linked List with O(1) Insertion Complexity

A simple linked list program where insertion complexity is O(1) order of one i.e independent of data size.

Here is the code for the same

Here is the Node/Element/Data object of linked list

Note: This program has been written with minimum code so that users can copy and experiment with it. This is not a full fledged program, hence not recommended for production use.


public class Node {

Node previous;
T element;
Node next;

public Node(Node previous, T element, Node next) {
this.previous=previous;
this.element=element;
this.next=next;

}

@Override
public String toString() {
return “Node [element=” + element + “]”;
}

}


And here is the linked list implementation,

package java8pract.linkedlist_custom;
/**
* An implementation of linked list. Entire linked list is dependent on first element in the list.
*/
import java.util.ArrayList;
import java.util.List;

public class CustomLinkedList {

Node firstNode;
Node tempNode;
Node lastNode;
/**
* Add an element to the linked list
* +/—————————————-
* + 1. if first node is null, create a node and assign it to first node.
* + 2. and assign the newly created node to a temp Node;
* + 3. for consecutive additions, get the temp node into a middle methods level node
* + 4. Create new node and assign previous node as middle node.
* + 5.update the last node.
* + 6. middle node.next to newly created node
* + 7. and update temp node with newly created node.
* @param element
*/

public void add(T element) {
Node node = null;
if (null == firstNode) {
node = new Node(null, element, null);
firstNode = node;

} else {
Node middleNode = tempNode;
node = new Node(middleNode, element, null);
lastNode = node;
middleNode.next = node;

}
tempNode = node;
}

/**
* Get all the elements in linked list
*
* @return
*/
public List getAll() {
List list = new ArrayList();
Node temp = firstNode;
while (temp != null) {
list.add(temp);
System.out.println(temp.element);
temp = temp.next;

}
return list;
}

/**
* Get all the elements in the linked list in reverse order.
*
* @return
*/
public List getAllReverse() {
List list = new ArrayList();
Node temp = lastNode;
while (temp != null) {
list.add(temp);
System.out.println(temp.element);
temp = temp.previous;

}
return list;

}

public Node get(T t) {

Node temp = firstNode;
while (temp != null) {

if (temp.element !=null && temp.element.compareTo(t)==0) {
break;
} else {
temp = temp.next;
}
}

return temp;

}
/**
* Get the first node (HEAD) in the linked list
* @return
*/
public Node getFirstNode(){
return firstNode;
}
/**
* Get the last node in the linked list.
* @return
*/
public Node getLastNode(){
return lastNode;
}


}

Uncategorized

Easiest way to create MongoDB Cluster in MacOS

An easiest way to create mongodb cluster in MacOs environment.

These steps can be executed one after the other in Mac Terminal.
Note: Make sure that the folders paths are correct before running these commands.

Create Initial directories required for mongo db cluter

cd /Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data

mkdir replica1 replica2 replica3 replica4 replica5 replica6 replica7 replica8 replica9 config1 config2 config3

Sudo chmod –R 777 repl*

Sudo chmod –R 777 conf*

shard1

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica1 –port=27011 –bind_ip_all –replSet=replica1 –shardsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica2 –port=27012 –bind_ip_all –replSet=replica1 –shardsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica3 –port=27013 –bind_ip_all –replSet=replica1 –shardsvr

rs.initiate({_id:”replica1″,members:[{“_id”:1,”host”:”localhost:27011″}]})

rs.add(“localhost:27012”)

rs.add(“localhost:27013”)

shard2

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica4 –port=27021 –bind_ip_all –replSet=replica2 –shardsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica5 –port=27022 –bind_ip_all –replSet=replica2 –shardsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica6 –port=27023 –bind_ip_all –replSet=replica2 –shardsvr

rs.initiate({_id:”replica2″,members:[{“_id”:1,”host”:”localhost:27021″}]})

rs.add(“localhost:27022”)

rs.add(“localhost:27023”)

Shard 3

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica7 –port=27031 –bind_ip_all –replSet=replica3 –shardsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica8 –port=27032 –bind_ip_all –replSet=replica3 –shardsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/replica9 –port=27033 –bind_ip_all –replSet=replica3 –shardsvr

rs.initiate({_id:”replica3″,members:[{“_id”:1,”host”:”localhost:27031″}]})

rs.add(“localhost:27032”)

rs.add(“localhost:27033”)

config

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/config1 –port=27018 –bind_ip_all –replSet=config1 –configsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/config2 –port=27019 –bind_ip_all –replSet=config1 –configsvr

./mongod –dbpath=/Users/prabhu/Documents/softwares/mongodb-osx-x86_64-4.0.6/bin/data/config3 –port=27020 –bind_ip_all –replSet=config1 –configsvr

rs.initiate({_id:”config1″,members:[{“_id”:1,”host”:”localhost:27018″}]})

rs.add(“localhost:27019”)

rs.add(“localhost:27020”)

Start Mongos with config cluster
./mongos –configdb=”config1/localhost:27018,localhost:27019,localhost:27020″ –port=27017 –bind_ip_all

Connect to Mongos Server
./mongod –port 27017

sh.addShard(“replica1/localhost27011”)

sh.addShard(“replica2/localhost27021”)

sh.addShard(“replica3/localhost27031”)

sharding Collection

sh.enableSharding(“shoppingdb”); // enable sharding for db

sh.shardCollection(“shoppingdb.Orders”,{_id:1},true); // shard the collection

Uncategorized

DDD, Event Driven and CQRS example

There are lot of articles which talks about domain driven design, Event Driven and CQRS architectural practices. However,In this blog post, an effort to put domain driven design (DDD), Event Driven and Command Query Responsibility Segregation in a simple application which will explain all of above concepts. This application has been developed using spring boot, axon ,axon db server, java programming language, maven for build and eclipse etc.
In this application we are just trying to create an order with some order items (Command) and retrieve the same (Query) using order id. This is a very common scenario in any e commerce application and also a good example to explain above concepts.
Here is the out line of flow,

DDD,EVENT DRIVE, CQRS exampl

And here is the git hub url for code

https://github.com/prabhukvn/axon-springboot-poc.git

Uncategorized

Arrays Are Efficient in Java

Here is en example where iterating over an array is much faster than iterating over a list directly. This we can apply if we have to iterate a list over multiple time in a single thread.

private static void checkArrayList() {
ArrayList listOne = new ArrayList();

long startTime = System.nanoTime();
for (int i = 0; i <span id="mce_SELREST_start" style="overflow:hidden;line-height:0;">&#65279;</span>&lt; 1000; i++) {
listOne.add(i);
}
// Total time taken to construct an array list with 1000 elements
System.out.println(&quot;Total Time 1:&quot; + (System.nanoTime() - startTime));

// Iterate entire list
startTime = System.nanoTime();
for (int k : listOne) {

}
// total time to iterate over 1000 elements
System.out.println(&quot;Total Time 2:&quot; + (System.nanoTime() - startTime));

Integer a[] = new Integer[1000];
// Convert list into array
startTime = System.nanoTime();
listOne.toArray(a);
// time to convert list into array
System.out.println(&quot;Total Time 3:&quot; + (System.nanoTime() - startTime));
// Iterate entire array
startTime = System.nanoTime();
for (int k : a) {

}
// total time taken to iterate over array
System.out.println(&quot;Total Time 4:&quot; + (System.nanoTime() - startTime));
}
Architecture · ATG · ATG External Cache · Cache · RESTFul

ATG Cache Using JBOSS Data Grid/Infinispan

ATG Cache Using JBOSS Data Grid/Infinispan

 

As performance is really important in retail Or web commerce applications, the caching plays an important role in improve the performance. ATG Commerce servers are loaded with lot of components and functionality. And top of that, repository caching will increase enormous memory consumption on ATG JVM’s. Hence, externalizing this cache is an important aspect to reduce the memory foot prints and also reduce the  overall load on ATG servers.

        JBoss data grid internally uses infinispan cache stores to handle the data. On top of infinispan, JDG has provided some more wrappers to include grid features like map/reduce and search functionalities.

Infinispan an open source version of JBoss Data Grid

Infinispan works in 4 caching modes.

·         Local Mode

·         Replicated Mode

·         Invalidation Mode

·         Distribution Mode (Preferred)

 

Where Distributed caching is more appropriate in most of the scenarios. And Replication mode provides an very high available cluster and consumes huge RAM .

 

ATG and JBoss Data Grid Integration

 

JBoss Data Grid/Infinispan works with TCP connections (at Base) between the clusters nodes. And it depends  onJgroups” as the communication configuration to form the Clusters. Jgroups will use TCP Or UDP to form clusters.

 

Cache grid Cluster

 

Using JBoss Cache Servers (Preferred)

·         Hotrod is an effective protocol to communicate with JBOSS data grids.

·         Clients like ATG App servers can connect to data grids using hotrod protocol.

·         We can host a cluster of cache servers using JBoss infinispan servers. These servers can form a cluster using “Jgroups” module which part of JBoss inbuilt modules.

4.       These jboss cache instances are deployed in a domain, so that they can be managed and configured accordingly.

5.       And jgroups use the multicast discovery protocols to find and add related  cache instances to a cluster.

6.       Each JBoss cache server instance start an individual embedded infinispan instance and form a cluster with rest of the instances.

7.       An integrated dashboard is available to check the health and performance of cluster. This dashboard can be used to configure Or fine tune the cache stores installed as part of data grids.

 

The following diagram depicts the 4 cache server instances On 2 hosts And an inbuilt load balancer and A controller.

 

 

image002

  

 

Using embedded Jar files

 

The above described clustered configuration can be achieved by embedded cache application instances. Multiple instances of a simple embedded cache applications are started to form a cluster. These instances use Jgroups to communicate and form a cluster.

 

This grid can be formed on any application servers independent of JBoss

However, JBoss servers provide an integrated dashboard as part of JBoss admin console.  This console will not be available in embedded cache clusters.

 

 

 

ATG Servers to Data grid

 

ATG Servers communicating to data grid using hotrod protocol (Preferred)

 

1.       ATG App serves use HotRod protocol to communicate with Infinispan data grid as depicted in following diagram

2.       This type of communication is essentially powerful if both client and server are JVM based.

3.       Here ATG Server can establish a  communication with cache grid over HotRod protocol.

 

image004

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Repository Cache ingestion into data grid

 

ATG Repositories can externalize its caches to Data grids.

 

Daily refresh/weekly

1.       A complete data refresh can be performed on daily basis/weekly basis by using ATG Scheduler. This activity can be triggered at an off peak time to refresh complete cache data.

2.       This is just to maintain consistence across DB and cache grids.

 

ATG Servers Communicating over REST HTTP

1.       Infinispan data grid also exposes REST end points to communicate over HTTP.

2.       Here, the client can be in any language. And any client can connect to infinispan data grids over http.

3.       This may increase HTTP communication protocol overhead.

4.   And also Object serialization and deserialization is an extra activity as part of this communication.

 

 

PLP/Search

 

1.       Fire a search query to endeca to fetch the relevant product id’s.

2.       Get the complete product data from cache grid using product id’s.

3.       Aggregate the product data and send it to Search/PLP pages.

 

PDP

 

The above search result set can be used to display PDP or else we can re-fetch again from cache grid to paint in PDP

 

Other Pages

It is better to rely on existing database to get the product details.

 

 

*Note: JBoss Data Grid is the licensed version of Infinispan Cache Grid.

 

Java · RESTFul · Spring · spring boot · Swagger

Swagger docs for Spring Boot

Spring boot is becoming famous and famous due to microservice architecture and advantage of spring framework support in it.As REST services are playing a huge role in microservice architecture, swagger introduces a better way to publish these REST services so that they can be tested, published as living documents.

Here is a simple spring boot application having a controlled on it. This controlled exposes a REST services. And this RESt service has been documented using SWAGGER with some simple annotations.

Most of the code is self-explanatory.

Git Link for Code

Run the code using >mvn spring-boot:run

and Access the swagger UI at http://localhost:8080/swagger-ui.html

Java · Servlet3.0

Asynchronous Servlet in 3.0

Async servlet is a new feature added in servlet 3.0 specification. This servlet works in a non-blocking mode. Each request is processed in a new thread which is independent of request thread. The request is temporarily suspended by application till the business logic is executed. Once the application is ready with result, the request will be resumed and the response will be pushed to browser.

The request is temporarily suspended and later resumed or re-dispatched through filters for further processing. This is completely dependent on persistent connection between a browser and server. And all the event which are generated while executing the request are relayed on existing persistent connection.

Required Environment:

Jetty9.x version server Or Tomcat Latest Version.

And example of AyncServlet

package com.servlets;

import java.io.IOException;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class AsyncServletDis
 */
@WebServlet(asyncSupported = true, urlPatterns = { "/asyncservletdis" })
public class AsyncServletDis extends HttpServlet {
 private static final long serialVersionUID = 1L;
 int instanceVariable =1;

 /**
 * @see HttpServlet#HttpServlet()
 */
 public AsyncServletDis() {
 super();
 // TODO Auto-generated constructor stub
 }

 /**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 /*
 * This is an important step to start asynchronous nature of servlet
 * Get the AsyncContext
 */

 AsyncContext aCtx = request.startAsync();
 // add a listener to this context.
 aCtx.addListener(new AsyncListener());
 //aCtx.setTimeout(5000);
 aCtx.start(new Runnable() {

 @Override
 public void run() {
 // TODO Auto-generated method stub

 String sleep = request.getParameter("sleep");
 if(sleep!=null){
 try {
 Thread.sleep(10000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }

 try {
 aCtx.getResponse().getWriter().write("Request Processed");
 System.out.println("Print instance variable#####"+instanceVariable);
 instanceVariable+=1;
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 /*
 * Once completed call the complete method to close asynch process.
 * Either call complete or dispatch to end thread.
 */

 aCtx.complete();
 //aCtx.dispatch("/result.jsp");

 }
 });
 }

 /**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 // TODO Auto-generated method stub
 }

}

And Listener

package com.servlets;

import javax.servlet.AsyncEvent;
import javax.servlet.annotation.WebListener;

import com.sun.media.jfxmedia.logging.Logger;

/**
 * Application Lifecycle Listener implementation class AsyncListener
 *
 */
@WebListener
public class AsyncListener implements javax.servlet.AsyncListener {

 /**
 * Default constructor. 
 */
 public AsyncListener() {
 // TODO Auto-generated constructor stub
 }

 /**
 * @see AsyncListener#onComplete(AsyncEvent)
 */
 public void onComplete(AsyncEvent arg0) throws java.io.IOException { 
 // TODO Auto-generated method stub
 System.out.println("Asyn proces completed..");
 }

 /**
 * @see AsyncListener#onError(AsyncEvent)
 */
 public void onError(AsyncEvent arg0) throws java.io.IOException { 
 // TODO Auto-generated method stub
 }

 /**
 * @see AsyncListener#onStartAsync(AsyncEvent)
 */
 public void onStartAsync(AsyncEvent arg0) throws java.io.IOException { 
 // TODO Auto-generated method stub
 System.out.println("Async process started..."+arg0.getAsyncContext());

 }

 /**
 * @see AsyncListener#onTimeout(AsyncEvent)
 */
 public void onTimeout(AsyncEvent arg0) throws java.io.IOException { 
 // TODO Auto-generated method stub
 }

}