Welcome To Fusebes - Dev & Programming Blog

Spring Boot File Upload / Download with JPA, Hibernate, and MySQL database
03
Mar
2021

Spring Boot File Upload / Download with JPA, Hibernate and MySQL database

In this article, you’ll learn how to upload and download files in a Restful spring boot web service. The files will be stored in MySQL database.

This article is a continuation of an earlier article where I’ve shown how to upload files and store them in the local filesystem.

We’ll reuse most of the code and concepts described in the last article. So I highly recommend you to go through that before reading this one.

Following is the directory structure of the complete application for your reference –

Spring Boot File Upload Download JPA, Hibernate, MySQL database example.

JPA and MySQL dependencies

Since we’ll be storing files in MySQL database, we’ll need JPA and MySQL dependencies along with Web dependency. So make sure that your pom file contains the following dependencies –

<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>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<scope>runtime</scope>
	</dependency>

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

If you’re building the project from scratch, you can generate the project skeleton from Spring Initialzr website

Configuring the Database and Multipart File properties

Next, we need to configure the MySQL database url, username, and password. You can configure that in the src/main/resources/application.properties file –

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url= jdbc:mysql://localhost:3306/file_demo?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username= root
spring.datasource.password= pass

## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update

## Hibernate Logging
logging.level.org.hibernate.SQL= DEBUG


## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB

The above properties file also has Multipart file properties. You can make changes to these properties as per your requirements.

DBFile model

Let’s create a DBFile entity to model the file attributes that will be stored in the database –

package com.example.filedemo.model;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

@Entity
@Table(name = "files")
public class DBFile {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    private String fileName;

    private String fileType;

    @Lob
    private byte[] data;

    public DBFile() {

    }

    public DBFile(String fileName, String fileType, byte[] data) {
        this.fileName = fileName;
        this.fileType = fileType;
        this.data = data;
    }

    // Getters and Setters (Omitted for brevity)
}

Note that, the file’s contents will be stored as a byte array in the database.

DBFileRepository

Next, we need to create a repository to save files in the database and retrieve them back –

package com.example.filedemo.repository;

import com.example.filedemo.model.DBFile;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DBFileRepository extends JpaRepository<DBFile, String> {

}

DBFileStorageService

The following DBFileStorageService contains methods to store and retrieve files to/from the database –

package com.example.filedemo.service;

import com.example.filedemo.exception.FileStorageException;
import com.example.filedemo.exception.MyFileNotFoundException;
import com.example.filedemo.model.DBFile;
import com.example.filedemo.repository.DBFileRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;

@Service
public class DBFileStorageService {

    @Autowired
    private DBFileRepository dbFileRepository;

    public DBFile storeFile(MultipartFile file) {
        // Normalize file name
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());

        try {
            // Check if the file's name contains invalid characters
            if(fileName.contains("..")) {
                throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
            }

            DBFile dbFile = new DBFile(fileName, file.getContentType(), file.getBytes());

            return dbFileRepository.save(dbFile);
        } catch (IOException ex) {
            throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
        }
    }

    public DBFile getFile(String fileId) {
        return dbFileRepository.findById(fileId)
                .orElseThrow(() -> new MyFileNotFoundException("File not found with id " + fileId));
    }
}

FileController (File upload/download REST APIs)

Finally, following are the Rest APIs to upload and download files –

package com.example.filedemo.controller;

import com.example.filedemo.model.DBFile;
import com.example.filedemo.payload.UploadFileResponse;
import com.example.filedemo.service.DBFileStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@RestController
public class FileController {

    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private DBFileStorageService dbFileStorageService;

    @PostMapping("/uploadFile")
    public UploadFileResponse uploadFile(@RequestParam("file") MultipartFile file) {
        DBFile dbFile = dbFileStorageService.storeFile(file);

        String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
                .path("/downloadFile/")
                .path(dbFile.getId())
                .toUriString();

        return new UploadFileResponse(dbFile.getFileName(), fileDownloadUri,
                file.getContentType(), file.getSize());
    }

    @PostMapping("/uploadMultipleFiles")
    public List<UploadFileResponse> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files) {
        return Arrays.asList(files)
                .stream()
                .map(file -> uploadFile(file))
                .collect(Collectors.toList());
    }

    @GetMapping("/downloadFile/{fileId}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String fileId) {
        // Load file from database
        DBFile dbFile = dbFileStorageService.getFile(fileId);

        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(dbFile.getFileType()))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + dbFile.getFileName() + "\"")
                .body(new ByteArrayResource(dbFile.getData()));
    }

}

Results

I’ll be reusing the complete front-end code that I demonstrated in the first part of this article. You should check out the first article to learn more about the front-end code.

Once you have the front-end code in place, type the following command to run the application –

mvn spring-boot:run

Here is a screenshot of the final app –

Spring Boot File Upload Download with JPA, Hibernate and MySQL database demo

That’s all for now. Thanks for reading!

How to delete a directory recursively with all its subdirectories and files in Java
03
Mar
2021

How to delete a directory recursively with all its subdirectories and files in Java

In this short article, you’ll learn how to delete a directory recursively along with all its subdirectories and files.

There are two examples that demonstrate how to achieve this task. The idea behind both of the examples is to traverse the file tree, and delete the files in any directory before deleting the directory itself.

Delete directory recursively – Java 8+

This example makes use of Files.walk(Path) method that returns a Stream<Path> populated with Path objects by walking the file-tree in depth-first order.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;

