• About Blog

    What's Blog?

    A blog is a discussion or informational website published on the World Wide Web consisting of discrete, often informal diary-style text entries or posts.

  • About Cauvery Calling

    Cauvery Calling. Action Now!

    Cauvery Calling is a first of its kind campaign, setting the standard for how India’s rivers – the country’s lifelines – can be revitalized.

  • About Quinbay Publications

    Quinbay Publication

    We follow our passion for digital innovation. Our high performing team comprising of talented and committed engineers are building the future of business tech.

Tuesday, April 20, 2021

Spring Boot Admin Server - Helps to Monitor Spring Boot Applications via Vue JS UI

 

Spring Boot Admin Server
Image Source: Sprint Boot Admin - Community Project

If you are in a micro services architecture, you will have lot of services and monitoring all of them by using Spring Boot Actuator Endpoint is quite difficult.

The CodeCentric Team provides a Spring Boot Admin Server UI to manage and monitor all your Spring Boot application Actuator endpoints at one place.

The applications register with Admin Server using Spring Boot Admin Client (via HTTP) or are discovered using Spring Cloud (e.g. Eureka, Consul). The Spring Boot Admin UI is a Vue JS application on top of the Spring Boot Actuator endpoints.

Let’s create a spring boot application which acts as a admin server. We will re-use one of the existing project as client, which registers with the admin server and we should be able to see all the information of the client on admin user interface.

Building a Spring Boot Admin Application

Let’s use the spring initializr to generate a spring boot application. Unzip the downloaded project and import it to your IDE.

For building a Spring Boot Admin Server, we need the below dependencies in the build configuration file.

<dependency>
   <groupId>de.codecentric</groupId>
   <artifactId>spring-boot-admin-server</artifactId>
   <version>2.3.1</version>
</dependency>
<dependency>
   <groupId>de.codecentric</groupId>
   <artifactId>spring-boot-admin-server-ui</artifactId>
   <version>2.3.1</version>
</dependency>

Next step is to add the EnableAdminServer annotation in your main Spring Boot application class file. This annotation is used to tell spring boot to make our application as Admin Server to monitor all other micro services.

@EnableAdminServer
@SpringBootApplication
public class AdminConsoleApplication {

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

}

Let’s define some of the server properties in application.properties

# Admin Server Properties
spring.application.name=admin-console
server.servlet.context-path=/
server.port=9090

We are almost ready with Spring Boot Admin service, let’s build and deploy the application. Once the application comes up, type in the URL http://localhost:9090/ on the web browser to access the Spring Boot Admin Server UI.

Sprint Boot Admin Dashboard

Now that we have admin server ready, let’s deploy another spring boot application so that we can monitor and manage it. I am taking an existing project rest-producer application for the exercise.

First, add the following dependencies in the build configuration file.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
   <groupId>de.codecentric</groupId>
   <artifactId>spring-boot-admin-starter-client</artifactId>
   <version>2.3.1</version>
</dependency>

Let’s configure the admin server URL and enable the actuator end points in application.properties.

# Admin Server URL
spring.boot.admin.client.url=http://localhost:9090
# Actuator Properties
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

Now build and deploy the rest-producer application. Once the application, comes up go back to the Admin Server UI and refresh the page. You should be able to see hystrix-rest-producer service registered and visible in admin server. Click on the service name, to get complete details of the service.

Sprint Boot Admin Dashboard

The Spring Boot Admin Server provides the following features for any registered applications:
  • Show Health Status
  • Show details like JVM & Memory, Datasource, Cache Metrics etc.
  • Show build-info number
  • Follow and Download Log file
  • View JVM System & Environmental properties
  • Easy Log Level Management
  • View thread dump, http-traces, audit events, http-endpoints etc.
  • View and Delete Active Sessions (using spring-session)
  • View Flyway / Liquibase Database Migrations
  • Download Heap Dump
  • Event Journal of Status Changes

Please note, the Spring Boot Admin Server has access to the application’s sensitive endpoints, so it’s recommended to add security configurations to both admin and client services. Enable the Spring Security, so that only with valid credentials the admin UI can be accessed and the client services can register with admin service with it.

As usual, the source code for the above spring boot admin server is available over on GitHub.


Thursday, April 8, 2021

Internationalization of Web Application using Spring Boot

Internationalization Globe Image

Internationalization (i18n) is the process of designing and preparing the application to be usable in different locales around the world. Localization (l10n) is the process of building versions of your app for different locales, including extracting text for translation into different languages, and formatting data for particular locales.

A locale identifies a region (such as a country) in which people speak a particular language or language variant. The locale determines the formatting and parsing of dates, times, numbers, and currencies as well as measurement units and the translated names for time zones, languages, and countries.


Building a SpringBoot Application for i18n

Let’s use the spring initializr to generate a spring boot application with dependency of spring web module. Unzip the downloaded project and import it to your IDE.

The end goal of this application is to create a web page that displays a welcome message for the user “Welcome to SpringBoot Internationalization!” on the home page. And user will be presented with an option to switch the locale or language of his/her choice. 


Resource Bundles

For an application to support internationalization (i18n), it requires the capability of resolving text messages for different locales. Spring’s application context is able to resolve text messages for a target locale by their keys.

Typically, the messages for each locale should be stored in separate properties file. This properties file is called a resource bundle, they should be added in resources folder of the spring boot application.

If we are supporting multiple locales then we will have multiple resource bundles so we need to follow a naming convention so that it’s easy for spring to lookup the values as well as easy for us to maintain it.

For example, messages_en.properties / messages_fr.properties. As you can see from the name itself we can make out first one is for English and next on is for French.


Message Source

MessageSource is an interface that defines several methods for resolving messages. The ApplicationContext interface extends this interface so that all application contexts are able to resolve text messages.

