Showing posts with label Spring boot. Show all posts
Showing posts with label Spring boot. Show all posts

Thursday, 14 February 2019

Spring Boot Session Management Hello World Example

Spring Boot + Session Management Hello World Example

In this post we will be implementing Session Management using Spring Boot.
First let us have a look at what is session management and how can it be accomplished.
Video
This tutorial is explained in the below Youtube Video.

What is Session Management?
We all know that HTTP is a stateless protocol. All requests and responses are independent. The server cannot distinguish between new visitors and returning visitors. But sometimes we may need to keep track of client's activity across multiple requests. This is achieved using Session Management. It is a mechanism used by the Web container to store session information for a particular user. 
Session management can be achieved in one of the following ways-
  • Cookies
  • Hidden form field
  • URL Rewriting
  • HttpSession
In this example we will be making use of HttpSession to achieve Session management. Also we will be using the Spring Session module
Spring Session consists of the following modules:
  • Spring Session Core - provides core Spring Session functionalities and APIs
  • Spring Session Data Redis - provides SessionRepository and ReactiveSessionRepository implementation backed by Redis and configuration support
  • Spring Session JDBC - provides SessionRepository implementation backed by a relational database and configuration support
  • Spring Session Hazelcast - provides SessionRepository implementation backed by Hazelcast and configuration support
In this post we will be using Spring Session JDBC to store spring session information. By default Apache Tomcat stores HTTP session objects in memory. 
Spring Boot HTTP Session
In order to achieve writing the session objects to MySQL database, we dont have to write any code. Spring Boot provides us this functionality out of the box by specifying the following configuration property
spring.session.store-type=jdbc
Spring session replaces the HttpSession implementation by a custom implementation. To perform this task spring session creates a SessionRepositoryFilter bean named as springSessionRepositoryFilter.
Lets Begin-
Maven Project will be as follows-

In the Maven we need the Spring Session dependency.Maven will be as follows-
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.journaldev.spring</groupId>
 <artifactId>Spring-Boot-Session-Example</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>Spring-Boot-Session-Example</name>
 <description>Spring-Boot-Session-Example</description>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.0.3.RELEASE</version>
  <relativePath /> <!-- lookup parent from repository -->
 </parent>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>8</java.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-thymeleaf</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.session</groupId>
   <artifactId>spring-session-core</artifactId>
  </dependency>
  <dependency>
   <groupId>org.springframework.session</groupId>
   <artifactId>spring-session-jdbc</artifactId>
  </dependency>
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>


</project>
Create the SpringBootHelloWorldApplication.java as below-
package com.javainuse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootSessionApplication {

 public static void main(String[] args) {
  SpringApplication.run(SpringBootSessionApplication.class, args);
 }
}
Create the Controller class as follows-
package com.javainuse.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class SpringSessionController {

 @GetMapping("/")
 public String process(Model model, HttpSession session) {
  @SuppressWarnings("unchecked")
  List<String> messages = (List<String>) session.getAttribute("MY_SESSION_MESSAGES");

  if (messages == null) {
   messages = new ArrayList<>();
  }
  model.addAttribute("sessionMessages", messages);

  return "index";
 }

 @PostMapping("/persistMessage")
 public String persistMessage(@RequestParam("msg") String msg, HttpServletRequest request) {
  @SuppressWarnings("unchecked")
  List<String> messages = (List<String>) request.getSession().getAttribute("MY_SESSION_MESSAGES");
  if (messages == null) {
   messages = new ArrayList<>();
   request.getSession().setAttribute("MY_SESSION_MESSAGES", messages);
  }
  messages.add(msg);
  request.getSession().setAttribute("MY_SESSION_MESSAGES", messages);
  return "redirect:/";
 }

 @PostMapping("/destroy")
 public String destroySession(HttpServletRequest request) {
  request.getSession().invalidate();
  return "redirect:/";
 }
}

So if not already present,we create an ArrayList named MY_SESSION_MESSAGES in a HTTPSession and persist messages in this list 
Spring Boot HTTP Session Object
The application.properties will be as follows-
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/springSession?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.initialization-mode=always

spring.h2.console.enabled=true

spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
spring.session.timeout.seconds=900

