Sunday 29 July 2018

Spring Boot Profiles

Configuring application in an easy way through Spring Boot Profiles


Spring provides @Profile annotation using which we can deal with multiple profiles based of application environment. @Profile is used with @Configuration and spring stereotypes such as @Component, @Service etc. Different profile is created for different environment. We can also create a default profile that will work when there is no active profile.

To add active profile in property file, we need to configure spring.profiles.active=?. This will be included for every active profile. When we add active profile using command line then the active profile added in property file is replaced.

@ActiveProfiles: Spring test framework provides this annotation to use active profile in our test cases.

Properties file can be injected as external configuration to determine the behavior of the application at run time, to enable or disable the features and to provide extra required resources as per the different environment.

We have multiple environment in Application Life Cycle. Few examples are below:

a) development
b) qa
c) production

Spring Boot provides features through which we can specify different environment properties and we can set the active profile for the intended environment.

We can also pass the active profiles through command line which will not needed any change in application source.

$ mvn package

#Dev profile, application-development.properties

java -jar target/spring-boot-profiles-1.0.jar

{"Message":"A User Defined Message from DEVELOPMENT","Version":1.5,"Enable":false}

# set a profile dynamically through command line.

Note:- When we add any active profile in property file then application will start with that active profile and when we will add active profile through command line then in this case active profile configured in property file will be replaced by active profile passed in command line.

java -jar -Dspring.profiles.active=production target/spring-boot-profiles-1.0.jar
or

java -jar -Dspring.profiles.active="prod, test_prod" spring-boot-profiles-1.0.jar -> For multiple profiles

{"Message":"A User Defined Message from PRODUCTION","Version":1.1,"Enable":false}

Set Active Profiles Programmatically like below 

@SpringBootApplication
public class SpringBootProfilesApplication {
    public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringBootProfilesApplication.class);
application.setAdditionalProfiles("dev","test_dev");
application.run(args);
    }

Another way to set active profiles.

SpringApplication application = new SpringApplication(SpringBootProfilesApplication.class);
ConfigurableEnvironment environment = new StandardEnvironment();
environment.setActiveProfiles("dev","qa");
application.setEnvironment(environment);
application.run(args);

Example to set active profiles using Spring Boot.

Open https://start.spring.io/ and create an application with below details

         <groupId>com.gaurav</groupId>
<artifactId>spring-boot-profiles</artifactId>

Select web and devtools dependency and click on Generate Project.



1. pom.xml

<?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.gaurav</groupId>
<artifactId>spring-boot-profiles</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<name>spring-boot-profiles</name>
<description>Demo project for Spring Boot</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>1.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-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

</project>

2. CustomConfiguration.java

package com.gaurav.springbootprofiles;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties("custom")
public class CustomConfiguration {

private boolean enable;
private String propMessage;
private double version;

public boolean isEnable() {
return enable;
}

public void setEnable(boolean enable) {
this.enable = enable;
}

public String getPropMessage() {
return propMessage;
}

public void setPropMessage(String propMessage) {
this.propMessage = propMessage;
}

public double getVersion() {
return version;
}

public void setVersion(double version) {
this.version = version;
}
}

3. SpringRestController.java

package com.gaurav.springbootprofiles;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SpringRestController {
@Autowired
private CustomConfiguration customConfiguration;
@Value("${greeting.propMessage}")
private String greetMessage;

@GetMapping("/greeting")
public String greetingMessage(String name) {
return "Hey "+ name+", " +greetMessage;
}

@GetMapping("/customConfiguration")
public Map<String, Object> dynamicConfiguration() {
Map<String, Object> map = new HashMap<>();
map.put("Message", customConfiguration.getPropMessage());
map.put("Version", customConfiguration.getVersion());
map.put("Enable", customConfiguration.isEnable());
return map;
}
}

4. SpringBootProfilesApplication.java

package com.gaurav.springbootprofiles;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;


@SpringBootApplication
public class SpringBootProfilesApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootProfilesApplication.class, args);
}
@Profile("production")
@Bean
public String productionBean() {
return "production";
}
@Profile("qa")
@Bean
public String qaBean() {
return "qa";
}
@Profile("development")
@Bean
public String developmentBean() {
return "development";
}
}

5. application.properties

server.port=9595
spring.profiles.active=production
app.name=spring-profiles-test

custom.enable: true
custom.propMessage: User Defined Message
custom.version: 2.5

logging.level.org.springframework.web.servlet: DEBUG
greeting.propMessage=A message from property file! Welcome to ${app.name}

6. application-development.properties

greeting.propMessage=A message from property file! Welcome to ${app.name} in DEVELOPMENT
custom.enable: false
custom.propMessage:A User Defined Message from DEVELOPMENT
custom.version: 1.5

7. application-production.properties

logging.level.org.springframework: INFO
greeting.propMessage=A message from property file! Welcome to ${app.name} in PRODUCTION
custom.enable: false
custom.propMessage:A User Defined Message from PRODUCTION
custom.version: 1.1

8. application-qa.properties

logging.level.org.springframework: INFO
greeting.propMessage=A message from property file! Welcome to ${app.name} in QA
custom.enable: false
custom.propMessage:A User Defined Message from QA Environment
custom.version: 1.1

Result:

Use URL:-

http://localhost:9595/greeting?name=gaurav


http://localhost:9595/customConfiguration





Tuesday 17 July 2018

Spring Boot Security using OAuth2 With Password encryption

About OAuth2.0

Question:- What is OAuth2.0 and OAuth?

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service whereas OAuth is simply a secure authorization protocol. It works by delegating user authentication to the service that hosts the user account and authorizing third-party applications to access the user account. OAuth 2 provides authorization flows for web and desktop applications, and mobile devices.


OAuth defines four roles:


  • Resource Owner
  • Client
  • Resource Server
  • Authorization Server




Tokens basically are random strings generated by the authorization server and are issued when the client requests them.

There are 2 types of token being used in OAuth 2.

Access Token: This is the most important because it allows the user data from being accessed by a third-party application. This token is sent by the client as a parameter or as a header in the request to the resource server. It has a limited lifetime, which is defined by the authorization server.

Refresh Token: This token is issued with the access token but it is not sent in each request from the client to the resource server. When access token validity is finished or access token is expired then It could be sent to the authorization server for renewing the access.

Code Example:-

1. Defining the Dependency using Maven

pom.xml

<?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.gaurav</groupId>
    <artifactId>oauth2-security-with-spring-boot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>


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


2. Configuration for Authorization Server

package com.gaurav.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * @author Kumar Gaurav
 *
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfigurationDetails extends AuthorizationServerConfigurerAdapter {

private static final int ACCESS_TOKEN_VALIDITY_SECONDS = 5000;
private static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 50000;
private static final String CLIEN_ID = "gaurav";
private static final String CLIENT_SECRET = "gaurav123";
private static final String GRANT_TYPE_PASSWORD = "password";
private static final String AUTHORIZATION_CODE = "authorization_code";
private static final String REFRESH_TOKEN = "refresh_token";
private static final String IMPLICIT = "implicit";
private static final String SCOPE_READ = "read";
private static final String SCOPE_WRITE = "write";
private static final String TRUST = "trust";
@Autowired
private TokenStore tokenStore;

@Autowired
private AuthenticationManager authenticationManager;

@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {

configurer
.inMemory()
.withClient(CLIEN_ID)
.secret(CLIENT_SECRET)
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT )
.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS);
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.authenticationManager(authenticationManager);
}
}


3. Configuration for Resource Server

package com.gaurav.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;

/**
 * @author Kumar Gaurav
 *
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfigurationDetails extends ResourceServerConfigurerAdapter {

private static final String RESOURCE_ID = "resource_id";

@Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().disable().authorizeRequests().antMatchers("/emps/**").access("hasRole('ADMIN')").and()
.exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}

@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}

}

4. Configuration for Web Security

package com.gaurav.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import javax.annotation.Resource;
/**
 * @author Kumar Gaurav
 *
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigurationDetails extends WebSecurityConfigurerAdapter {

    @Resource(name = "employeeService")
    private UserDetailsService userDetailsService;

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(encoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .anonymous().disable()
                .authorizeRequests()
                .antMatchers("/api-docs/**").permitAll();
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    public BCryptPasswordEncoder encoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

5. REST API for Employee(EmployeeController.java)

package com.gaurav.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.gaurav.model.Employee;
import com.gaurav.service.EmployeeService;
/**
 * @author Kumar Gaurav
 *
 */
@RestController
@RequestMapping("/emps")
public class EmployeeController {

    @Autowired
    private EmployeeService empService;

    @RequestMapping(value="/employee", method = RequestMethod.GET)
    public List<Employee> listUser(){
        return empService.findAll();
    }

    @RequestMapping(value = "/employee", method = RequestMethod.POST)
    public Employee create(@RequestBody Employee user){
        return empService.save(user);
    }

    @RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)
    public String delete(@PathVariable(value = "id") Long id){
        empService.delete(id);
        return "success";
    }

}

6. Service for Employee

package com.gaurav.service;

import java.util.List;

import com.gaurav.model.Employee;
/**
 * @author Kumar Gaurav
 *
 */
public interface EmployeeService {

Employee save(Employee employee);
    List<Employee> findAll();
    void delete(long id);
}

7. Service Implementation for Employees

package com.gaurav.service.impl;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.gaurav.dao.EmployeeDao;
import com.gaurav.model.Employee;
import com.gaurav.service.EmployeeService;

/**
 * @author Kumar Gaurav
 *
 */
@Service(value = "employeeService")
public class EmployeeServiceImpl implements UserDetailsService, EmployeeService {
@Autowired
private EmployeeDao employeeDao;

public List<Employee> findAll() {
List<Employee> list = new ArrayList<>();
employeeDao.findAll().iterator().forEachRemaining(list::add);
return list;
}

@Override
public void delete(long id) {
employeeDao.delete(id);
}

@Override
    public Employee save(Employee emp) {
        return employeeDao.save(emp);
    }
public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
Employee employee = employeeDao.findByUsername(userId);
if(employee == null){
throw new UsernameNotFoundException("Invalid username or password.");
}
return new org.springframework.security.core.userdetails.User(employee.getUsername(), employee.getPassword(), getAuthority());
}
private List<SimpleGrantedAuthority> getAuthority() {
return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
}

8. DAO for Employee

package com.gaurav.dao;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.gaurav.model.Employee;
/**
 * @author Kumar Gaurav
 *
 */
@Repository
public interface EmployeeDao extends CrudRepository<Employee, Long> {
Employee findByUsername(String username);
}

9. Model Class for Employee

package com.gaurav.model;

import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.*;
/**
 * @author Kumar Gaurav
 *
 */
@Entity
public class Employee {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private long id;
    
    @Column
    private String username;
   
    @Column
    @JsonIgnore
    private String password;
    
    @Column
    private String email;
    
    @Column
    private String designation;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getDesignation() {
return designation;
}

public void setDesignation(String designation) {
this.designation = designation;
}
}

10. Spring Boot Initialize Program

package com.gaurav;

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

/**
 * @author Kumar Gaurav
 *
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

11. Property file with DB configuration

application.properties

server.port=9595
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect =org.hibernate.dialect.MySQLDialect
spring.datasource.url=jdbc:mysql://localhost:3306/oauth2
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
security.oauth2.resource.filter-order=3

12. DB.SQL

CREATE TABLE `employee` (
`id` BIGINT (20),
`designation` VARCHAR (765),
`email` VARCHAR (765),
`password` VARCHAR (765),
`username` VARCHAR (765)
); 

INSERT INTO `employee` (`id`, `designation`, `email`, `password`, `username`) VALUES('1','System Analyst','gaurav@gmail.com','$2a$04$HJGJBytFiKq009XsQxxK4e8kKWKOWlm5438F1kfOh9oDDJarRrA92','Gaurav');

INSERT INTO `employee` (`id`, `designation`, `email`, `password`, `username`) VALUES('2','Technical Lead','aaditya1@gmail.com','$2a$04$LGwQg.SGToIO1ocj26kfxOGtu9Tz3jCmQV4.2S5hZgnuZaMEwUC.a','Aaditya');

INSERT INTO `employee` (`id`, `designation`, `email`, `password`, `username`) VALUES('3','Senior Developer','shivam10@gmail.com','$2a$04$i5Jjw.ypcuQR8xNKuFS7/.IQIFdojWw.iiIQ6Cff0QzvOCV.MqfD6','Shivam');

Username
Password
Hash Value(Round 4)
Gaurav
test
$2a$04$HJGJBytFiKq009XsQxxK4e8kKWKOWlm5438F1kfOh9oDDJarRrA92
Aaditya
hello
$2a$04$LGwQg.SGToIO1ocj26kfxOGtu9Tz3jCmQV4.2S5hZgnuZaMEwUC.a
Shivam
welcome
$2a$04$i5Jjw.ypcuQR8xNKuFS7/.IQIFdojWw.iiIQ6Cff0QzvOCV.MqfD6

Executing the Application

On Application.java ->Right Click ->Run As ->Java Application

Using Postman Rest Client we can hit the below URL for getting the access & Refresh token.

http://localhost:9595/oauth/token

Step 1:- In Authorization, First set type = Basic Auth, then in username and password -> pass the client_id and client_secret.


Step -2, Set the POST parameters in Body like below and hit the send button will receive the response like below.



Step-3
Use the access token to get the list of employees which is available in the Database.

URL - http://localhost:9595/emps/employee?access_token=66331215-ab80-4241-acd6-e48971f73b6c






Step-4
Use the refresh token to get the new access token like below, pass the refresh_token and corresponding values received from step 1.

URL - http://localhost:9595/oauth/token



Sunday 15 July 2018

Spring Boot Actuator

How to use Spring Boot Actuator for Management Endpoints


We can say that Spring Boot Actuator is a module or sub project of Spring Boot which provide many production grade services. It provides several management HTTP endpoints like application health, bean details, version details, configurations, logger details, etc.which we can use for interacting and monitoring our applications.

Enabling Spring Boot Actuator

Required Dependency

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

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>


HAL Browser provides a User Interface for viewing the management endpoints.
Below is the URL for HAL Browser UI


In the HAL Browser UI, There are 2 group buttons: GET and NON-

GET. GET is used to navigate to a resource of the collection. 
NON-GET button is used to do a {POST, PUT, DELETE} request on the collection.


pom.xml

<?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.gaurav.boot</groupId>
<artifactId>actuator-hal-browser-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>actuator-hal-browser-demo</name>
<description>Demo project for Spring Boot</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>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

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

ActuatorDemoController.java

package com.gaurav.boot.actuatorhalbrowserdemo;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/rest")
public class ActuatorDemoController {
@GetMapping("/greeting")
public String greetingMessage(@RequestParam String name){
return "Welcome "+name+" in the world of Spring Boot";
}
private static Map<Long, String> employeeMap = new HashMap<Long, String>();
 
@GetMapping(path = "/list/employee")
public String listEmployees() {
  employeeMap.put(new Long(1001), "Gaurav");
  employeeMap.put(new Long(1234), "Aaditya");
  employeeMap.put(new Long(11), "Shivam");
  employeeMap.put(new Long(101), "Kumar");
  
  return employeeMap.toString();
}
}

ActuatorHalBrowserDemoApplication.java

package com.gaurav.boot.actuatorhalbrowserdemo;

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

@SpringBootApplication
public class ActuatorHalBrowserDemoApplication {

public static void main(String[] args) {
SpringApplication.run(ActuatorHalBrowserDemoApplication.class, args);
}
}

App URL for greeting method:- 

http://localhost:8080/rest/greeting?name=Aaditya

Actuator URl - http://localhost:8080/actuator