An application context delegates the message resolution to a bean with the exact name messageSource. ResourceBundleMessageSource is the most common MessageSource implementation that resolves messages from resource bundles for different locales.

Here is the bean declaration for ResourceBundleMessageSource for our application.

@Bean
public ResourceBundleMessageSource messageSource() {
   ResourceBundleMessageSource source = 
         new ResourceBundleMessageSource();
   source.setDefaultEncoding("UTF-8");
   source.setBasename("messages");
   source.setCacheSeconds(600);
   return source;
}


Application Properties

Let’s add some of the important configurations related to the resource bundle message source into the application.properties file.

I have added an explanation for each of the configuration which is easy to understand, hence am not going to details.

# Whether to always apply the MessageFormat rules, parsing even messages without arguments.

spring.messages.always-use-message-format=false

# Whether to fall back to the system default Locale, if no files for a specific Locale have been found.

spring.messages.fallback-to-system-locale=true

# Whether to use the message code as the default message instead of throwing a "NoSuchMessageException". Recommended during development only.

spring.messages.use-code-as-default-message=false


Interceptor

Next, we will add an interceptor to intercept the request and identify whether user has requested a locale change or not. It will come handy when user want to change the language of the application explicitly.

@Bean
public LocaleResolver localeResolver() {
    return new SessionLocaleResolver();
}

@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
    return new LocaleChangeInterceptor();
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
}

The LocalChangeInterceptor looks for a request parameter name locale by default. If you are not interested to use that parameter, you can override it by giving your own parameter name.

We will add a controller that returns a web page as a response by adding the required keys into the model so that it can be access in the html page.

@Controller
public class DefaultController {
    @Autowired
    private MessageSource messageSource;
    @GetMapping("/")
    public ModelAndView getIndex(
            Map<String, Object> model, Locale locale) {
        model.put("greetMessage", messageSource
                .getMessage("welcomeText", null, locale));
        model.put("languageSupported", messageSource
                .getMessage("languageSupport", null, locale));
        return new ModelAndView("index", model);
    }
}

If you see am trying to read two keys from the messageSource, one is welcomeText and another one is languageSupport. We need to make sure whatever locales we are going to support, it has these two keys in respective locale resource bundle.

messages_en.properties
welcomeText=Welcome to SpringBoot Internationalization!
languageSupport=Language Options

messages_kn.properties
welcomeText=ಸ್ಪ್ರಿಂಗ್‌ಬೂಟ್ ಅಂತರರಾಷ್ಟ್ರೀಕರಣಕ್ಕೆ ಸುಸ್ವಾಗತ!
languageSupport=ಭಾಷಾ ಆಯ್ಕೆಗಳು

messages_fr.properties
welcomeText=Bienvenue dans SpringBoot Internationalization!
languageSupport=Options de langue

Last but not the least is to create a html page which can display the welcome message as well as provides an option to switch the locale or language.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Springboot Internationalization Demo</title>
</head>
<body>
<h1>{{greetMessage}}</h1>
<br/>
<b>{{languageSupported}}:</b>
<a href="/?locale=en">English</a>&nbsp;|&nbsp;
<a href="/?locale=hi">Hindi</a>&nbsp;|&nbsp;
<a href="/?locale=kn">Kannada</a>&nbsp;|&nbsp;
<a href="/?locale=te">Telugu</a>&nbsp;|&nbsp;
<a href="/?locale=ta">Tamil</a>&nbsp;|&nbsp;
<a href="/?locale=ar">Arabic</a>&nbsp;|&nbsp;
<a href="/?locale=zh">Chinese</a>&nbsp;|&nbsp;
<a href="/?locale=fr">French</a>&nbsp;|&nbsp;
<a href="/?locale=in">Indonesia</a>
</body>
</html>

In the above html code you can see the place holders {{greetMessage}} and {{languageSupported}}, they will be replaced with the actual messages based on the locale.

The languages supported can be returned as a list from the controller and we can loop through it and render them but for now am skipping it and hard-coding the languages supported.

Now if we compile the code and deploy our springboot application, we should be able to see the output on the web browser.

Open the browser and type in the URL — http://localhost:8181/

Internationalization English Image

Now if the user clicks on any other language options, the page should change to that specific locale or language. Let’s say I click on Kannada language, then the same web page will be rendered in that language.

Internationalization Kannada Image

Using the cURL command, you can make the request and get the response.

$ curl -X GET -H 'Accept-Language: fr' 'http://localhost:8181/'
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>Springboot Internationalization Demo</title>
</head><body><h1>Bienvenue dans SpringBoot Internationalization!</h1>
<br/><b>Options de langue:</b>
<a href="/?locale=en">English</a>&nbsp;|&nbsp;
<a href="/?locale=hi">Hindi</a>&nbsp;|&nbsp;
<a href="/?locale=kn">Kannada</a>&nbsp;|&nbsp;
<a href="/?locale=te">Telugu</a>&nbsp;|&nbsp;
<a href="/?locale=ta">Tamil</a>&nbsp;|&nbsp;
<a href="/?locale=ar">Arabic</a>&nbsp;|&nbsp;
<a href="/?locale=zh">Chinese</a>&nbsp;|&nbsp;
<a href="/?locale=fr">French</a>&nbsp;|&nbsp;
<a href="/?locale=in">Indonesia</a></body>
</html>

With Localization (l10n), we should be able to manage other customization like date and time format, currency, number formatting as these things varies from locale to locale.

As usual, the source code for the above spring boot implementation is available over on GitHub.

Featured Post

Benefits & Best Practices of Code Review

Photo by Bochelly Code reviews are methodical assessments of code designed to identify bugs, increase code quality, and help developers lear...