Advertisement

Sri Lanka's First and Only Platform for Luxury Houses and Apartment for Sale, Rent

Tuesday, June 15, 2021

Java 16 Features


Java is nearing its next Long Term Support (LTS) Release which is Java 17. Thus far it has released Java 16 General Availability (GA) Release which can be used in Production. There are some new features available in Java 16 which we are going to look at right now.

Record 

Record is simplified way to declare a class which is used only to represent data. This type of classes are defined as Data Transfer Objects (DTO) or Entities in ORM frameworks to represent Tables. The current way to declare this type of classes is to create a public class with properties and all argument constructor and define all getters/setters along with equals, hashCode and toString. This requires a lot of additional code which can be reduced using code generation libraries and plugins like Lombok yet it is still an hassle. 

Java 16 introduces record type to ease creation of such classes. 

 import java.util.*;  
 public class RecordTest {  
      public static void main(String... args) {  
           Student s1 = new Student(1, "Shazin", 1);  
           Student s2 = new Student(2, "Shahim", 2);  
           System.out.println("Student 1 : "+s1);  
           System.out.println("Student 2 : "+s2);  
           System.out.println("s1 == s2 : "+(s1 == s2));  
           System.out.println("s1.equals(s1) : "+(s1.equals(s1)));  
           System.out.println("s1.equals(s2) : "+(s1.equals(s2)));  
           record GraduateStudent(Student student, List<String> qualifications) {};  
           GraduateStudent gs1 = new GraduateStudent(s1, Arrays.asList("A/S", "BSc"));  
           System.out.println("GraduateStudent 1 : " + gs1);  
      }  
      private static record Student(Integer id, String name, Integer grade) {  
           public Student {  // All args constructor 
                if (grade < 0 || grade > 13) {  
                     throw new IllegalArgumentException("Grade must be between 1 and 13");  
                }  
           }  
      }  
 }  
The above example shows the use a Record in Java 16. The record Student is defined below as a static variable with attributes id, name and grade. The getters/setters with equals, hashCode and toString will be generated by default for this.

Once instantiated the a record object acts as a regular object. The only difference is that generated accessors/modifiers don't follow Java Beans convention (getter for name is name() not getName()) thus not a drop in replacement for Java Beans. Due to this reason record types are not yet supported by JSON Serializers and ORM frameworks but its a work in progress.

New methods in Stream interface

There are several new methods introduced in Stream interface which can be used to increase performance and reduce boilerplate code. One is the Stream.toList() method.

           List<Integer> evenNos = nos.stream().filter(i -> i % 2 == 0).toList(); //.collect(Collectors.toList())  
           System.out.println("Even numbers : "+evenNos);  
This method reduces the need to call collect method when there is need to aggregate a Stream values to a List.

Also there is a new method introduced which is Stream.mapMulti() which is a more imperative implementation of Stream.flatMap(). The practical use of this is a bit complex but this article by Nicolai Parlog explains it well. I suggest you read it.

Pattern Matching

Pattern Matching is a very useful addition to Java 16 which eliminates the need of casting after the use of instanceof operator.

 import java.util.*;  
 public class PatternMatchingTest {  
      public static void main(String... args) {  
           String name = "Shazin";  
           List<Integer> nos = Arrays.asList(1, 2, 3, 4, 5);  
           Map map = Collections.singletonMap("Key", "Value");  
           Long bigInt = 1l;  
           System.out.println("Name Length : " + length(name));  
           System.out.println("Nos Length : " + length(nos));  
           System.out.println("Map Length : " + length(map));  
           System.out.println("bigInt Length : " + length(bigInt));  
      }  
      private static int length(Object o) {  
           if (o instanceof String s) { // s variable of type String  
                return s.length();  
           } else if (o instanceof Collection c) { // c variable of type Collection  
                return c.size();  
           } else if (o instanceof Map m) { // m variable of type Map  
                return m.size();  
           } else { // o variable of type Object  
                return 0;  
           }  
      }  
 }  
This feature allows to use a local scoped variable name right after the use of instanceof operator which matches the type used and can be used without casting. This eliminates a lot of boilerplate code.


Sunday, April 18, 2021

Writing Cloud Native Spring Applications with Docker, GraalVM and Spring Native

Cloud Computing has taken the IT world by storm because of its versatility, low initial capital required to get started and low operational costs. Many new programming languages/platforms such as Go, Node JS, etc. have been tailormade to work on Cloud nodes 

But many Enterprise level Software applications still run on Java and have failed to harness full capabilities of the Cloud due to its high memory footprint and high latency due to its Just in Time (JIT) compilation. These contribute to slower start up times and cold starts.

In order to tackle problems Oracle Labs Team introduced a VM called GraalVM which enabled language agnostic method to produce Cloud Native applications using Java (not only Java) along with capabilities to integrate Spring as well.

In order to harness the capabilities of GraalVM and easy development Spring introduced a developer tool named Spring Native which enables to convert most of the Spring Applications to Docker Container Images with GraalVM image as base which converts the Spring Application to a Native application runs it.

This enables faster startup time, low latency and low memory usage. GraalVM achieves this by using its Ahead of Time (AOT) compilation and building capabilities. 

You can use this developer tool directly from Spring Initializr as below;


Using this tool will add a new plugin and a Spring Native dependency to the maven pom.xml of the Spring Application. This plugin is available for Gradle as well if you fancy that.

If you have a Simple Spring Application like below;
@SpringBootApplication
@RestController
@RequestMapping("/native")
public class SpringNativeDemoApplication {

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

@PostConstruct
public void init() {
System.out.println("Initialized...");
}

@GetMapping("/greet")
public String greet() {
return "Hello";
}


}
Which has an endpoint /native/greet you will see the dependency in the pom.xml following;

<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency>

And plugin under plugins;
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
You can build the Docker container using the following command;

./mvnw spring-boot:build-image

This will generate the native image with ahead of time compilation. The generated executable will have all the necessary classes and statically linked native code from the SDK. Substrate VM which is a docker image provided by GraalVM is used here as the base of the image.

 
 After a long build process which is one of the downsides of this approach for the time being. Following command be used to list down the newly built image in Docker.

./docker images | grep spring-native-demo

Then the image can be run using the following command to be listening at port 8088.

./docker run -p 8088:8080 spring-native-demo:0.0.1-SNAPSHOT

This will start up the Spring Application very quickly due to the Ahead of Time compilation capability of GraalVM. 

You can hit the endpoint using following command or by visiting the url in a browser;

curl localhost:8088/native/greet --silent

As of now not all Spring Eco System modules are supported in Spring Native. But it is a work in progress.

There are numerous samples provided by Spring Team on how to use Spring Native in with other Spring Modules. 

More details can be found at Spring Native documentation. You can find the Source code at Github.



 

 

Friday, November 20, 2020

Spring Data Elasticsearch GeoPoint Field in Index

Recently I was working on a Project which involved Spring Data Elasticsearch and needed to use geo_point type field in the Elasticsearch index for speedier location based searches. Spring Data Elasticsearch provides a data type by the name GeoPoint to achieve this and an annotation named @GeoPointField to mark such fields.

@Document(indexName = "properties", replicas = 0, refreshInterval = "-1")
public class Property implements Serializable {

...
@GeoPointField
private GeoPoint location;
...

 

But sadly for me creating a repository out for the above @Document and saving objects was keep on converting the GeoPoint field to a plain map of latitude and longitude but not as a geo_point field. 

    "location": {
      "properties": {
        "latitude": {
          "type": "string"
         },
        "longitude": {
          "type": "string"
        }
      }
    } 

This results in following error while querying using Geo Distance Query. 

QueryParsingException failed to find geo_point field

After some research I finally found out that in such cases we would need to manually create the index before calling Repository.save.

In a service or any other initializer class you need to do the following;

@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;

@PostConstruct
public void init() {
IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Property.class);
indexOperations.putMapping(indexOperations.createMapping());
indexOperations.refresh();
}

 This fixes the issue and creates the location field with type geo_point as expected.

Sunday, March 22, 2020

Corona Meter

Corona Meter



Corona (Covid19) has taken over the world and it also has made its way to my home country Sri Lanka. We are in a curfew till Tuesday (24/03/2020) and it is expected to extended. Our security forces, medical staff are doing there best but as of writing this the no of cases reported hasn't stopped completely and also it hasn't blown out of control either. So we can say we are safe for now as long as we maintain social distancing and good personal hygiene.