The index.html will be as follows-
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Spring Boot Session Example</title>
</head>
<body>
 <div>
  <form th:action="@{/persistMessage}" method="post">
   <textarea name="msg" cols="40" rows="2"></textarea>
   <br> <input type="submit" value="Save Message" />
  </form>
 </div>
 <div>
  <h2>Messages</h2>
  <ul th:each="message : ${sessionMessages}">
   <li th:text="">msg</li>
  </ul>
 </div>
 <div>
  <form th:action="@{/destroy}" method="post">
   <input type="submit" value="Destroy Session" />
  </form>
 </div>
</body>
</html>
Compile and the run the SpringBootHelloWorldApplication.java as a Java application.
Go to localhost:8080
We can add the items to be stored in the session. The Spring session created 2 tables for storing session related information.
The spring_session table is as follows-
The spring_session_attributes table is as follows-

Download Source Code

Download it -
Spring Boot + Session Management

ELK Stack + Spring Boot Microservice Hello World Example

Spring Boot Microservices + ELK(Elasticsearch, Logstash, and Kibana) Stack Hello World Example


In this tutorial we will be using ELK stack along with Spring Boot Microservice for analyzing the generated logs.
The implementation architecture will be as follows- 
Spring Boot microservice elk stack example

What is ELK? Need for it?

The ELK Stack consists of three open-source products - Elasticsearch, Logstash, and Kibana from Elastic.
  • Elasticsearch is a NoSQL database that is based on the Lucene search engine.
  • Logstash is a log pipeline tool that accepts inputs from various sources, executes different transformations, and exports the data to various targets. It is a dynamic data collection pipeline with an extensible plugin ecosystem and strong Elasticsearch synergy
  • Kibana is a visualization UI layer that works on top of Elasticsearch.
These three projects are used together for log analysis in various environments. So Logstash collects and parses logs, Elastic search indexes and store this information while Kibana provides a UI layer that provide actionable insights.
Use Cases-
  • Consider you have a single application running and it produces logs. Now suppose you want analyze the logs generated. One option is to manually analyze them. But suppose these logs are large, then manually analyzing them is not feasible.
  • Suppose we have multiple Application running and all these applications produce logs. If we have to analyze the logs manually we will need to go through all the log files. These may run into hundreds.
We can use ELK here to analyze the logs more efficiently and also using more complex search criterias. It provides log aggregation and efficient searching.
Video
This tutorial is explained in the below Youtube Video.

Lets Begin

We will first download the required stack.
  • Elasticsearch -
    • Download the latest version of elasticsearch from Elasticsearch downloads 
      elasticsearch example
    • Run the elasticsearch.bat using the command prompt. Elasticsearch can then be accessed at localhost:9200 
      elastic start example
  • Kibana -
    • Download the latest version of kibana from Kibana downloads 
      kibana example
    • Modify the kibana.yml to point to the elasticsearch instance. In our case this will be 9200. So uncomment the following line in kibana.yml-
      elasticsearch.url: "http://localhost:9200"
      
    • Run the kibana.bat using the command prompt. kibana UI can then be accessed at localhost:5601 
      start kibana
  • Logstash -
    • Download the latest version of logstash from Logstash downloads 
      logstash example
    • Create a configuration file named logstash.conf. In further section we will be making the changes for this file and starting logstash.
Lets now come to the spring boot part. We will be creating a simple spring boot application, to generate the logs. 
spring boot elasticsearch example
Define the pom.xml as follows-
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.javainuse</groupId>
 <artifactId>spring-boot-elk</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>spring-boot-elk</name>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.6.RELEASE</version>
  <relativePath /> <!-- lookup parent from repository -->
 </parent>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>


</project>

Create the Spring Boot Bootstrap class as follows-
package com.javainuse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloWorldSpringBootApplication {

 public static void main(String[] args) {
  SpringApplication.run(HelloWorldSpringBootApplication.class, args);
 }
}
Next define the controller to expose REST API. We will be making use of these calls to write content to the log file.
package com.javainuse;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
class ELKController {
 private static final Logger LOG = Logger.getLogger(ELKController.class.getName());

 @Autowired
 RestTemplate restTemplete;

 @Bean
 RestTemplate restTemplate() {
  return new RestTemplate();
 }

 @RequestMapping(value = "/elk")
 public String helloWorld() {
  String response = "Welcome to JavaInUse" + new Date();
  LOG.log(Level.INFO, response);

  return response;
 }