public class DeleteDirectoryRecursively {
    public static void main(String[] args) throws IOException {
        Path dir = Paths.get("java");

        // Traverse the file tree in depth-first fashion and delete each file/directory.
        Files.walk(dir)
                .sorted(Comparator.reverseOrder())
                .forEach(path -> {
                    try {
                        System.out.println("Deleting: " + path);
                        Files.delete(path);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
    }
}

Delete directory recursively – Java 7

The following example uses Files.walkFileTree(Path, FileVisitor) method that traverses a file tree and invokes the supplied FileVisitor for each file.

We use a SimpleFileVisitor to perform the delete operation.

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class DeleteDirectoryRecursively1 {
    public static void main(String[] args) throws IOException {
        Path dir = Paths.get("java");

        // Traverse the file tree and delete each file/directory.
        Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                System.out.println("Deleting file: " + file);
                Files.delete(file);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                System.out.println("Deleting dir: " + dir);
                if (exc == null) {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                } else {
                    throw exc;
                }
            }
        });
    }
}
3 Layer Automated Testing
26
Mar
2021

3 Layer Automated Testing

Birth of Quality Engineering

Quality Assurance practice was relatively simple when we built the Monolith systems with traditional waterfall development models. The Quality Assurance (QA) teams would start the GUI layer’s validation process after waiting for months for the product development. To enhance the testing process, we would have to spend a lot of efforts and $$$ (commercial tools) in automating the GUI via various tools like Microfocus UFTSeleniumTest CompleteCoded UIRanorex etc., and most often these tests are complex to maintain and scale. Thus, most QA teams would have to restrict their automated tests to smoke and partial regression, ending in inadequate test coverage.

With modern technology, the new era tech companies, including Varo, have widely adopted Microservices-based architecture combined with the Agile/ Dev-Ops development model. This opens up a lot of opportunities for Quality Assurance practice, and in my opinion, this was the origin of the transformation from Quality Assurance to “Quality Engineering.”

The Common Pitfall

While automated testing gives us a massive benefit with the three R’s (Repeatable → Run any number of times, Reliable → Run with confidence, Reusable → Develop, and share), it also comes with maintenance costs. I like to quote Grady Boosh’s — “A fool with a tool is still a fool.” Targeting inappropriate areas would not provide us the desired benefit. We should consider several factors to choose the right candidate for automation. Few to name are the lifespan of the product, the volatility of the requirements, the complexity of the tests, business criticality, and technical feasibility.

It’s well known that the cost of a bug increases toward the right of software lifecycle. So it is necessary to implement several walls of defenses to arrest these software bugs as early as possible (Shift-Left Testing paradigm). By implementing an agile development model with a fail-fast mindset, we have taken care of our first wall of defense. But to move faster in this shorter development cycle, we must build robust automated test suites to take care of the rolled out features and make room for testing the new features.

The 3 Layer Architecture

The Varo architecture comprises three essential layers.

  • The Frontend layer (Web, iOS, Mobile apps) — User experience
  • The Orchestration layer (GraphQl) — Makes multiple microservices calls and returns the decision and data to the frontend apps
  • The Microservice layer (gRPC, Kafka, Postgres) — Core business layer

While understanding the microservice architecture for testing, there were several questions posed.

  • Which layer to test?
  • What to test in these layers?
  • Does testing frontend automatically validate downstream service?
  • Does testing multiple layers introduce redundancies?

We will try to answer these by analyzing the table below, which provides an overview of what these layers mean for quality engineering.

After inferring the table, we have loosely adopted the Testing Pyramid pattern to invest in automated testing as:

  • Full feature/ functional validations on Microservices layer
  • Business process validations on Orchestration layer
  • E2E validations on Frontend layer

The diagram below best represents our test strategy for each layer.

Note: Though we have automated white-box tests such as unit-test and integration-test, we exclude those in this discussion.

Use Case

Let’s take the example below for illustration to understand best how this Pyramid works.

The user is presented with a form to submit. The form accepts three inputs — Field A to get the user identifier, Field B a drop-down value, and Field C accepts an Integer value (based on a defined range).

Once the user clicks on the Submit button, the GraphQL API calls Microservice A to get what type of customer. Then it calls the next Microservice B to validate the acceptable range of values for Field C (which depends on the values from Field A and Field B).

Validations:

1. Feature Validations

✓ Positive behavior (Smoke, Functional, System Integration)

  • Validating behavior with a valid set of data combinations
  • Validating database
  • Validating integration — Impact on upstream/ downstream systems

✓ Negative behavior

  • Validating with invalid data (for example: Invalid authorization, Disqualified data)

2. Fluent Validations

✓ Evaluating field definitions — such as

  • Mandatory field (not empty/not null)
  • Invalid data types (for example: Int → negative value, String → Junk values with special characters or UUID → Invalid UUID formats)

Let’s look at how the “feature validations” can be written for the above use case by applying one of the test case authoring techniques — Boundary Value Analysis.

To test the scenario above, it would require 54 different combinations of feature validations, and below is the rationale to pick the right candidate for each layer.

Microservice Layer: This is the layer delivered first, enabling us to invest in automated testing as early as possible (Shift-Left). And the scope for our automation would be 100% of all the above scenarios.

Orchestration Layer: This layer translates the information from the microservice to frontend layers; we try to select at least two tests (1 positive & 1 negative) for each scenario. The whole objective is to ensure the integration is working as expected.

Frontend Layer: In this layer, we focus on E2E validations, which means these validations would be a part of the complete user journey. But we would ensure that we have at least one or more positive and negative scenarios embedded in those E2E tests. Business priority (frequently used data by the real-time users) helps us to select the best scenario for our E2E validations.

Conclusion

There are always going to be sets of redundant tests across these layers. But that is the trade-off we had to take to ensure that we have correct quality gates on each of these layers. The pros of this approach are that we achieve safe and faster deployments to Production by enabling quicker testing cycles, better test coverage, and risk-free decisions. In addition, having these functional test suites spread across the layers helps us to isolate the failures in respective areas, thus saving us time to troubleshoot an issue.

However, often, not one size fits all. The decision has to be made based on understanding how the software architecture is built and the supporting infrastructure to facilitate the testing efforts. One of the critical success factors for this implementation is building a good quality engineering team with the right skills and proper tools. But that is another story — Coming soon “Quality Engineering: Redefined.”

Deploying AND Hosting Spring Boot applications on Heroku
06
Feb
2021

Deploying / Hosting Spring Boot applications on Heroku

Heroku is a cloud platform as a service (PaaS) that you can use to deploy, manage, and scale your applications. It supports several programming languages and has a very simple and convenient deployment model.

In this article, you’ll learn how to deploy Spring Boot applications on Heroku with step by step instructions.

There are several ways of deploying spring boot apps to Heroku. I’ll take you through all of them one by one. I’ll also show you the pros and cons of using one method over the other.

Creating a Simple Spring Boot app for deployment

Before learning about deployment, Let’s first create a simple Spring Boot app that we’ll deploy on Heroku.

  1. Bootstrapping the appThe easiest way to bootstrap a new spring boot app is using Spring Boot CLI. Just enter the following command in your terminal to generate the project using Spring Boot CLI –$ spring init -n=heroku-demo -d=web heroku-demo Using service at https://start.spring.io Project extracted to '/Users/rajeevkumarsingh/heroku-demo' The command will generate the application with all the necessary configurations in a directory named heroku-demo.You can also use the Spring Initializr web app to generate the application if you don’t want to install Spring Boot CLI:
    • Open http://start.spring.io.
    • Enter heroku-demo in the artifact field.
    • Add Web in the dependencies section.
    • Click Generate Project to generate and download the project.
    This will downloaded a zip archive of the project with all the directories and configurations.
  2. Building a Demo endpointLet’s add a controller endpoint to the application so that it responds with a message whenever we access the root (/) endpoint.Create a file named IndexController.java inside src/main/java/com/example/herokudemo/, and add the following code to it –package com.example.herokudemo; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @GetMapping("/") public String index() { return "Hello there! I'm running."; } }
  3. Running the appYou can run the app using the following command –$ mvn spring-boot:run The app will start on port 8080 by default. You can access it by going to http://localhost:8080. You should see the message Hello there! I'm running..

Deploying a Spring Boot app on Heroku using Git and Heroku CLI

All right! Now that we have a sample app, let’s learn how to deploy it to Heroku. In this section we’ll deploy the app using Git and Heroku CLI.

You need to have a Heroku account. If you don’t have one, you can create it from Heroku’s Signup Page. Once you’re registered with Heroku, follow the steps below to deploy the Spring Boot app.

  1. Download and install Heroku CLIHeroku CLI is a command line application that lets you create, deploy and manage Heroku apps from the command line. You can download Heroku CLI from Heroku Dev Center. You’ll also find the instructions for installing Heroku CLI on your platform on that page.
  2. Login using your email and passwordEnter the following command to login to Heroku using Heroku CLIheroku login You will be prompted to enter your Heroku account’s email and password. Enter all the details –Enter your Heroku credentials: Email: youremail@example.com Password: ************** Logged in as youremail@example.com That’s it! You’re logged in to Heroku. We can now proceed with the deployment.
  3. Set up Git and create a Heroku appExecute the following commands from the root directory of the project to create a local Git repository for the project –git init git add . git commit -m "initial commit" Now, create a new heroku app using heroku create command like so –$ heroku create Creating app... done, ⬢ apple-custard-73702 https://apple-custard-73702.herokuapp.com/ | https://git.heroku.com/apple-custard-73702.git The above command creates a new heroku app and also makes a remote repository for the app at Heroku.Heroku chooses a random unique name for the app by default. If you want to specify a custom name then you can pass the app name in the heroku create command like this –heroku create <YOUR_UNIQUE_APP_NAME> You can also rename an existing app using heroku apps:rename command –heroku apps:rename --app <OLD_NAME> <NEW_NAME> Let’s use the above command to rename our app –$ heroku apps:rename --app apple-custard-73702 projectname-heroku-demo Renaming apple-custard-73702 to projectname-heroku-demo... done
    Git remote heroku updated ▸ Don't forget to update git remotes for all other local checkouts of the app.
  4. Deploy the app to HerokuFinally, you can deploy the app by simply pushing the code to the remote repository named heroku which was created by the heroku create command.git push heroku master Heroku automatically detects that the project is a Maven/Java app and triggers the build accordingly.The deployment will take some time. You should see the build logs on console. Once the application is deployed, you can open it using the following command –heroku open The app should open in the system’s default browser and you should see the message Hello there! I'm running..You can see the logs of the application anytime by running the following command –heroku logs --tail

This is the easiest method of deploying spring boot apps to Heroku. But its not the ideal option if –

  • Your project doesn’t use Git.
  • Your project is closed source and you don’t want to push the source code to Heroku.
  • Your project uses some dependencies that are internal to your company. In this case the source code won’t compile at Heroku because it won’t be able to download the internal dependencies.

Deploying a Spring Boot app on Heroku using Heroku CLI Deploy Plugin

Unlike the previous method, this heroku deployment method doesn’t require you to setup a Git repository for your project and push the source code to Heroku.

You can build and package the app locally and deploy the packaged jar file to Heroku. This is done using Heorku CLI Deploy Plugin. It allows you to deploy a pre-built jar or war file to Heroku.