In a time like this, it is particularly important to keep track of the Corona virus outbreak situation. So to ease thing I made a small DIY project which uses an API provided by the official Sri Lankan Health Promotion Bureau to show vital statistics. This is a need of the hour as it makes easy for myself and my wife to keep track of things easily. This is a self contained IOT project which only requires a power source or battery which can input 5v. It will connect to WiFi router and pull data. It can be easily modified to pull and display any country's data with minor modifications so it will be useful for many.

More information on how this was developed can be found at https://github.com/shazin/corona-meter

Tuesday, October 30, 2018

Spring Security Authentication

Spring Security Authentication

Security is one of the most vital concerns for any organization. In this article, you will learn about authentication and how to integrate them easily with the Spring MVC application.

Authentication

One of the fundamental ways to secure a resource is to make sure that the caller is who they claim to be. This process of checking credentials and making sure that they are genuine is called authentication.
This article will delve into the technical capabilities of Spring Security, specifically authentication. To find the complete code for this article, go to https://github.com/PacktPublishing/Hands-On-Spring-Security-5-for-Reactive-Applications/tree/master/Chapter02.
The following diagram shows the fundamental process Spring Security uses to address this core security requirement. The figure is generic and can be used to explain all the various authentication methods that the framework supports:


Authentication architecture

Spring Security has a series of servlet filters (a filter chain). When a request reaches the server, it is intercepted by this series of filters (Step 1 in the preceding diagram).In the reactive world (with the new Spring WebFlux web application framework), filters are written quite differently fromtraditional filters (such as those used in the Spring MVC web application framework). Having said that, the fundamental mechanism remains the same for both.
The Servlet filter code execution in the filter chain keeps skipping until the right filter is reached. Once it reaches the right authentication filter based on the authentication mechanism used, it extracts the supplied credentials (most commonly a username and password) from the caller.
Using the supplied values (here, you have a username and password), the filter(UsernamePasswordAuthenticationFilter) creates an Authentication object (in the preceding diagram, UsernamePasswordAuthenticationToken is created withthe username and password supplied in Step 2). The Authentication object created in Step 2 is then used to call the authenticate method in the AuthenticationManager interface:
public interface AuthenticationManager {

    Authentication authenticate(Authentication authentication)

    throwsAuthenticationException;

}
The actual implementation is provided by ProviderManager, which has a list of configured AuthenticationProvider.
public interface AuthenticationProvider {

    Authentication authenticate(Authentication authentication)

    throwsAuthenticationException;

    boolean supports(Class authentication);

}
The request passes through various providers and, in due course, tries to authenticate the request. There are a number of AuthenticationProvider interfaces as part of Spring Security.
In the diagram above, AuthenticationProvider requires user details (some providers require this, but some don't), which are provided in UserDetailsService:
public interface UserDetailsService {

    UserDetailsloadUserByUsername(String username) throws UsernameNotFoundException;

}
UserDetailsService retrieves UserDetails (and implements the User interface) using the supplied username.
If all goes well, Spring Security creates a fully populated Authentication object (authenticate: true, granted authority list, and username), which will contain various necessary details. The Authentication object is stored in the SecurityContext object by the filter for future use.
The authenticate method in AuthenticationManager can return the following:
  • An Authentication object with authenticated=true, if Spring Security can validate the supplied usercredentials
  • An AuthenticationException, if Spring Security finds that the supplied user credentials are invalid
  • null, if Spring Security cannot decide whether it is true or false (confused state)

Setting up AuthenticationManager

There are a number of built-in AuthenticationManager in Spring Security that can be easily used in your application. Spring Security also has a number of helper classes, using which you can set up AuthenticationManager. One helper class is AuthenticationManagerBuilder.
Using this class, it’s quite easy to set up UserDetailsService against a database, in memory, in LDAP, and so on. If the need arises, you could also have your own custom UserDetailsService (maybe a custom single sign-on solution is already there in your organization).
You can make an AuthenticationManager global, so it will be accessible by your entire application. It will be available for method security and other WebSecurityConfigurerAdapter instances.
WebSecurityConfigurerAdapter is a class that is extended by your Spring configuration file, making it quite easy to bring Spring Security into your Spring application. This is how you set up a global AuthenticationManager using the @Autowired annotation:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void confGlobalAuthManager(AuthenticationManagerBuilderauth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password("admin@password")
            .roles("ROLE_ADMIN");

    }

}
You can also create local AuthenticationManager, which is only available for this particular WebSecurityConfigurerAdapter, by overriding the configure method, as shown in the following code:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilderauth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password("admin@password")
            .roles("ROLE_ADMIN");

    }

}
Another option is to expose the AuthenticationManager bean by overriding the authenticationManagerBean method:
@Override
publicAuthenticationManagerauthenticationManagerBean() throws Exception {

    returnsuper.authenticationManagerBean();

}
You can also expose various AuthenticationManager, AuthenticationProvider, or UserDetailsService as beans, which will override the default ones.
The preceding code example has used AuthenticationManagerBuilder to configure in-memory authentication.

AuthenticationProvider

AuthenticationProvider provides a mechanism for getting the user details with which authentication can be performed. Spring Security provides a number of AuthenticationProvider implementations, as shown in the following diagram:


Spring Security built-in AuthenticationProvider

Custom AuthenticationProvider

You can also write a custom AuthenticationProvider by implementing the AuthenticationProvider interface. You have to implement two methods, namely authenticate (Authentication) and supports(ClassaClass):
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException 
    {

        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        if ("user".equals(username) && "password".equals(password)) {
            return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList());
        } else {
            throw new BadCredentialsException("Authentication failed");
        }

    }

    @Override
    publicboolean supports(ClassaClass) {
         returna Class.equals(UsernamePasswordAuthenticationToken.class);

    }

}

Your authenticate method is quite simple. Compare the username and password with a static value. You can write any logic here and authenticate the user. If there is an error, it throws an exception, AuthenticationException.
On the GitHub page, navigate to the jetty-in-memory-basic-custom-authentication project to see the full source code of this class.

Multiple AuthenticationProvider

Spring Security allows you to declare multiple AuthenticationProvider in your application. They are executedaccording to the order in which they are declared in the configuration.
The jetty-in-memory-basic-custom-authentication project is modified further, and you have used the newly created CustomAuthenticationProvider as an AuthenticationProvider (Order 1) and the existing inMemoryAuthentication as your second AuthenticationProvider (Order 2):
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomAuthenticationProvider.class)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomAuthenticationProvider customAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers("/**")
            .authenticated(); // Use Basic authentication

    }

    @Override
    protected void configure(AuthenticationManagerBuilderauth) throws Exception {
        // Custom authentication provider - Order 1
        auth.authenticationProvider(customAuthenticationProvider);

        // Built-in authentication provider - Order 2
        auth.inMemoryAuthentication()
            .withUser("admin")
            .password("{noop}admin@password")

        //{noop} makes sure that the password encoder doesn't do anything
            .roles("ADMIN") // Role of the user
            .and()
            .withUser("user")
            .password("{noop}user@password")
            .credentialsExpired(true)
            .accountExpired(true)
            .accountLocked(true)
            .roles("USER");

    }

}
Whenever the authenticate method executes without error, the controls return, and, thereafter, the configured AuthenticationProvider doesn't get executed.

If you found this article interesting, you can explore Hands-On Spring Security 5 for Reactive Applications to secure your Java applications by integrating the Spring Security framework in your code. Hands-On Spring Security 5 for Reactive Applications
will guide you in integrating add-ons that will add value to any Spring Security module.

Sunday, February 18, 2018

Using ThingsBoard, MQTT, Arduino to Monitor Plant Soil Moisture, Temperature and Humidity - Part 1

Problem

Recently I got a rose plant from one of my friends who got married. I have been having plants of all sorts at my home but as any busy guy I forget to water the plants. This is a problem I thought I need to address using technology.

Solution

After doing some research I got to know about a Platform called ThingsBoard which allows Devices to connect to a central server using HTTP, MQTT, CoAP protocols and send telemetry to visualize everything in a Dashboard. I quickly downloaded it, used my Ethernet Shield, DHT11 sensor and YL-69 Soil Moisture sensor which I had lying around to check the possibility of integrating everything together.


Implementation

I just connected YL-69 Soil Moisture sensor to Arduno Analog Pin A1 to read the sensor data and Digital Pin 7 to power it if and when required. I connected Digital Pin 6 to read the sensor data from DHT11 sensor. Finally I followed the ThingsBoard Installation guide [1] and Getting Started guide [2] to setup ThingsBoard server in my laptop.

Finally wrote the following Arduino Sketch to use Ethernet Shield to connect to the network and ThingsBoard via MQTT protocol to send data.

Arduino sketch can be found below;


Data was sent in following format.
{"temperature":29.00, "humidity":30.00, "moisture":10, "active": false}

And was visualized in Dashboard Widgets like below;



You can see a Demo below where the Blue Color Soil Moisture sensor reading go up and down based on inserting and removal of the YL-69 sensor probe and Temperature and Humidity going up when I exhale hot air into the DHT11 sensor.





Future Work

Future work would be to add ESP8266 wireless connectivity to the entire thing and using ThingsBoard rule to fire and send an email when soil moisture level goes down below a threshold.

References


  1. https://thingsboard.io/docs/user-guide/install/windows/
  2. https://thingsboard.io/docs/getting-started-guides/helloworld/
  3. https://create.arduino.cc/projecthub/nekhbet/using-the-yl-39-yl-69-soil-humidity-sensor-with-arduino-968268
  4. https://playground.arduino.cc/Main/DHT11Lib
  5. https://www.techtalks.lk/blog/2018/2/thingsboard-mqtt-arduino-part-1

Tuesday, January 30, 2018

Git Commit Information in Spring MVC

At time there is a need for developers the need to know which Git Commit from which Git Branch was used to build a release so that they can keep track of the versions.
Spring Boot Actuator is tailor made for this if you are working on Spring Boot but if you are like me and not using Spring Boot for a specific project but only using Spring MVC then this guide will be helpful for you.
First of all you need to add the spring-boot-actuator
 <dependency>  
     <groupid>org.springframework.boot</groupid>  
     <artifactid>spring-boot-actuator</artifactid>  
     <version>Version</version>  
 </dependency>  
And then instead of relying on Spring Boot Autoconfiguration, in your Java Annotation configuration you can do the following;
@Configuration
@Import({
        EndpointWebMvcAutoConfiguration.class,
        ManagementServerPropertiesAutoConfiguration.class,
        EndpointAutoConfiguration.class
})
And in order to generate the git.properties file you can use the Maven git-commit-id plugin and use it as below;
 <build>  
     <pluginmanagement>  
       <plugins>  
         <plugin>  
           <groupid>pl.project13.maven</groupid>  
           <artifactid>git-commit-id-plugin</artifactid>  
           <version>2.2.4</version>  
           <executions>  
             <execution>  
               <id>get-the-git-infos</id>  
               <goals>  
                 <goal>revision</goal>  
               </goals>  
               <phase>package</phase>  
             </execution>  
             <execution>  
               <id>validate-the-git-infos</id>  
               <goals>  
                 <goal>validateRevision</goal>  
               </goals>  
             </execution>  
           </executions>  
           <configuration>  
             <dotgitdirectory>${project.basedir}/../.git</dotgitdirectory>  
             <dateformat>yyyy-MM-dd'T'HH:mm:ssZ</dateformat>  
             <dateformattimezone>${user.timezone}</dateformattimezone>  
             <generategitpropertiesfile>true</generategitpropertiesfile>  
             <generategitpropertiesfilename>${project.build.outputDirectory}/git.properties</generategitpropertiesfilename>  
             <format>properties</format>  
             <skippoms>true</skippoms>  
             <injectallreactorprojects>false</injectallreactorprojects>  
             <failonnogitdirectory>true</failonnogitdirectory>  
             <failonunabletoextractrepoinfo>true</failonunabletoextractrepoinfo>  
             <commitidgenerationmode>flat</commitidgenerationmode>  
             <gitdescribe>  
               <skip>false</skip>  
               <always>true</always>  
               <dirty>-dirty</dirty>  
               <match>*</match>  
               <tags>false</tags>  
               <forcelongformat>false</forcelongformat>  
             </gitdescribe>  
             <validationproperties>  
               <validationproperty>  
                 <name>validating project version</name>  
                 <value>${project.version}</value>  
                 <shouldmatchto>&lt;![CDATA[^.*(?&lt;!-SNAPSHOT)$]]&gt;</shouldmatchto>  
               </validationproperty>  
             </validationproperties>  
           </configuration>  
          </plugin>  
        </plugins>  
      </pluginmanagement>  
   </build>  
And when packaging you can use the following command
$ mvn clean package git-commit-id:revision 
Now when you access http://://info endpoint you will see the git commit id, branch name, commit time etc. and you can customize the pom.xml git-commit-id plugin configuration to have more information.