 @RequestMapping(value = "/exception")
 public String exception() {
  String response = "";
  try {
   throw new Exception("Exception has occured....");
  } catch (Exception e) {
   e.printStackTrace();
   LOG.error(e);

   StringWriter sw = new StringWriter();
   PrintWriter pw = new PrintWriter(sw);
   e.printStackTrace(pw);
   String stackTrace = sw.toString();
   LOG.error("Exception - " + stackTrace);
   response = stackTrace;
  }

  return response;
 }
}

Finally specify the name and location of the log file to be created in the application.properties file.
logging.file=C:/elk/spring-boot-elk.log
Next we will configure the logstash pipeline- 
Logstash Pipeline
This is done using the logstash.conf-
input {
  file {
    type => "java"
    path => "C:/elk/spring-boot-elk.log"
    codec => multiline {
      pattern => "^%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}.*"
      negate => "true"
      what => "previous"
    }
  }
}
 
filter {
  #If log line contains tab character followed by 'at' then we will tag that entry as stacktrace
  if [message] =~ "\tat" {
    grok {
      match => ["message", "^(\tat)"]
      add_tag => ["stacktrace"]
    }
  }
 
}
 
output {
   
  stdout {
    codec => rubydebug
  }
 
  # Sending properly parsed log events to elasticsearch
  elasticsearch {
    hosts => ["localhost:9200"]
  }
}
Start logstash using the command prompt as follows-
logstash -f logstash.conf

start logstash
Start the spring boot application by running the HelloWorldSpringBootApplication as a java application.
Logs will be generated in C:/elk folder.
  • goto localhost:8080/elk 
    spring elk
  • goto localhost:8080/exception 
    spring exception
  • go to kibana UI console- localhost and create an index pattern logstash-* to see the indexed data- 
    kibana index

    kibana discover

Download Source Code

Download it -
Spring Boot Microservice+ ELK stack

Tuesday, 12 February 2019

Spring Boot Microservices + ELK(Elasticsearch, Logstash, and Kibana) Stack Hello World Example

Spring Boot Microservices + ELK(Elasticsearch, Logstash, and Kibana) Stack Hello World Example


In this tutorial we will be using ELK stack along with Spring Boot Microservice for analyzing the generated logs.
The implementation architecture will be as follows- 
Spring Boot microservice elk stack example

What is ELK? Need for it?

The ELK Stack consists of three open-source products - Elasticsearch, Logstash, and Kibana from Elastic.
  • Elasticsearch is a NoSQL database that is based on the Lucene search engine.
  • Logstash is a log pipeline tool that accepts inputs from various sources, executes different transformations, and exports the data to various targets. It is a dynamic data collection pipeline with an extensible plugin ecosystem and strong Elasticsearch synergy
  • Kibana is a visualization UI layer that works on top of Elasticsearch.
These three projects are used together for log analysis in various environments. So Logstash collects and parses logs, Elastic search indexes and store this information while Kibana provides a UI layer that provide actionable insights.
Use Cases-
  • Consider you have a single application running and it produces logs. Now suppose you want analyze the logs generated. One option is to manually analyze them. But suppose these logs are large, then manually analyzing them is not feasible.
  • Suppose we have multiple Application running and all these applications produce logs. If we have to analyze the logs manually we will need to go through all the log files. These may run into hundreds.
We can use ELK here to analyze the logs more efficiently and also using more complex search criterias. It provides log aggregation and efficient searching.
Video
This tutorial is explained in the below Youtube Video.

Lets Begin

We will first download the required stack.
  • Elasticsearch -
    • Download the latest version of elasticsearch from Elasticsearch downloads 
      elasticsearch example
    • Run the elasticsearch.bat using the command prompt. Elasticsearch can then be accessed at localhost:9200 
      elastic start example
  • Kibana -
    • Download the latest version of kibana from Kibana downloads 
      kibana example
    • Modify the kibana.yml to point to the elasticsearch instance. In our case this will be 9200. So uncomment the following line in kibana.yml-
      elasticsearch.url: "http://localhost:9200"
      
    • Run the kibana.bat using the command prompt. kibana UI can then be accessed at localhost:5601 
      start kibana
  • Logstash -
    • Download the latest version of logstash from Logstash downloads 
      logstash example
    • Create a configuration file named logstash.conf. In further section we will be making the changes for this file and starting logstash.
