JLUPIN PLATFORM WEBSITE
tutorials
  • Rating:
  • Views: 31
  • Author: JLupin
  • Skill level: medium
  • Comments: 0

This tutorial shows how to create new project with JLupin Platform IntelliJ Plugin 2.0.2 and JLupin Platform 1.5.0.3. The project will be the same as the one in chapter 3 about microservices communication. Maven will be also used for this project.

Requirements

To complete this tutorial you should download zip with JLupin Platform version 1.5.0.3 and JLupin Platform IntelliJ Plugin 2.0.2. They can be downloaded from our download section here.

Installation

To install plugin at first got to plugins configuration page (main screen of IntelliJ -> Configure -> Plugins).

Then in the bottom of the window click button Browse repositories....

Now enter JLupin name in search box at the top. Then from the list select JLupin Platform IntelliJ Plugin and choose to install it.

Restart IntelliJ IDE to make changes applied. After that your editor with plugin will be ready to use.

Creating new project

Select Create New Project.

New window will open with project type to choose. Select JLupin Platform from the list on the left side of the window. Then in the center select proper JDK (we recommend 1.8) and choose proper JLupin Platform project type. For this tutorial it is Three layer project. That means that generated project structure will support three layers: access, business-logic and data. Each layer with has one microservice to show you how to manage microservice's dependencies. The second option Standard project does not have any constraints for project architecture, you can create any architecture you want with support for native and servlet microservices as well.

The next step is to provide some project details. For this tutorial server will be embedded inside project (server binaries will be included inside project directory). Select check box next to Embed server in project and then provide path to platform you have downloaded (use button with three dots next to input). As a Group id for this tutorial type in com.example.exchange. Group id is used for Maven configuration files, but also for creating main package inside modules. You can leave Artifact version as it is.

Next three steps are for providing microservice names for each layer. The first is access layer, type in exchange and click Add button.

Next one is business logic layer, type in currency-converter and click Add button.

The last one is data layer, type in exchange-rates and click Add button.

Last one is standard IntelliJ IDE step. You provide here where to create your project. When you done click Finish button.

Now wait a moment. IntelliJ will be generating your project and indexing created files. This can take up to few minutes, so be patient!

Generated structure

When project is ready to use you should see generated structure inside project files tab.

common-pojo and common-util

This two modules are created to contain shared classes for all microservices. Standard package structure is created for each.

Access Layer

Access layer contains microservices which are available for external access. They serve web pages, services, etc. You can transform data here, authorize users and more. Microservices created inside access layer are servlet type. That means it only has implementation module and additional-files directory. This type of microservice is using servlet container for exposing its functionality (Spring Boot is used under the hood).

additional-files

For servlet type microservices three files are created. First is microservice configuration file called servlet_configuration.yml.

The log4j2.xml file is for JLupin system and Spring container logging configuration.

implementation

Implementation contains generated starter class for Spring Boot application. Also Spring container configuration file is generated to make it easier to configure communication between microservices.

The log4j2.xml file is located in resources and used for configuring Spring Boot logging.

Business Logic Layer

Business logic layer should contain all algorithms implementation and your application logic. They use Spring container to allow communication between created services and to support other useful Spring features. This layer contains native type microservices. Three directories are created automatically: interfaces, implementation and additional-files.

additional-files

For native microservice two files are created here. The configuration.yml is a microservice configuration file for JLupin. Inside it has set proper canonical name of application context producer class which is created inside implementation module. The log4j2.xml similarly to servlet microservice is responsible for JLupin system and Spring container logging configuration.

implementation

This is main microservice module. All implementation and configuration goes here. By default SpringConfiguration and JLupinConfiguration are created. These are standard files you should create for every module.

interfaces

By default nothing is generated here beside proper package structure. This is a place where all interfaces for externally enabled services are located. This way you can add this module as a dependency to other projects and hide your implementation from the others.

Data Layer

Data layer should contain all classes for communication with persistent systems like databases. It is the best place for DAO implementations. All operations here should be atomic. Structure is the same as for business logic layer. This is because microservices in this layer are also native type.

additional-files

For native microservice two files are created here. The configuration.yml is a microservice configuration file for JLupin. Inside it has set proper name of application context producer class which is created inside implementation module. The log4j2.xml similarly to servlet microservice is responsible for JLupin system and Spring container logging configuration.

implementation

This is main microservice module. All implementation and configuration goes here. By SpringConfiguration and JLupinConfiguration are created. These are standard files you should create for every module.

interfaces

By default nothing is generated here beside proper package structure. This is a place where all interfaces for externally enabled services are located. This way you can add as a dependency this module to other projects and hide your implementation from the others.

Integration test

This module contains generated classes for calling native microservices through running JLupin Platform. Base test class is generated with simple delegators configured for calls to server running on localhost (you can change it here).

Server

Here are platform binaries. Nothing more.

Implementation

As was said before this application will be same as the one in previous chapter. So now we need to add same implementation. Let's start.

common-pojo

Create Currency enum here.

package com.example.exchange.common.pojo;

public enum Currency {
    EUR, USD, GBP
}

exchange-rates

Create ExchangeRatesService for exchange-rates microservice. Without plugin you have to create two classes in different modules and then add proper annotations for them and add service's name for remotely enabled bean list. With IntelliJ plugin you can do it with few simple clicks. So now click with right mouse button on implementation module and select New Service.

When popup opens type in your service name (ExchangeRatesService) and click Ok. You can type ExchangeRates without Service suffix. If it is not found plugin will add it by itself. Plugin should create interface and implementation files, configure them and add your service name to remotely enabled bean list. Now add only classes' body.

package com.example.exchange.service.interfaces;

import com.example.exchange.common.pojo.Currency;

import java.math.BigDecimal;

public interface ExchangeRatesService {
    BigDecimal getRate(Currency from, Currency to);
}
package com.example.exchange.service.impl;

import com.example.exchange.common.pojo.Currency;
import com.example.exchange.service.interfaces.ExchangeRatesService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service("exchangeRatesService")
public class ExchangeRatesServiceImpl implements ExchangeRatesService {
    private Map<Pair, BigDecimal> rates;

    public ExchangeRatesServiceImpl() {
        rates = new HashMap<>();
        initRates();
    }

    private void initRates() {
        rates.put(new Pair(Currency.USD, Currency.EUR), BigDecimal.valueOf(0.89389));
        rates.put(new Pair(Currency.EUR, Currency.USD), BigDecimal.valueOf(1.11871));
        rates.put(new Pair(Currency.USD, Currency.GBP), BigDecimal.valueOf(0.78139));
        rates.put(new Pair(Currency.GBP, Currency.USD), BigDecimal.valueOf(1.27978));
        rates.put(new Pair(Currency.EUR, Currency.GBP), BigDecimal.valueOf(0.87416));
        rates.put(new Pair(Currency.GBP, Currency.EUR), BigDecimal.valueOf(1.14396));
    }

    @Override
    public BigDecimal getRate(Currency from, Currency to) {
        return rates.get(new Pair(from, to));
    }

    private class Pair {
        private Currency from;
        private Currency to;

        Pair(Currency from, Currency to) {
            this.from = from;
            this.to = to;
        }

        public Currency getFrom() {
            return from;
        }

        public Currency getTo() {
            return to;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair pair = (Pair) o;
            if (from != pair.from) return false;
            return to == pair.to;
        }

        @Override
        public int hashCode() {
            int result = from.hashCode();
            result = 31 * result + to.hashCode();
            return result;
        }
    }
}

currency-converter

This microservice will call exchange-rates. That's why we need to add bean to Spring configuration which will be a stub for remote microservice calling. Update CurrencyConverterSpringConfiguration class and add methods:

@Bean(name = "exchangeRatesService")
public ExchangeRatesService getExchangeRatesService() {
    return JLupinClientUtil.generateRemote(getJLupinDelegator(), "exchange-rates", ExchangeRatesService.class);
}

Create CurrencyConverterService for currency-converter microservice. Again click right mouse button on implementation module and select New Service.

Enter service name (CurrencyConverterService) and put implementation.

package com.example.exchange.service.interfaces;

import com.example.exchange.common.pojo.Currency;

import java.math.BigDecimal;

public interface CurrencyConverterService {
    BigDecimal convert(BigDecimal value, Currency from, Currency to);
}
package com.example.exchange.service.impl;

import com.example.exchange.common.pojo.Currency;
import com.example.exchange.service.interfaces.CurrencyConverterService;
import com.example.exchange.service.interfaces.ExchangeRatesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Service("currencyConverterService")
public class CurrencyConverterServiceImpl implements CurrencyConverterService {
    @Autowired
    private ExchangeRatesService exchangeRatesService;

    @Override
    public BigDecimal convert(BigDecimal value, Currency from, Currency to) {
        final BigDecimal rate = exchangeRatesService.getRate(from, to);
        return rate != null ? value.multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP) : null;
    }
}

exchange

This microservice will call currency-converter. That's why we need to add bean to Spring configuration which will be a stub for remote microservice calling. Update ExchangeSpringConfiguration class and add methods:

@Bean(name = "currencyConverterService")
public CurrencyConverterService getCurrencyConverterService() {
    return JLupinClientUtil.generateRemote(getJLupinDelegator(), "currency-converter", CurrencyConverterService.class);
}

We are going to add REST controller now. It will be called ExchangeController. But first create new package for it to have same structure like below:

+--com
   |
   +--example
      |
      +--exchange
         |
         +--configuration
         |
         +--controller
            |
            +--exchange
               |
               +--in
               |
               +--out

Packages in and out should contain data transfer objects definition for input and output. Create these objects and controller.

package com.example.exchange.controller.exchange.in;

import com.example.exchange.common.pojo.Currency;

import java.math.BigDecimal;

public class ConvertIn {
    private BigDecimal value;
    private Currency currency;

    public BigDecimal getValue() {
        return value;
    }

    public void setValue(BigDecimal value) {
        this.value = value;
    }

    public Currency getCurrency() {
        return currency;
    }

    public void setCurrency(Currency currency) {
        this.currency = currency;
    }
}
package com.example.exchange.controller.exchange.out;

import com.example.exchange.common.pojo.Currency;

import java.math.BigDecimal;

public class ConvertOut {
    private BigDecimal value;
    private Currency currency;

    public BigDecimal getValue() {
        return value;
    }

    public void setValue(BigDecimal value) {
        this.value = value;
    }

    public Currency getCurrency() {
        return currency;
    }

    public void setCurrency(Currency currency) {
        this.currency = currency;
    }
}
package com.example.exchange.controller.exchange;

import com.example.exchange.common.pojo.Currency;
import com.example.exchange.controller.exchange.in.ConvertIn;
import com.example.exchange.controller.exchange.out.ConvertOut;
import com.example.exchange.service.interfaces.CurrencyConverterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.LinkedList;
import java.util.List;

@RestController
public class ExchangeController {
    @Autowired
    private CurrencyConverterService currencyConverterService;

    @CrossOrigin
    @PostMapping("/convert")
    public List<ConvertOut> convert(@RequestBody ConvertIn in) {
        List<ConvertOut> result = new LinkedList<ConvertOut>();

        for (final Currency currency : Currency.values()) {
            final ConvertOut out = new ConvertOut();
            out.setCurrency(currency);
            if (currency.equals(in.getCurrency())) {
                out.setValue(in.getValue());
            } else {
                out.setValue(currencyConverterService.convert(in.getValue(), in.getCurrency(), currency));
            }
            result.add(out);
        }

        return result;
    }
}

And that's all. Everything is ready for deployment now.

Run configurations

The simplest way to deploy applications is to create proper run configurations. To do so select option to configure run configurations from dropdown menu.

Then add new run configuration called JLupin Platform.

Change it name to Platform. You can leave log level set to INFO.

Next add deployer configurations. Select from list JLupin Platform Microservice Deployer.

Set its name to exchange-rates and from dropdown select exchange-rates-data-implementation module.

Do the same for the rest of microservices and select Ok. Then select server from dropdown and click green arrow next to it.

When platform is started select microservice from the list and start it one by one. Same way as you started server. Proper Maven command will be run under the hood. You should see maven output on IntelliJ console. For actual deploy jlupin-platform-maven-plugin is used (configured inside project pom.xml).

Manual test

When all microservices are deployed you should be able to check if your service run properly. You can use Postman or curl to check your service:

curl -X POST http://localhost:8000/exchange/convert -H 'content-type: application/json' -d '{"value": 1.23, "currency": "USD"}'
[{"value":1.10,"currency":"EUR"},{"value":1.23,"currency":"USD"},{"value":0.96,"currency":"GBP"}]

If you see the result everything works as expected. As you can see with plugin help creation of microservice was much more simple than creating all your pom and configuration files by yourself.

Done tutorial

You can download project which is result of making this tutorial from GitHub: https://github.com/jlupin/exchange-project-jlp-1.5.0.3-jlpip-2.0.2

RATE & DISCUSS (0)

No comments found.