Follow the steps below to deploy a Spring Boot app on Heroku using Heroku CLI Deploy plugin:

  1. Install Heroku Deploy CLI PluginEnter the following command in your terminal to install the heroku-cli-deploy plugin:heroku plugins:install heroku-cli-deploy
  2. Package your Spring Boot applicationNext, you’ll need to package the application in the form of a jar file. You can do that using mvn package command –mvn clean package This command will create a packaged jar file of the application in the target folder of the project.
  3. Create a Heroku appNow let’s create a Heroku app using heroku create command –heroku create <APP-NAME> --no-remote Notice the use of --no-remote option. This tells heroku to not setup any git remote repository.
  4. Deploy the jar file on HerokuFinally, you can deploy the jar file using the following command –heroku deploy:jar target/heroku-demo-0.0.1-SNAPSHOT.jar --app <APP-NAME> The above command should have deployed the app successfully. But there is a caveat here. Let’s check the logs of the application to understand that-heroku logs --tail --app <APP-NAME> If you check the logs using the above command, you’ll notice an error like this –Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 90 seconds of launch Heroku requires our application to listen on the port passed through $PORT environment variable. But the spring boot application listens on port 8080 by default.Fixing the Port binding errorThere are two ways of fixing the port binding error:
    • You can specify the port that the application should listen to in a property named server.port in the src/main/java/resources/application.properties file –server.port=${PORT:8080} The above property will evaluate to the PORT environment variable if it is available, otherwise it will fall back to the default port 8080.
    • Alternatively, you can use a Procfile to customize the command that is used to run the application. The customized command would include the server.port configuration that will be used by Spring Boot to bind the app.Create the Procfile in the root directory of the project with the following configuration –# Procfile web: java $JAVA_OPTS -jar target/heroku-demo-0.0.1-SNAPSHOT.jar -Dserver.port=$PORT $JAR_OPTS
    After doing one of the above two, You can deploy the app using the same heroku deploy:jar command –heroku deploy:jar target/heroku-demo-0.0.1-SNAPSHOT.jar --app <APP-NAME> This time the application should start successfully. You can verify that by opening the app in the browser using heroku open command.

Deploying a Spring Boot app on Heroku using Heroku Maven Plugin

The Heroku Maven plugin allows you to deploy any maven application without having to install Heroku CLI. It integrates the deployment into your build system, and works out of the box with any CI / CD server like Jenkins or Travis CI.

Follow the steps below to deploy your spring boot application using Heroku Maven Plugin.

  1. Adding and Configuring Heroku Maven Plugin
    Add the heroku-maven-plugin to the plugins section of your pom.xml file –
    Change the <appName>
  2.  configuration to an app name of your choice.
 -<build> <plugins> <!-- Heroku Maven Plugin Configuration --> <plugin> <groupId>com.heroku.sdk</groupId> <artifactId>heroku-maven-plugin</artifactId> <version>2.0.3</version> <configuration> <appName>project-heroku-maven-demo</appName> <includeTarget>false</includeTarget> <includes> <include>${project.build.directory}/${project.build.finalName}.jar</include> </includes> <jdkVersion>${java.version}</jdkVersion> <processTypes> <web>java $JAVA_OPTS -jar ${project.build.directory}/${project.build.finalName}.jar</web> </processTypes> </configuration> </plugin> </plugins> </build> Change the <appName>
  1. Creating the app
  2. You can create an app either using Heroku CLI or from the Heroku dashboard. To create the app using Heroku CLI, type the following command in your terminal –heroku create project-heroku-maven-demo Don’t forget to change the name project-heroku-maven-demo to the app name that you’ve set in the pom.xml file.If you don’t want to install Heroku CLI, then create the app from the dashboard.
  3. Deploying the app using Heroku maven plugin
  4. If you have Heroku CLI installed, then use the following maven command to deploy the application –mvn clean heroku:deploy If you don’t have Heroku CLI installed, then you need to set the HEROKU_API_KEY environment variable before running heroku:deploy –HEROKU_API_KEY="YOUR HEROKU API KEY" mvn clean heroku:deploy You can find the API key from Heroku dashboard.

Thanks for reading. In the next article, you’ll learn how to deploy spring boot applications on AWS using Elastic beanstalk. Also, Don’t forget to subscribe to my newsletter to get notified whenever I publish new articles on the blog.

Understanding Regular Expressions
18
Mar
2021

Understanding Regular Expressions

it’s time to get over your fears of regular expressions(regex)! If you’re like me, you’ve heard of regex but have always been confused by the cryptic syntax. Fear not, because in the next 5 minutes, you’ll have a basic understanding of what’s going on and how to use RegEx to make your life easier!

So what are Regular Expressions ?

Basically, regular expressions are patterns that you can use to find matching patterns in strings. This could be useful for password validation, or checking if the formatting of input fields is correct, or perhaps you want to parse a phone number, etc…

How do you use them?

There are a couple ways of creating a regex, you can either use the literal version( which I prefer) or you can use the constructor option. The literal version looks like so:

const regEx = /hello/;

When making a regular expression literal, you place the pattern between two forward slashes. Above, we would be searching for the word ‘hello’.

Using the constructor would look something like this:

 const regEx = new RegExp('hello');

I’m not the biggest fan of this, so moving forward I will only be using the literal version.

Testing Methods

How do you test your regex anyways? JavaScript provides us a couple of methods that are compatible with regular expressions:

  • test()
  • exec()
  • match()
  • matchAll()
  • replace()
  • search()
  • split()

For my examples I will primarily be using test() and match(). Test is a RegExp method used to search a string and return either true or false if your pattern is found, and match is a string method that can use regex and returns the instances found in an array.

How to Match Strings

As you saw in my example above, I created the regex /hello/. This pattern would be useful for finding the first case sensitive instance of ‘hello’. What if you want to find every instance of ‘hello’, case insensitive? This is where ‘flags’ come in.

Flags act as modifiers to your regular expression. They go after the closing slash and there are five native flags in JavaScript!

  • i : This makes your search case-insensitive!
  • g : This flag tells your search to look for all matches, not just the first one.
  • m : Multiline mode
  • s : This enables “dotall” mode. It allows ‘.’ to match newlines
  • u : Enables full unicode support
  • y : sticky; it matches only from the index indicated by the lastIndex property of the regex in the target string.

So if we wanted to find every instance of ‘hello’ case insensitive, in the string “Hello heLLO hellO HELLO!”, we would do something like this:

let regex = /hello/gi;
let string = “Hello heLLO hellO HELLO!”;
string.match(regex);//returns [ 'Hello', 'heLLO', 'hellO', 'HELLO' ]

See that’s not so bad! Let’s look at another tool that’s very useful: character classes.

Character Classes

Character classes let you match a group of characters by placing them inside square brackets! This lets you find multiple matches with different characters. For example: if you wanted to find the words ‘big’, ‘bag’, ‘bog’, ‘bug’ in the string “The big bug crawled out of my bag and went into the bog.” you could use a simple regular expression to do so!

let string = “The big bug crawled out of my bag and went into the bog.”;let regex = /b[aiou]g/gi;
string.match(regex);//returns [ 'big', 'bug', 'bag', 'bog' ]

That’s pretty cool. You can also search for a range of characters inside of a character set using a hyphen ‘-’! For example, if I wanted to find every number in a string for some reason, I could do something like this:

let string = "I want 6 chocolates, 5 pop tarts, and 3 pumpkin pies please."let regex = /[0-9]/g;
string.match(regex);//returns [ '6', '5', '3' ]

You can do the above and so, so much more using Regular Expressions. You’ll find it’s basically like another language! This is just the tip of the iceberg, and I hope at least I’ve made regex a little less scary. There is so much more to regular expressions than I can cover here, but there are plenty of great resources to continue learning.

Happy Coding!

What is auto-configuration? How to enable or disable certain configuration?
30
Mar
2021

What is Auto-Configuration? How to Enable or Disable Certain Configuration?

Spring boot auto configuration scans the classpath, finds the libraries in the classpath and then attempt to guess the best configuration for them, and finally configure all such beans.

Auto-configuration tries to be as intelligent as possible and will back-away as we define more of our own custom configuration. It is always applied after user-defined beans have been registered.

Auto-configuration works with help of @Conditional annotations such as @ConditionalOnBean and @ConditionalOnClass.

For example, look at AopAutoConfiguration class.

If class path scanning finds EnableAspectJAutoProxy, Aspect, Advice and AnnotatedElement classes and spring.aop.auto=false is not present in properties file then Spring boot will configure the Spring AOP module for us.

@Configuration @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class }) @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true) public class AopAutoConfiguration {//code}
Kotlin Overview, Installation, and Setup
07
Mar
2021

Kotlin Overview, Installation, and Setup

Kotlin is a programming language developed by JetBrains, the same company that has built world-class IDEs like IntelliJ IDEA, PhpStorm, PyCharm, ReSharper etc.

It runs on the Java Virtual Machine (JVM), and can also be compiled to JavaScript and Machine Code.

In this tutorial, I’ll give you a brief overview of Kotlin and its features. I’ll also help you set up Kotlin in your system and prepare you for future tutorials.

Why Kotlin?

In today’s world where we have a dozen programming language for every possible task, following are few reasons to choose Kotlin as the primary language for your next exciting project –

1. Statically Typed

Kotlin is a Statically typed programming language. This means that the type of every variable and expression is known at compile time.

The advantage with static typing is that the compiler can validate the methods calls and property access on the objects at compile time itself and prevent lots of trivial bugs that would otherwise crop up at runtime.

Although Kotlin is a statically typed language, it doesn’t require you to explicitly specify the type of every variable you declare. Most of the time, Kotlin can infer the type of a variable from the initializer expression or the surrounding context. This is called Type Inference. You’ll learn more about Type inference in the Variables and Data Types tutorial.

2. Concise

Kotlin is concise. It drastically reduces the amount of boilerplate code that you have been writing all the time in other OOP languages like Java.

It provides rich idioms for performing common tasks. For example, You can create a POJO class with getters, setters, equals()hashCode() and toString() methods in a single line –

data class User(val name: String, val email: String, val country: String)

3. Safe

Kotlin is safe. It avoids the most dreaded and annoying NullPointerExceptions by supporting nullability as part of its type system.

It works like this – Every variable in Kotlin is non-null by default:

String str = "Hello, World"    // Non-null type (can't hold null value)
str = null // Compiler Error

To allow a variable to hold null value, you need to explicitly declare it as nullable:

String nullableStr? = null   // Nullable type (can be null)

Since Kotlin knows which variables are nullable and which are not, It can detect and disallow unsafe calls at compile time itself that would otherwise result in a NullPointerException at runtime –

println(nullableStr.length()) // Compiler Error

Kotlin doesn’t allow the method call length() on the nullableStr variable because the call is not safe and may lead to NullPointerException.

However, if you add a null check then the method call is allowed –

if(nullablStr != null) {
    println(nullableStr.length())
}

Notice how Kotlin is enforcing developers to write safe code by distinguishing between nullable and non-null types.

4. Explicit

Kotlin is Explicit. It will do/allow things only if you tell it to do so. Explicitness is considered a good thing. Being explicit means being specific about your design choices and not hiding anything from the readers or consumers of your code.

Following are few examples of Explicitness in Kotlin –

  • Kotlin doesn’t allow implicit type conversions, for example, int to long, or float to double. It provides methods like toLong() and toDouble() to do so explicitly.
  • All the classes in Kotlin are final (non-inheritable) by default. You need to explicitly mark a class as open to allow other classes to inherit from it. Similarly, All the properties and member functions of a class are final by default. You need to explicitly mark a function or property as open to allow child classes to override it.
  • If you’re overriding a parent class function or property, then you need to explicitly annotate it with the override modifier.

5. Easy to learn.

Kotlin has a very low learning curve. The basic syntax looks a lot like Java. If you have a little experience in Java or any other OOP language then you’ll be able to pick up Kotlin in a matter of hours.

6. Functional and Object Oriented Capabilities

Kotlin has both functional and object-oriented capabilities. It has a rich set of features to support functional programming which includes functional types, lambda expressions, data classes and much more.

7. Completely interoperable with Java

Kotlin is 100% interoperable with Java. You can easily access Java code from Kotlin and vice versa. You can use Kotlin and Java in the same project without any problem. This enables easy adoption of Kotlin into your existing Java projects.

Kotlin Java Interoperability

8. Excellent Tooling

Kotlin has excellent tooling support. You can choose any Java IDE – IntelliJ IDEA, Eclipse, Android Studio. All of them support Kotlin.

Moreover, you can also download Kotlin’s standalone compiler and run Kotlin code from the command line.

Kotlin Tool Friendly

9. Build Applications for Server Side, Android, Browser, and Desktop

You can use Koltin to build applications for a wide range of platforms including Server side, Android, Browser, and Desktop.

  • Android has official support for Kotlin.
  • On the server side, you can use Kotlin with the Spring framework which has added full support for Kotlin in Spring version 5.
  • Kotlin can be compiled to JavaScript and Machine code as well.

10. Free and Open Source

Kotlin programming language, including the compiler, libraries and all the tooling is completely free and open source. It is available under Apache 2 license and the complete project is hosted on Github – https://github.com/JetBrains/kotlin

Setup Kotlin

You can set up and run Kotlin programs in several ways. You can either install kotlin’s compiler and run Kotlin programs from the command line or install and setup Kotlin in an IDE like IntelliJ or Eclipse –

  • Install Kotlin’s Standalone Compiler
  • Setup Kotlin in IntelliJ IDEA
  • Setup Kotlin in Eclipse

Installing the Standalone Compiler

Follow the steps below to install Kotlin’s compiler –

  1. Go to Kotlin releases page on Github
  2. Download Kotlin’s compiler in the form of a zip file from the Assets section on the Github releases page. The latest version of Kotlin compiler at the time of writing this page is 1.2.10
  3. Unzip the downloaded kotlin-compiler-x.x.x.zip file and store the unzipped folder in a location where you have write access.
  4. Add path-to-unzipped-folder/bin to your PATH variable.
  5. Verify the installation by typing kotlinc in the command line –
$ kotlinc
Welcome to Kotlin version 1.2.10 (JRE 1.8.0_112-b16)
Type :help for help, :quit for quit
>>>

Run your first Kotlin program from the command line

Open your favorite editor and create a new file called hello.kt with the following contents –

fun main(args: Array<String>) {
    println("Hello, World!")
}

Save the file and type the following commands to compile and run the program

$ kotlinc hello.kt
$ kotlin HelloKt
Hello, World

Setting up Kotlin in IntelliJ IDEA

Install the latest version of IntelliJ IDEA. Kotlin comes bundled with the recent versions of IntelliJ. You won’t need to install any plug-in separately to run Kotlin programs.

Follow these steps to create and run a new Kotlin project in IntelliJ

  1. Create a new project by selecting “Create New Project” on the welcome screen or go to File → New → Project.Select Kotlin on the left side menu and Kotlin/JVM from the options on the right side –IntelliJ Kotlin Project Setup
  2. Specify the project’s name and location, and select a Java version (1.6+) in the Project SDK. Once all the details are entered, click Finish to create the project –IntelliJ Kotlin Hello World Project ExampleThe generated project will look like this –IntelliJ Kotlin Hello World Project Directory Structure
  3. Let’s now create a new Kotlin file. Right click on src folder → New → Kotlin File/Class.IntelliJ Create new Kotlin ClassA prompt will appear where you’ll need to provide a name for the file. Let’s name it HelloWorld.
  4. Now let’s write a simple hello world program in the new file that we have created. Add the following main() function to the HelloWorld.kt file –Kotlin Hello World Example
  5. Finally, You can run the program by clicking the Kotlin icon that appears beside the main() method –Run Kotlin Program in IntelliJ IDEA

You can also run the program by Right Clicking the HelloWorld.kt file and selecting Run 'HelloWorldKt'.

Setting up Kotlin in Eclipse

I assume that you have Eclipse installed on your system. If not, download the eclipse installer from Eclipse Downloads page, and install “Eclipse IDE for Java Developers”.

Once Eclipse is installed, follow the steps below to setup and run Kotlin in Eclipse –

  1. Install Kotlin Plugin from Eclipse Marketplace: Go to Help → Eclipse Marketplace, and search for Kotlin.Eclipse Kotlin PluginClick install to install the plugin.
  2. You will need to restart eclipse once the installation is finished.
  3. Let’s verify the plugin’s installation switching to Kotlin perspective in eclipse. Go to Window → Perspective → Open Perspective → Other. A window will open which will show Kotlin as a new perspective. Select Kotlin and click Open to open Kotlin perspective –Eclipse Kotlin Perspective
  4. Let’s now create a new project. Select File → New → Kotlin Project. Enter the project’s name and click finish –Create Kotlin Project in Eclipse
  5. A new project will be created which will look like this –Eclipse Kotlin Project Directory Structure
  6. Let’s now create a new Kotlin file under the src folder. Right click src folder → New → Kotlin File –Create Kotlin File/Class in Eclipse
  7. First, add the following code in the HelloWorld.kt file, and then right-click anywhere on the source file and click Run As → Kotlin Application to run the application –Run Kotlin Application in Eclipse

Conclusion

That’s all folks! In this article, you learned about Kotlin and some of its features. You also learned how to setup and run Kotlin programs in your system using Kotlin’s standalone compiler and IDEs like IntelliJ and Eclipse.

A Guide on How to Write a Clean Code
18
Mar
2021

A Guide on How to Write a Clean Code

In this article, I’m going to talk about writing clean code in general and then end up with some examples. As an Android developer having a clean code has always been challenging for me which needs lots of effort and that’s just coding and coding.

Rules We Should Follow

  1. Ignore duplication (imply DRY principle-Don’t Repeat Yourself)
  2. Minimize entities, classes, and functions (avoid repetition)
  3. It should be readable and simple
  4. Be testable as it makes your code flexible and maintainable
  5. Follow SOLIDprinciples

S = Single-responsibility principle: A class should only have one purpose.

O = Open-closed principleA class should be open for extension, but closed for modification.

L = Liskov substitution principleAbstraction should be able to provide all needs of child class.

I = Interface segregation principleSmall interface is better than big one.

D = Dependency Inversion Principle: A class should depend on abstraction, not implementation.

6. Be careful with dependencies

As many as possible try to have one-directional dependency. When dependency goes in multiple directions, things get much more complicated which makes hard to update and change.

7. Don’t hardcode

Define constant or use variables instead of hardcoding the values which will not only help readability but also make it easy to change if it is being used at multiple places.

Now let’s start writing Clean Code 🚀 …

Valid Names

Naming is one of the hardest parts of programming and may take time to choose, but it is a strong way to convey your code’s intent to other developers who read them in the future which must show the purpose of that class, function, or variable and even tell what is going to do. Don’t append prefixes or type information. I always have a checklist in my mind as listed below which assures me that a name has been chosen well:

  • Are the variables named according to the convention (camelCase, PascalCase, etc)?.
  • Does the name have an appropriate length to ensure that no one will be confused by it?.
  • Are the name of variables clear about what they hold?.
  • Are the names meaningful, searchable, and easy to pronounce?.

Class names should not only be names (not verbs) but also should have the PascalCase convention. On the other hand, method names should be verbs or phrase verbs and follow the camelCase convention. The same rules apply to variable names.

Functions and Methods

Following S from SOLID principles, let functions and methods perform only one task which should be small. If the function arguments are too many, you should review your code and maybe pack them into an object or divide that task between some other functions. Prefer possible exceptions to return error codes and extract error handling try catch into their own function.

Comments

We should use comments only when it is necessary, not to explain bad code. Writing lengthy comments will not help us in changing our code into a clean one. If the code is bad, we should solve it by improving the code, not by adding instructions on how to use it, but it doesn’t mean that you shouldn’t use comments at all, sometimes it is important such as dealing with third party APIs where you need to explain some behavior.

Code Appearance

It might look unimportant at first glance, but it is of high importance to write your code with a well-organized format which makes it readable such as:

  • Do not write everything in a single line. Give proper whitespace, indentation, or line breaks in your code.

Indentation styles assist in identifying control flow and blocks of code. In some programming languages, indentation is used to delimit logical blocks of code; correct indentation in these cases is more than a matter of style. In other languages, indentation and white space do not affect function, although logical and consistent indentation makes code more readable. (Inspired by WIKIPEDIA)

  • Instance variables should be declared at the top of the class.
  • If functions are calling each other (dependent functions) they should be close while putting the caller at first.
  • It is often helpful to align similar elements vertically, to make typo-generated bugs more obvious.

Tests

The importance of Test code is equal to producing the code and of course, while writing tests you might find some bugs. However, it can sometimes be quite difficult to write a good test for a particular piece of code which is a result of a badly designed and untestable code. Testing is almost like coding for the second time so follow all the previous rules for writing a good test as well which should be as per below :

  • One assert and single concept per test
  • Easy to write and readable (simplicity)
  • Fast
  • Independent

To conclude, I hope this article could be helpful to write a better code although it is important to keep practicing and learning in this field 😃 …

How to check if a File or Directory exists in Java
03
Mar
2021

How to check if a File or Directory exists in Java

In this quick and short article, you’ll find two examples demonstrating how to check if a File or Directory exists at a given path in Java.
We’re going to get familiar with different ways to check the existence of a file or directory.

Check if a File/Directory exists using Java IO’s File.exists()

import java.io.File;

public class CheckFileExists1 {
    public static void main(String[] args) {

        File file = new File("/Users/callicoder/demo.txt");

        if(file.exists()) {
            System.out.printf("File %s exists%n", file);
        } else {
            System.out.printf("File %s doesn't exist%n", file);
        }

    }
}

Check if a File/Directory exists using Java NIO’s Files.exists() or Files.notExists()

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class CheckFileExists {
    public static void main(String[] args) {

        Path filePath = Paths.get("/Users/callicoder/demo.txt");

        // Checking existence using Files.exists
        if(Files.exists(filePath)) {
            System.out.printf("File %s exists%n", filePath);
        } else {
            System.out.printf("File %s doesn't exist%n", filePath);
        }


        // Checking existence using Files.notExists
        if(Files.notExists(filePath)) {
            System.out.printf("File %s doesn't exist%n", filePath);
        } else {
            System.out.printf("File %s exists%n", filePath);
        }
    }
}
Creating PDF with Java and iText
05
Mar
2021

Creating PDF with Java and iText

Java and PDF with iText. This article demonstrate how to create PDF files with Java and the iText library. In this tutorial iText version 5.0.x is used

iText is a Java library originally created by Bruno Lowagie which allows to create PDF, read PDF and manipulate them. The following tutorial will show how to create PDF files with iText. This tutorial assumes that you have basis in Java and Eclipse knowledge.

iText has a hierarchical structure. The smallest text unit is a “Chunk” which is a String with a pre-defined font. A “Phrase” combines several Chunks and allows to define line spacing. “Paragraph” is a subclass of “Phrase” and allows to define more layout attributes, e.g. margins. The class “Anchor” is a subclass of “Paragraph” and serves as the basis for hyperlinks in the generated PDF.

Create the following class “FirstPdf.java” . I assume that the code is pretty much self-explaining. I tried to add lots of comments to make it easier to understand. For more complex examples have a look at the iText Homepage.

package de.fusebes.itext.write;

import java.io.FileOutputStream;
import java.util.Date;

import com.itextpdf.text.Anchor;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chapter;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Section;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;


public class FirstPdf {
    private static String FILE = "c:/temp/FirstPdf.pdf";
    private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,
            Font.BOLD);
    private static Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12,
            Font.NORMAL, BaseColor.RED);
    private static Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16,
            Font.BOLD);
    private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12,
            Font.BOLD);

    public static void main(String[] args) {
        try {
            Document document = new Document();
            PdfWriter.getInstance(document, new FileOutputStream(FILE));
            document.open();
            addMetaData(document);
            addTitlePage(document);
            addContent(document);
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // iText allows to add metadata to the PDF which can be viewed in your Adobe
    // Reader
    // under File -> Properties
    private static void addMetaData(Document document) {
        document.addTitle("My first PDF");
        document.addSubject("Using iText");
        document.addKeywords("Java, PDF, iText");
        document.addAuthor("Lars Vogel");
        document.addCreator("Lars Vogel");
    }

    private static void addTitlePage(Document document)
            throws DocumentException {
        Paragraph preface = new Paragraph();
        // We add one empty line
        addEmptyLine(preface, 1);
        // Lets write a big header
        preface.add(new Paragraph("Title of the document", catFont));

        addEmptyLine(preface, 1);
        // Will create: Report generated by: _name, _date
        preface.add(new Paragraph(
                "Report generated by: " + System.getProperty("user.name") + ", " + new Date(), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                smallBold));
        addEmptyLine(preface, 3);
        preface.add(new Paragraph(
                "This document describes something which is very important ",
                smallBold));

        addEmptyLine(preface, 8);

        preface.add(new Paragraph(
                "This document is a preliminary version and not subject to your license agreement or any other agreement with vogella.com ;-).",
                redFont));

        document.add(preface);
        // Start a new page
        document.newPage();
    }

    private static void addContent(Document document) throws DocumentException {
        Anchor anchor = new Anchor("First Chapter", catFont);
        anchor.setName("First Chapter");

        // Second parameter is the number of the chapter
        Chapter catPart = new Chapter(new Paragraph(anchor), 1);

        Paragraph subPara = new Paragraph("Subcategory 1", subFont);
        Section subCatPart = catPart.addSection(subPara);
        subCatPart.add(new Paragraph("Hello"));

        subPara = new Paragraph("Subcategory 2", subFont);
        subCatPart = catPart.addSection(subPara);
        subCatPart.add(new Paragraph("Paragraph 1"));
        subCatPart.add(new Paragraph("Paragraph 2"));
        subCatPart.add(new Paragraph("Paragraph 3"));

        // add a list
        createList(subCatPart);
        Paragraph paragraph = new Paragraph();
        addEmptyLine(paragraph, 5);
        subCatPart.add(paragraph);

        // add a table
        createTable(subCatPart);

        // now add all this to the document
        document.add(catPart);

        // Next section
        anchor = new Anchor("Second Chapter", catFont);
        anchor.setName("Second Chapter");

        // Second parameter is the number of the chapter
        catPart = new Chapter(new Paragraph(anchor), 1);

        subPara = new Paragraph("Subcategory", subFont);
        subCatPart = catPart.addSection(subPara);
        subCatPart.add(new Paragraph("This is a very important message"));

        // now add all this to the document
        document.add(catPart);

    }

    private static void createTable(Section subCatPart)
            throws BadElementException {
        PdfPTable table = new PdfPTable(3);

        // t.setBorderColor(BaseColor.GRAY);
        // t.setPadding(4);
        // t.setSpacing(4);
        // t.setBorderWidth(1);

        PdfPCell c1 = new PdfPCell(new Phrase("Table Header 1"));
        c1.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(c1);

        c1 = new PdfPCell(new Phrase("Table Header 2"));
        c1.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(c1);

        c1 = new PdfPCell(new Phrase("Table Header 3"));
        c1.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(c1);
        table.setHeaderRows(1);

        table.addCell("1.0");
        table.addCell("1.1");
        table.addCell("1.2");
        table.addCell("2.1");
        table.addCell("2.2");
        table.addCell("2.3");

        subCatPart.add(table);

    }

    private static void createList(Section subCatPart) {
        List list = new List(true, false, 10);
        list.add(new ListItem("First point"));
        list.add(new ListItem("Second point"));
        list.add(new ListItem("Third point"));
        subCatPart.add(list);
    }

    private static void addEmptyLine(Paragraph paragraph, int number) {
        for (int i = 0; i < number; i++) {
            paragraph.add(new Paragraph(" "));
        }
    }
}

The resulting pdf should look like the following.

pdfwrite10