Lets now come to the spring boot part. We will be creating a simple spring boot application, to generate the logs. 
spring boot elasticsearch example
Define the pom.xml as follows-
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.javainuse</groupId>
 <artifactId>spring-boot-elk</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>spring-boot-elk</name>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.6.RELEASE</version>
  <relativePath /> <!-- lookup parent from repository -->
 </parent>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>


</project>

Create the Spring Boot Bootstrap class as follows-
package com.javainuse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloWorldSpringBootApplication {

 public static void main(String[] args) {
  SpringApplication.run(HelloWorldSpringBootApplication.class, args);
 }
}
Next define the controller to expose REST API. We will be making use of these calls to write content to the log file.
package com.javainuse;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
class ELKController {
 private static final Logger LOG = Logger.getLogger(ELKController.class.getName());

 @Autowired
 RestTemplate restTemplete;

 @Bean
 RestTemplate restTemplate() {
  return new RestTemplate();
 }

 @RequestMapping(value = "/elk")
 public String helloWorld() {
  String response = "Welcome to JavaInUse" + new Date();
  LOG.log(Level.INFO, response);

  return response;
 }

 @RequestMapping(value = "/exception")
 public String exception() {
  String response = "";
  try {
   throw new Exception("Exception has occured....");
  } catch (Exception e) {
   e.printStackTrace();
   LOG.error(e);

   StringWriter sw = new StringWriter();
   PrintWriter pw = new PrintWriter(sw);
   e.printStackTrace(pw);
   String stackTrace = sw.toString();
   LOG.error("Exception - " + stackTrace);
   response = stackTrace;
  }

  return response;
 }
}

Finally specify the name and location of the log file to be created in the application.properties file.
logging.file=C:/elk/spring-boot-elk.log
Next we will configure the logstash pipeline- 
Logstash Pipeline
This is done using the logstash.conf-
input {
  file {
    type => "java"
    path => "C:/elk/spring-boot-elk.log"
    codec => multiline {
      pattern => "^%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}.*"
      negate => "true"
      what => "previous"
    }
  }
}
 
filter {
  #If log line contains tab character followed by 'at' then we will tag that entry as stacktrace
  if [message] =~ "\tat" {
    grok {
      match => ["message", "^(\tat)"]
      add_tag => ["stacktrace"]
    }
  }
 
}
 
output {
   
  stdout {
    codec => rubydebug
  }
 
  # Sending properly parsed log events to elasticsearch
  elasticsearch {
    hosts => ["localhost:9200"]
  }
}
Start logstash using the command prompt as follows
-
logstas
h -f logstash.conf

start logstash
Start the spring boot application by running the HelloWorldSpringBootApplication as a java application.
Logs will be generated in C:/elk folder.
  • goto localhost:8080/elk 
    spring elk
  • goto localhost:8080/exception 
    spring exception
  • go to kibana UI console- localhost and create an index pattern logstash-* to see the indexed data- 
    kibana index

    kibana discover

Download Source Code

Download it -
Spring Boot Microservice+ ELK stack

Why Spring cloud is required?

Spring Cloud


Previously we developed microservices using Spring Boot. These were all stand alone applications. But suppose we now have to connect the various applications and build a distributed system.
Why Spring cloud is required?
When developing distributed microservices with Spring Boot we face the following issues-
  • Complexity associated with distributed systems-
    This overhead includes network issues, Latency overhead, Bandwidth issues, security issues.
  • Service Discovery-
    Service discovery tools manage how processes and services in a cluster can find and talk to one another. It involves a directory of services, registering services in that directory, and then being able to lookup and connect to services in that directory.
  • Redundancy-
    Redundancy issues in distributed systems.
  • Loadbalancing-
    Load balancing improves the distribution of workloads across multiple computing resources, such as computers, a computer cluster, network links, central processing units, or disk drives.
  • Performance issues-
    Performance issues due to various operational overheads.
  • Deployment complexities-
    Requirement of Devops skills.

Spring Cloud Tutorial

Spring Cloud Tutorials
















40 Latest Interview Questions and Answers on Spring, Spring MVC, and Spring Boot

  40 Latest Interview Questions and Answers on Spring, Spring MVC, and Spring Boot 1. What is Tight Coupling? When a class (ClassA) is depen...