Financial services

Extending our example of a credit scoring application, we have to add a new microservice named FinancialServices. In Chapter 2, Defining Microservice Components, we created a UserServices microservice. That service is suppose to store the user's personal details along with addresses. In this chapter, we will learn about financial microservices which are supposed to store the financial details of users, which include bank account details and the user's financial obligations. The table structure of this microservice is as follows:

CREATE TABLE `bank_account_details` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
   `user_id` char(36) NOT NULL, 
  `bank_name` varchar(100) DEFAULT NULL, 
  `account_number` varchar(20) NOT NULL, 
  `account_holders_name` varchar(250) NOT NULL, 
  `fsc` varchar(20) DEFAULT NULL, 
  `account_type` int(11) DEFAULT NULL, 
  `created_on` datetime(6) NOT NULL, 
  `deleted_on` datetime(6) DEFAULT NULL, 
  PRIMARY KEY (`Id`) 
) ENGINE=InnoDB  DEFAULT CHARSET=latin1; 
 
CREATE TABLE `obligations_details` ( 
  `id` int(11) NOT NULL AUTO_INCREMENT, 
  `user_id` char(36) NOT NULL, 
  `total_monthly_spending` decimal(10,0) NOT NULL, 
  `monthly_income_supports` decimal(10,0) NOT NULL, 
  `monthly_emi_payout` decimal(10,0) NOT NULL, 
  `created_on` datetime(6) NOT NULL, 
  `deleted_on` datetime(6) DEFAULT NULL, 
  PRIMARY KEY (`Id`), 
  KEY `Obligations_user_id` (`user_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Boot strap properties files will contain two properties in it:

spring.application.name=financialService 
spring.cloud.config.uri=http://localhost:8888 

Also we have to create financialService.properties inside the configServer code at location:

server.port=8090
Connect.database=financialDetails
spring.datasource.url=jdbc:mysql://localhost:3306/financialDetails
spring.datasource.username=xxxxxx
spring.datasource.password=xxxxxxxx
# optional Properties
spring.jpa.show-sql = true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy

The creation of this application is the same as the UserService application. You have to download the templated code from start.spring.io. Use the application name as FinancialServiceApplication while creating a project on start.spring.io and hit the generate button and download the code. The main application file will look pretty much similar to the user service application:

package com.practicalMicroservcies; 
 
import org.flywaydb.core.Flyway; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.Bean; 
 
@SpringBootApplication 
public class FinancialServiceApplication { 
    @Value("${spring.datasource.url}") 
    private String url; 
    @Value("${spring.datasource.username}") 
    private String userName; 
    @Value("${spring.datasource.password}") 
    private String password; 
    @Value("${Connect.database}") 
    private String database; 
 
    @Bean(initMethod = "migrate") 
    public Flyway flyway() { 
        String urlWithoutDatabaseName= 
url.substring(0,url.lastIndexOf("/")); Flyway flyway = new Flyway(); flyway.setDataSource(urlWithoutDatabaseName, userName,
password); flyway.setSchemas(database); flyway.setBaselineOnMigrate(true); return flyway; } public static void main(String[] args) { SpringApplication.run(FinancialServiceApplication.class, args); } }

As we have two tables in this, we will have two entity tables: bank account details and obligation details. The code in these files will look like this:

@Entity 
@Table(name = "bank_account_details") 
public class BankAccountDetail implements Serializable { 
 
    
    private static final long serialVersionUID = 4804278804874617196L; 
 
 
 
    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "id") 
    private int id; 
 
    /** 
     * User Id , unique for every user 
     */ 
 
    @Column(name = "user_id", nullable = false, unique = true, length = 
36) private String userId; /** * Bank Name of User */ @Column(name = "bank_name", nullable = false, length = 100) private String bankName; /** * Account number of User */ @Column(name = "account_number", nullable = false, unique = true,
length = 20) private String accountNumber; /** * Account holder Name of account */ @Column(name = "account_holders_name", nullable = false, length =
250) private String accountHolderName; /** * Any National Financial system code of bank */ @Column(name = "fsc", nullable = false, length = 20) private String fsc; /** * Account Type of user */ @Column(name = "account_type", nullable = false) private Integer accountType; /** * Date on which Entry is created */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "created_on", columnDefinition = "TIMESTAMP DEFAULT
CURRENT_TIMESTAMP") private Date createdOn = new Date(); /** * Date on which Entry is deleted. */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "deleted_on", columnDefinition = "TIMESTAMP DEFAULT
NULL") private Date deletedOn; }

Next, the entity class, obligation entity, which should be storing the user's financial obligation, and will be look like the following:

@Entity 
@Table(name = "obligations_details") 
public class ObligationDetails implements Serializable { 
 
    /** 
     *  
     */ 
    private static final long serialVersionUID = -7123033147694699766L; 
 
    /** 
     * unique Id for each record. 
     */ 
 
    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "id") 
    private int id; 
 
    /** 
     * User Id , unique for every user 
     */ 
 
    @Column(name = "user_id", nullable = false, unique = true, length = 
36) private String userId; /** * Totally monthly income , may be from himself or wife (combined) */ @Column(name = "monthly_income_supports", nullable = false) private BigDecimal monthlyIncome; /** * Monthly Emi to payout */ @Column(name = "monthly_emi_payout", nullable = false) private BigDecimal monthlyemi; /** * totally month spending */ @Column(name = "total_monthly_spending", nullable = false) private BigDecimal monthlySpending; /** * Date on which Entry is created */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "created_on", columnDefinition = "TIMESTAMP DEFAULT
CURRENT_TIMESTAMP") private Date createdOn = new Date();; /** * Date on which Entry is deleted. */ @Temporal(TemporalType.TIMESTAMP) @Column(name = "deleted_on", columnDefinition = "TIMESTAMP DEFAULT
NULL") private Date deletedOn; }

It should include setter and getter methods for class properties.

And can override the toString method:

    @Override 
    public String toString() { 
        return "ObligationDetails [userId=" + userId + ", 
monthlyIncome=" + monthlyIncome + ", monthlyemi=" + monthlyemi + ", monthlySpending=" + monthlySpending + ", createdOn=" +
createdOn + ", deletedOn=" + deletedOn + "]"; }

In our user service, we will have repositories for both the entities (bank account details and obligation details):

package com.practicalMicroservcies.repo;
import org.springframework.data.jpa.repository.JpaRepository; import com.practicalMicroservcies.entity.BankAccountDetail; public interface BankAccountDetailRepository extends JpaRepository<BankAccountDetail, Integer> { BankAccountDetail findByUserId(String userId); }

And obligation repositories:

 
package com.practicalMicroservcies.repo; 
 
import org.springframework.data.jpa.repository.JpaRepository; 
 
import com.practicalMicroservcies.entity.BankAccountDetail; 
import com.practicalMicroservcies.entity.ObligationDetails; 
 
public interface ObligationRepository extends JpaRepository<ObligationDetails, Integer> { 
     
    ObligationDetails findByUserId(String userId); 
} 

There will be one service class named FinancialServices to handle queries from both repositories:

@Service 
@Transactional 
public class FinancialServices { 
 
    @Resource 
    BankAccountDetailRepository accountDetailRepo; 
 
    @Resource 
    ObligationRepository obligationRepo;

The following method is used to store the bank account details of the user:

  
    public void saveAccountDetail(BankAccountDetail accountDetail) { 
        accountDetailRepo.save(accountDetail); 
        System.out.println("AccountDetails Saved!"); 

    } 
 
    public void saveObligation(ObligationDetails obligationDetails) { 
        obligationRepo.save(obligationDetails); 
        System.out.println("Obligation Details Saved!"); 
 
    }  

We need a method to fetch the bank account details and obligations from the database based on the userId provided. The following are two methods in the service class, to do the get data job for us:

    public ObligationDetails getObligationDetail(UUID userId) { 
        ObligationDetails returnAddressObject = 
obligationRepo.findByUserId(userId.toString()); return returnAddressObject; } public BankAccountDetail getAccountDetail(UUID userId) { BankAccountDetail userObjectToRetrun =
accountDetailRepo.findByUserId(userId.toString()); return userObjectToRetrun; }

The following is the method to delete the financial details of the user. This method doesn't actually delete the data from the database. Rather it just marks the data as deleted. Any data destruction statement should be avoided for the database as much as possible.

    public void deleteFinancialDetail(UUID userId) { 
        BankAccountDetail accountObject = 
accountDetailRepo.findByUserId(userId.toString()); accountObject.setDeletedOn(new Date()); accountDetailRepo.saveAndFlush(accountObject); ObligationDetails obligationObject =
obligationRepo.findByUserId(userId.toString()); obligationObject.setDeletedOn(new Date()); obligationRepo.saveAndFlush(obligationObject); } }

The controller will look like as follows:

@RestController 
@RequestMapping("/PM/finance/") 
public class FinancialController { 
    private static final Logger logger = Logger.getLogger(FinancialController.class); 
 
    @Resource 
    FinancialServices financialService; 
 
    @Resource 
    ObjectMapper mapper; 
    /** 
     * Method is responsible for adding new AccountDetails. 
     *  
     * @param address 
     * @param userId 
     * @return 
     */ 
    public static final String addAccountDetails = 
"addAccountDetails(): "; @RequestMapping(method = RequestMethod.POST, value = "
{userId}/account", produces = "application/json", consumes =
"application/json") public ResponseEntity<String> addAccountDetails(@RequestBody
BankAccountDetail accountDetail, @PathVariable("userId") UUID
userId) { logger.debug(addAccountDetails + " Account for user Id " +
userId + " is creating."); accountDetail.setUserId(userId.toString()); financialService.saveAccountDetail(accountDetail); return new ResponseEntity<>(HttpStatus.CREATED); } /** * Method is responsible for creating a obligation Details. * * @param userDetail * @param userId * @return */ public static final String addObligationDetails =
"addObligationDetails(): "; @RequestMapping(method = RequestMethod.POST, value = "
{userId}/obligation", produces = "application/json", consumes =
"application/json") public ResponseEntity<String> addObligationDetails(@RequestBody
ObligationDetails obligationDetails, @PathVariable("userId") UUID
userId) { logger.debug(addObligationDetails + " Creating user's
obligation with Id " + userId + " and details : " +
obligationDetails); obligationDetails.setUserId(userId.toString()); financialService.saveObligation(obligationDetails); return new ResponseEntity<>(HttpStatus.CREATED); } /** * Deleting Financial Detail of user * @param userDetail * @param userId * @return */ public static final String deleteFinancialDetails =
"deleteFinancialDetails(): "; @RequestMapping(method = RequestMethod.DELETE, value = "{userId}",
produces = "application/json", consumes = "application/json") public ResponseEntity<String> deleteFinancialDetails(
@PathVariable("userId") UUID userId) { logger.debug(deleteFinancialDetails + " deleting user with Id "
+ userId); financialService.deleteFinancialDetail(userId); return new ResponseEntity<>(HttpStatus.CREATED); } /** * Method is responsible for getting the account detail for given ID. * * @param userId * @return */ public static final String getAccountDetails =
"getAccountDetails(): "; @RequestMapping(method = RequestMethod.GET, value = "
{userId}/account", produces = "application/json", consumes =
"application/json") public ResponseEntity<BankAccountDetail>
getAccountDetails(@PathVariable("userId") UUID userId) { logger.debug(getAccountDetails + " getting information for
userId " + userId); BankAccountDetail objectToReturn =
financialService.getAccountDetail(userId); if (objectToReturn == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); else return new ResponseEntity<>(objectToReturn, HttpStatus.OK); } /** * Method is responsible getting the Obligation Detail. * @param userId * @return */ public static final String getObligationDetails =
"getObligationDetails(): "; @RequestMapping(method = RequestMethod.GET, value = "
{userId}/obligation", produces = "application/json", consumes =
"application/json") public ResponseEntity<ObligationDetails>
getObligationDetails(@PathVariable("userId") UUID userId) { logger.debug(getObligationDetails + " getting Obligation
Details for user Id: " + userId); ObligationDetails objectToReturn =
financialService.getObligationDetail(userId); if (objectToReturn == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); else return new ResponseEntity<>(objectToReturn, HttpStatus.OK); }
}

This completes the code of financial microservices. The endpoint URL for this will be as follows.

For creating the obligation, the endpoint will be:

POST  http://localhost:8090/PM/finance/<user Id>/obligation  

An example of this URL will be as follows:

POST  http://localhost:8090/PM/finance/93a52ce4-9331-43b5-8b56-09bd62cb0444/obligation  

For creating the bank account details, the endpoint will be:

POST http://localhost:8090/PM/finance/<user Id>account  

An example of this URL will be as follows:

POST http://localhost:8090/PM/finance/93a52ce4-9331-43b5-8b56-09bd62cb0444/account  

If we make the GET request of the same endpoint, then it will fetch the details of the user from the database and send it back as JSON. For instance if we want to know the obligation for any user, hit the GET request to the endpoint mentioned above like:

GET http://localhost:8090/PM/finance/93a52ce4-9331-43b5-8b56-09bd62cb0444/obligation  

The response would be a JSON something like the following service:

{
"id": 1, "user_id":"3a52ce4-9331-43b5-8b56-09bd62cb0444", "monthlyIncome":150000, "monthlyemi":50000, "monthlySpending":50000, "createdOn":"1483209000000", "deletedOn":null }

This service helps store the financial information of users. It consists of two tables: one to store the bank detail information of the users and the second table to store monthly income, household spending, monthly EMI spending, and so on. All these decisions will help us in creating the credit scoring microservice. In the same way, there is another microservice called employment microservice. This stores information regarding employment details such as salaried or self-employed, who is the current employer, and the employee's current salary. The implementation of this service is very similar to what we already have, so I'm leaving it to the readers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset