Monday, June 1, 2020

Introduction to Clean Architecture

The architecture of software refers to the overall design of a software project. It proposes models and
rules to determine the structures (like classes, interfaces, and structs) in a system and how they relate
to each other. Architecture defines where the application performs its core functionality and how that
functionality interacts with things like the database and the user interface. Anyhow the designed
architecture of the software should have the ability to change implementation details such as DBMS,
frameworks, and refactors and bug fixes should be effected in little part of the system most importantly
it should reduce the cost of the software lifecycle. 


Clean architecture refers to organizing the project so that it's easy to understand and easy to change
as the project grows. This architecture model was proposed in 2012 by Robert C. Martin.
Here my effort is to explain Uncle Bob’s Clean Architecture with simple manners. Let’s start with the
layered architecture we all are familiar with and will discuss the problems with the layered architecture.


Problem with the layered architecture

Layered architecture has more restrictions between layers so it’s difficult to define and defend clear abstraction from one layer to another. 

Also most of the time we do database driven designs in our projects in layered architecture. That couples domain logic or services in the business layer into the persistence layer.

So we first build a persistence layer and then we build business logic but it should be the other way around. Domain logic is the most important in this so we need to build domain logic first and then we have to implement the persistence layer. 

The layered architecture allows short cuts like layer bridging for example web layer can access the persistence layer sometimes it makes testing harder.

As the solution to the issues in layered architecture, we can use Clean Architecture instead. It has wrapped these layers with each other.



What is Clean Architecture



A software application has a domain that includes all the business rules and defines what the
application does. Domain should be the core of the application. Infrastructure includes Database, UIs,
APIs which are supported to the domain rule to function.
Architecture represented by the picture will reduce the cost of the software lifecycle. Because science,
the domain, and infrastructure has clear boundaries so it was easy to change and maintain the
application. Because of the boundary between the Domain and Infrastructure. Domain does not know
anything about infrastructure. This means that business rules do not depend on database or UI.
Not like the layered architecture here, the persistence layer has been decoupled from the business
layer. So we can independently work on these two layers. We can call this as a plugin architecture.

To make clear the domain layer has been divided into two sub-layers call Entity and Use Case and the input and output between the domain and infrastructure Adapter layer was introduced. 
So domain layers include all the business logic and outside of the domain layer are just details that need to perform the business. Dependencies between the layers only may point inwards.

Let’s look into each of these layers individually and what those layers do.


Entity


As Uncle Bob says Entities encapsulate Enterprise wide business rules. These can be POJOs,
objects with methods, or even data structures. Entities encapsulate most general and high-level business rules. These should not be affected by any change external to them, and these should be the most stable code within your application.


Use Case


Use Cases include application specific business rules. These encapsulate and implement all the use cases of the system. Changes in the Usecase layer should not affect the entity also this layer should not be affected by the outer layers such as database UI or the frameworks.


Adapter


Adapters are translators between the domain and the infrastructure which can trigger as an interactor to perform business logic.
They take input from the Infrastructure layer (as an example from GUI) and translate data that is convenient for Domain layer(UseCase and entities) also they take the output from the domain layer and form the data that convenient for Infrastructure layer (such as GUI, Database).


Infrastructure


This layer is where all the I/O components go: the UI, database, frameworks, devices, etc. t's the most volatile layer.

Implementation

To implement the solution with Clean Architecture we need to have a better understanding of SOLID principles. I have recognized two basic principles that are very important for better implementation. Those two are the Single Responsibility Principle and Dependency Inversion. I am going to brief these two principles here. That does not mean the other principles are not in use but those are better to have.

Dependency Inversion Principle


DIP refers to Higher-level modules should not depend on lower-level modules. Instead, both
higher-level modules and lower level modules should depend on abstractions.
This means that less stable classes and components should depend on more stable ones, not the other way around.


In the layered architecture which has database-driven architecture service has a dependency on the database through the entity, it couples to the persistence layer. What we do in Clean architecture is we inverse above dependency other way around. The service layer no longer has the dependency on persistence but other way around. The entity is no longer belongs to the persistence layer ad it belongs to the domain layer 


Single Responsibility Principle


SRP refers to a module that should have only one reason to change.
A module can be a class, package, component, etc.. 
EX: A class should only have one job to perform. It may have multiple methods, but these methods all work together to do one main thing. The class should only have one reason to change.

When we look into layered architecture dependencies are always pointed downwards so if we did some changes in the persistence layer it may affect the business layer. (Refer figure 1).

But in clean architecture with dependency inversion all the dependencies are pointed inwards means the persistence layer depends on the domain but not the other way around. So any change that happens to the persistence layer does not affect business.


Repository Example


Here is the simple Spring boot code implementation of Clean Architecture.

Conclusion 

Now we can begin a project with the least amount of information we have about the system we are building. We should not need to worry about the framework or the database. With Clean Architecture, we can start a software project with domain-driven design and we can easily decouple our business logic from the infrastructure. Also, It was very easy to change the implementation when the project grows and we are ready for future requirements.

With dependency inversion, the written code is very easy to test because we can test domain logic without any dependency on the framework or database. External parts of the project become obsolete so we can replace those obsolete parts without any impact on the business logic.

Reference


Thursday, August 29, 2019

Resolve "sqlcmd: command not found" error Ubuntu command line



Even after installing SQL Server on Ubuntu you can’t run sqlcmd commands in Ubuntu without installing mssql-tools

First of all, make sure that mssql-tools installed. If you are not sure you can simply try to install Using following command 

$ sudo apt-get install mssql-tools


if mssql-tools already installed it will show the following 


Reading package lists... Done
Building dependency tree       
Reading state information... Done
mssql-tools is already the newest version (17.4.1.1-1).


If it not install command will install the mssql-tools into your ubuntu machine 


Even after install mssql-tools, if you get "sqlcmd: command not found" error it because you have no proper symlinks created in /user/bin directory.


Check you have sqlcmd in /opt/mssql-tools/bin/ directory 
run following command 

$ sudo ls /opt/mssql-tools/bin/sqlcmd*

After you get the name of the tool you can create a symlink by following command

$ sudo ln -sfn /opt/mssql-tools/bin/sqlcmd /usr/bin/sqlcmd

Wednesday, February 13, 2019

Sending emails via Spring boot application

Here I am going to discuss how we can send email from Spring application which is recently used scenario in software development. Here I am going to use org.springframework.mail package which provided by the spring framework to support for the mails. There are interfaces and classes for java mail support in spring framework.


  1. MailSender interface: It is the root interface. It provides basic functionality for sending simple emails.
  2. JavaMailSender interface: It is the subinterface of MailSender. It supports MIME messages. It is mostly used with MimeMessageHelper class for the creation of JavaMail MimeMessage, with attachment, etc. The spring framework recommends MimeMessagePreparator mechanism for using this interface.
  3. JavaMailSenderImpl class: It provides the implementation of JavaMailSender interface. It supports JavaMail MimeMessages and Spring SimpleMailMessages.
  4. SimpleMailMessage class: It is used to create a simple mail message including from, to, cc, subject and text messages.
  5. MimeMessagePreparator interface: It is the callback interface for the preparation of JavaMail MIME messages.
  6. MimeMessageHelper class: It is the helper class for creating a MIME message. It offers support for inline elements such as images, typical mail attachments, and HTML text content.

Here to send email message, I used JavaMailSender interface.

First, you have to create a simple maven project. Following is my sample project structure for your reference





Step 1 - Update Maven dependency

As first step developer need to update the pom.xml with the maven dependencies for Java Mail. For that, you can declare spring-boot-starter-mail. This will pull the dependency for your application. 

following is my sample POM file with all dependencies 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com</groupId> <artifactId>email</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>email</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- dependancy for Java mail --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.0</version> </plugin> </plugins> </build> </project>

Step 2 - Create application.property file The developer needs to add application.properties file into src/main/resources folder. In this file, the developer is creating a number of properties in a single file to run the application. Following are the properties need to send email from the application



  1. Host
  2. port
  3. username
  4. password
  5. javaMailProperties

aplication.properties

logging.level.org.springframework.mail=DEBUG spring.mail.host=smtp.gmail.com spring.mail.port=587 spring.mail.username=<Email for send mail> spring.mail.password=<Password> # javaMailProperties spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.connectiontimeout=5000 spring.mail.properties.mail.smtp.timeout=5000 spring.mail.properties.mail.smtp.writetimeout=5000 spring.mail.properties.mail.smtp.starttls.enable=true

Step 3 - Create a Java class

Then developer need to create java class in src/main/java folder
There are two methods I have implemented one to send mail without attachment and send a mail with an attachment.
In here you can only run one method at a time.
package com.email.service; import java.io.IOException; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.core.io.ClassPathResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; @SpringBootApplication public class MailService implements CommandLineRunner {

@Autowired private JavaMailSender javaMailSender; public static void main(String[] args) { SpringApplication.run(MailService.class, args); } @Override public void run(String... args) throws MessagingException,IOException { System.out.println("Sending Email...!"); //sendEmailWithoutAttachment(); sendEmailWithAttachment(); System.out.println("Emai Sent...!"); } void sendEmailWithoutAttachment() { SimpleMailMessage message = new SimpleMailMessage(); message.setTo("sample@email");// Recivers email message.setSubject("Testing from Spring Boot"); message.setText("Hello World \n Spring Boot Email"); javaMailSender.send(message); } void sendEmailWithAttachment() throws MessagingException, IOException { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setTo("sample@mail");// Receivers mail helper.setSubject("Testing from Spring Boot"); helper.setText("<B>Image attached in the email..!</B>", true); helper.addAttachment("Spring.png", new ClassPathResource("ImageToUpload.png")); javaMailSender.send(message); } }


If you want to send the same message into multiple emails you can simply add the multiple receiver's addresses by comma separating each.

Gotcha...
if you use Gmail as sender's mail even though you have done everything correctly you may not able to run the application correctly. You might get the following error once you run the application.


 Caused by: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted.

This happens because the sender's mail should turn on the Allow less secure apps in your google account.

How to enable Allow less secure apps on Gmail
  • Log in to google account from here 
  • Navigate to Security tab from the left side menu 
  • Find Less secure app access section in the right side

  • Now you will navigate to the page where you can turn on Allow less secure apps: ON toggle button

Now you will be able to run the application without error.
Very simple sample project you can find from the following URL
https://github.com/ikalani/springboot-email-sample

Reference https://www.javatpoint.com/spring-java-mail-tutorialab