• 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.

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

Saturday, November 5, 2022

Understanding Spring AOP

Understanding Spring AOP
Photo by Glenn Carstens Peters

What is Spring AOP?

Spring AOP enables Aspect-Oriented Programming in spring applications. It provides the way to dynamically add the cross-cutting concerns(logging, security, transaction management, auditing, i18n etc.) before, after or around the actual logic using simple pluggable configurations. It makes easy to maintain code in the present and future as well. You can add/remove concerns without recompiling complete source code simply by changing configuration files (if you are applying aspects using XML configuration).


What is advice, joinpoint or pointcut?

  • An important term in AOP is advice. It is the action taken by an aspect at a particular join-point. 
  • Joinpoint is a point of execution of the program, such as the execution of a method or the handling of an exception. In Spring AOP, a joinpoint always represents a method execution.
  • Pointcut is a predicate or expression that matches join points.
  • Advice is associated with a pointcut expression and runs at any join point matched by the pointcut.
  • Spring uses the AspectJ pointcut expression language by default.


Pointcut

Pointcut determines the join point of interest and in the code it appears as pointcut expression. It works similarly to regular expressions, using the special syntax it matches methods with advices. Please note, that Spring AOP supports only those classes that are defined as Spring beans/component otherwise they won’t be available. Here is a pointcut expression general syntax (those parts that are in red are mandatory) with some examples:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

The following examples show some common pointcut expressions:

The execution of any public method, First * means that it will match any return type, and *(..) means that the expression will match any method, no matter how much arguments it contains.
    execution(public * *(..))

The execution of any method with a name that begins with set:
    execution(* set*(..))

The execution of any method defined by the OrderService interface/class:
    execution(* com.bhargav.service.AccountService.*(..))

The execution of any method defined in the service package or one of its sub-packages:
    execution(* com.bhargav.service..*.*(..))

This will be matched only for those methods in the DemoClass, which has int as a first parameter, return type as int and method should be public:
    execution(public int DemoClass.*(int, ..))

Any join point (method execution only in Spring AOP) within the service package:
    within(com.bhargav.service.*)

Advices

Spring AOP includes the following types of advice:

@Before: 
Advice that runs before a join point but that does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception).

@After: 
Advice to be run regardless of the means by which a join point exits (normal or exceptional return).

@AfterReturning: 
Advice to be run after a join point completes normally (for example, if a method returns without throwing an exception).

@AfterThrowing: 
Advice to be run if a method exits by throwing an exception.

@Around:
Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. Around advice can perform custom behaviour before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception.


References:

Friday, May 7, 2021

Working With ThreadPoolTaskExecutor of Spring


Working With ThreadPoolTaskExecutor of Spring
Photo Courtesy Unsplash

ThreadPoolTaskExecutor is a java bean that allows for configuring a ThreadPoolExecutor in a bean style by setting up the values for the instance variables like corePoolSize, maxPoolSize, keepAliveSeconds, queueCapacity and exposing it as a Spring TaskExecutor.

One of the added Advantage of using ThreadPoolTaskExecutor of Spring is that it is well suited for management and monitoring via JMX.

The default configuration of core pool size is 1, max pool size and queue capacity as 2147483647.

This is roughly equivalent to Executors.newSingleThreadExecutor(), sharing a single thread for all tasks. And setting queueCapacity to 0 mimics Executors.newCachedThreadPool(), with immediate scaling of threads in the pool to a very high number.

If you are using XML file for configuring the bean, you can setup the ThreadPoolTaskExecutor like below:

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
   <property name="corePoolSize" value="5" />
   <property name="maxPoolSize" value="10" />
   <property name="WaitForTasksToCompleteOnShutdown" value="true" />
</bean>

If you are using Java Annotation to define the bean, you can setup like below:

@Bean
public TaskExecutor threadPoolTaskExecutor() {
   ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
   executor.setCorePoolSize(5);
   executor.setMaxPoolSize(10);
   executor.initialize();
   return executor;
}

CorePoolSize

Is the minimum number of threads that remain active at any given point of time. If you don’t provide a value explicitly then it will have default value as 1. The TaskExecutor delegates the value to the underlying class ThreadPoolExecutor.

MaxPoolSize

Is the maximum number of threads that can be created. The TaskExecutor delegates the value to the underlying ThreadPoolExecutor. The maxPoolSize relies on queueCapacity because ThreadPoolTaskExecutor creates a new thread only if the number of items in the queue exceeds queue capacity.

Let’s test out the theory with some code so that it will be more clear for all of us. Here is a code snippet that will create new thread from TaskExecutor.

@Bean
public TaskExecutor threadPoolTaskExecutor() {
   ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
   executor.setCorePoolSize(5);public void createTasks(ThreadPoolTaskExecutor taskExecutor, int numTasks) {

    for (int i=0; i<numTasks; i++) {
       taskExecutor.execute(() -> {
       try {
          long sleepTime = ThreadLocalRandom.current().nextLong(1, 10) * 100;
          Thread.sleep(sleepTime);
       } 
       catch (InterruptedException e) {
          Thread.currentThread().interrupt();
       }
       });
   }
}

Now let’s create a main method where we can try out various use cases by setting values to the ThreadPoolTaskExecutor.

public static void main(String[] args) {
    // Creating ThreadPoolTaskExecutor
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.afterPropertiesSet();

    // Creating Tasks within ThreadPoolTaskExecutor
    createTasks(taskExecutor, 6);

    // Getting PoolSize
    System.out.println("Properties " +
        "- corePoolSize: " + taskExecutor.getCorePoolSize() +
        ", maxPoolSize: " + taskExecutor.getMaxPoolSize() +
        ", poolSize: " + taskExecutor.getPoolSize() +
        ", activeCount: " + taskExecutor.getActiveCount());

    // Shutting Down ThreadPoolTaskExecutor
    taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
    taskExecutor.shutdown();
}

If execute the above code snippet, you will the below output on the console. You can see that corePoolSize is 1 by default and maxPoolSize is 2147483647. Since the QueueCapacity is also 2147483647, you will see that it will make use of the one thread to process all 6 tasks.

17:37:21.696 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Initializing ExecutorService

Properties - corePoolSize: 1, maxPoolSize: 2147483647, poolSize: 1, activeCount: 1

17:37:21.747 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Shutting down ExecutorService

Let’s modify our code to setup some of the parameters so that we can see whether it will have any behavioural change in the TaskExecutor.

ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(1);
taskExecutor.setMaxPoolSize(4);
taskExecutor.afterPropertiesSet();

You will still observe that the TaskExecutor will still make use of one thread only though the max pool size is set to 4.

17:42:43.396 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Initializing ExecutorService

Properties - corePoolSize: 1, maxPoolSize: 4, poolSize: 1, activeCount: 0

17:42:43.447 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Shutting down ExecutorService

Let’s modify our code to setup queue capacity parameter so we see the behavioural change in the TaskExecutor.

ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(1);
taskExecutor.setMaxPoolSize(4);
taskExecutor.setQueueCapacity(2);
taskExecutor.afterPropertiesSet();

Now when you run the same piece of code, you will see that the pool size increases but it will not exceed max pool size.

17:47:29.986 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Initializing ExecutorService

Properties - corePoolSize: 1, maxPoolSize: 4, poolSize: 4, activeCount: 4

17:47:30.036 [main] INFO org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Shutting down ExecutorService

TaskExecutor creates a new thread only if the number of items in the queue exceeds queue capacity. As a result, you will observe that pool size increases.

To conclude, it’s always a good practice to define the core pool size, max pool size and queue capacity for the TaskExecutor explicitly from our end instead of leaving it to use the default values.

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.


Featured Post

Your AI Sidekick: How Claude took over Pritee’s Repetitive tasks

  It was a classic Wednesday morning in our Bengaluru office . Pritee, one of our sharpest Project Managers, had just stepped out of a stake...