
- Rating:
- Views: 539
- Author: JLupin
- Skill level: easy
- Comments: 0
Overview
In this tutorial you will see how to configure your microservice to call other ones. We will create application called exchange. It will convert money you send to other currencies. It will contain three microservices: two native, one servlet. This tutorial will show how to create connections: servlet-native, native-native.
Requirements
To complete this tutorial you will need JLupin Platform version 1.5.0.3. You can download it from here. You should also done two previous tutorials about basic microservice's types and their creation: native, servlet.
Configure project
Create project with three microservices called: exchange-rates (native), currency-converter (native), exchange (servlet). Create also common-pojo project to share pojo classes with all microservices. Maven tool will be used.

Below directory structure is shown:
+--common-pojo | | | +--src | | | | | +--main | | | | | +--java | | | +--pom.xml | +--currency-converter | | | +--additional-files | | | +--implementation | | | | | +--src | | | | | | | +--main | | | | | | | +--java | | | | | +--pom.xml | | | +--interfaces | | | +--src | | | | | +--main | | | | | +--java | | | +--pom.xml | +--exchange | | | +--additional-files | | | +--implementation | | | +--src | | | | | +--main | | | | | +--java | | | | | +--resources | | | +--pom.xml | +--exchange-rates | | | +--additional-files | | | +--implementation | | | | | +--src | | | | | | | +--main | | | | | | | +--java | | | | | +--pom.xml | | | +--interfaces | | | +--src | | | | | +--main | | | | | +--java | | | +--pom.xml | +--pom.xml
Now configure all pom.xml files. Their content is shown below.
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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.example.exchange</groupId> <artifactId>exchange-project</artifactId> <packaging>pom</packaging> <version>1.0.0</version> <repositories> <!-- Repository is also accessible using https connection: --> <!-- https://support.jlupin.com/maven2/ --> <repository> <id>jlupin-central</id> <name>jlupin</name> <url>http://support.jlupin.com/maven2/</url> </repository> </repositories> <pluginRepositories> <!-- Repository is also accessible using https connection: --> <!-- https://support.jlupin.com/maven2/ --> <pluginRepository> <id>jlupin-central</id> <name>jlupin</name> <url>http://support.jlupin.com/maven2/</url> </pluginRepository> </pluginRepositories> <modules> <module>common-pojo</module> <module>currency-converter/interfaces</module> <module>currency-converter/implementation</module> <module>exchange/implementation</module> <module>exchange-rates/interfaces</module> <module>exchange-rates/implementation</module> </modules> <properties> <jlupin.platform.client.version>1.5.0.3</jlupin.platform.client.version> <jlupin.platform.maven.plugin.version>1.5.0.0</jlupin.platform.maven.plugin.version> <jlupin.skipDeploy>true</jlupin.skipDeploy> <maven.surefire.skipTests>false</maven.surefire.skipTests> <spring.context.version>5.0.8.RELEASE</spring.context.version> <slf4j.version>1.8.0-alpha2</slf4j.version> <log4j.slf4j.bridge.version>2.11.0</log4j.slf4j.bridge.version> <maven.failsafe.plugin.version>2.20</maven.failsafe.plugin.version> <maven.surefire.plugin.version>2.20</maven.surefire.plugin.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${maven.surefire.plugin.version}</version> <configuration> <skipTests>${maven.surefire.skipTests}</skipTests> </configuration> </plugin> </plugins> <pluginManagement> <plugins> <plugin> <groupId>com.jlupin</groupId> <artifactId>jlupin-platform-maven-plugin</artifactId> <version>${jlupin.platform.maven.plugin.version}</version> <executions> <execution> <id>jlupin-zip</id> <goals> <goal>zip</goal> </goals> <configuration> <additionalFilesDirectories> <param>../additional-files</param> </additionalFilesDirectories> </configuration> </execution> <execution> <id>jlupin-deploy</id> <phase>pre-integration-test</phase> <goals> <goal>deploy</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>${maven.failsafe.plugin.version}</version> <executions> <execution> <id>integration-test</id> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <includes> <include>**/Test*.java</include> <include>**/*Test.java</include> <include>**/*Tests.java</include> <include>**/*TestCase.java</include> </includes> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>
common-pojo/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <artifactId>exchange-project</artifactId> <groupId>com.example.exchange</groupId> <version>1.0.0</version> <relativePath>./../pom.xml</relativePath> </parent> <artifactId>common-pojo</artifactId> </project>
currency-converter/implementation/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <artifactId>exchange-project</artifactId> <groupId>com.example.exchange</groupId> <version>1.0.0</version> <relativePath>./../../pom.xml</relativePath> </parent> <name>currency-converter</name> <artifactId>currency-converter-implementation</artifactId> <properties> <jlupin.skipDeploy>false</jlupin.skipDeploy> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.context.version}</version> </dependency> <dependency> <groupId>com.example.exchange</groupId> <artifactId>currency-converter-interfaces</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.example.exchange</groupId> <artifactId>common-pojo</artifactId> <version>1.0.0</version> </dependency> <!-- JLupin dependencies --> <dependency> <groupId>com.jlupin</groupId> <artifactId>jlupin-client-assembly</artifactId> <version>${jlupin.platform.client.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j.slf4j.bridge.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.jlupin</groupId> <artifactId>jlupin-platform-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
currency-converter/interfaces/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <artifactId>exchange-project</artifactId> <groupId>com.example.exchange</groupId> <version>1.0.0</version> <relativePath>./../../pom.xml</relativePath> </parent> <artifactId>currency-converter-interfaces</artifactId> <dependencies> <dependency> <groupId>com.example.exchange</groupId> <artifactId>common-pojo</artifactId> <version>1.0.0</version> </dependency> </dependencies> </project>
exchange/implementation/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> </parent> <name>exchange</name> <groupId>com.example.exchange</groupId> <artifactId>exchange-implementation</artifactId> <packaging>war</packaging> <version>1.0.0</version> <repositories> <!-- Repository is also accessible using https connection: --> <!-- https://support.jlupin.com/maven2/ --> <repository> <id>jlupin-central</id> <name>jlupin</name> <url>http://support.jlupin.com/maven2/</url> </repository> </repositories> <pluginRepositories> <!-- Repository is also accessible using https connection: --> <!-- https://support.jlupin.com/maven2/ --> <pluginRepository> <id>jlupin-central</id> <name>jlupin</name> <url>http://support.jlupin.com/maven2/</url> </pluginRepository> </pluginRepositories> <properties> <jlupin.platform.client.version>1.5.0.3</jlupin.platform.client.version> <jlupin.platform.maven.plugin.version>1.5.0.0</jlupin.platform.maven.plugin.version> <jlupin.servlet.monitor.version>1.5.0.0</jlupin.servlet.monitor.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- JLupin dependencies --> <dependency> <groupId>com.jlupin</groupId> <artifactId>jlupin-client-assembly</artifactId> <version>${jlupin.platform.client.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.jlupin</groupId> <artifactId>jlupin-spring-boot-2-servlet-monitor</artifactId> <version>${jlupin.servlet.monitor.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> </dependencies> <build> <finalName>${project.name}</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>com.jlupin</groupId> <artifactId>jlupin-platform-maven-plugin</artifactId> <version>${jlupin.platform.maven.plugin.version}</version> <executions> <execution> <id>jlupin-zip</id> <goals> <goal>zip</goal> </goals> <configuration> <additionalFilesDirectories> <param>../additional-files</param> </additionalFilesDirectories> <includeDependenciesInZip>false</includeDependenciesInZip> </configuration> </execution> <execution> <id>jlupin-deploy</id> <phase>pre-integration-test</phase> <goals> <goal>deploy</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
exchange-rates/implementation/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <artifactId>exchange-project</artifactId> <groupId>com.example.exchange</groupId> <version>1.0.0</version> <relativePath>./../../pom.xml</relativePath> </parent> <name>exchange-rates</name> <artifactId>exchange-rates-implementation</artifactId> <properties> <jlupin.skipDeploy>false</jlupin.skipDeploy> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.context.version}</version> </dependency> <dependency> <groupId>com.example.exchange</groupId> <artifactId>exchange-rates-interfaces</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.example.exchange</groupId> <artifactId>common-pojo</artifactId> <version>1.0.0</version> </dependency> <!-- JLupin dependencies --> <dependency> <groupId>com.jlupin</groupId> <artifactId>jlupin-client-assembly</artifactId> <version>${jlupin.platform.client.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j.slf4j.bridge.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.jlupin</groupId> <artifactId>jlupin-platform-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
exchange-rates/interfaces/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <artifactId>exchange-project</artifactId> <groupId>com.example.exchange</groupId> <version>1.0.0</version> <relativePath>./../../pom.xml</relativePath> </parent> <artifactId>exchange-rates-interfaces</artifactId> <dependencies> <dependency> <groupId>com.example.exchange</groupId> <artifactId>common-pojo</artifactId> <version>1.0.0</version> </dependency> </dependencies> </project>
If you configure everything you are ready to start adding implementation.
Implementation
At first create suitable package structure. In this tutorial com.example.exchange will be used as main package. Recommended structure (also used by this tutorial) is presented below.
+--common-pojo | | | +--src | | | | | +--main | | | | | +--java | | | | | +--com | | | | | +--example | | | | | +--exchange | | | | | +--pojo | | | +--pom.xml | +--currency-converter | | | +--additional-files | | | +--implementation | | | | | +--src | | | | | | | +--main | | | | | | | +--java | | | | | | | +--com | | | | | | | +--example | | | | | | | +--exchange | | | | | | | +--bean | | | | | | | | | +--impl | | | | | | | | | +--interfaces | | | | | | | | | +--pojo | | | | | | | +--configuration | | | | | | | +--dao | | | | | | | | | +--impl | | | | | | | | | +--interfaces | | | | | | | | | +--pojo | | | | | | | +--service | | | | | | | +--impl | | | | | +--pom.xml | | | +--interfaces | | | +--src | | | | | +--main | | | | | +--java | | | | | +--com | | | | | +--example | | | | | +--exchange | | | | | +--service | | | | | +--interfaces | | | | | +--pojo | | | +--pom.xml | +--exchange | | | +--additional-files | | | +--implementation | | | +--src | | | | | +--main | | | | | +--java | | | | | +--com | | | | | +--example | | | | | +--exchange | | | | | +--configuration | | | | | +--controller | | | +--pom.xml | +--exchange-rates | | | +--additional-files | | | +--implementation | | | | | +--src | | | | | | | +--main | | | | | | | +--java | | | | | | | +--com | | | | | | | +--example | | | | | | | +--exchange | | | | | | | +--bean | | | | | | | | | +--impl | | | | | | | | | +--interfaces | | | | | | | | | +--pojo | | | | | | | +--configuration | | | | | | | +--dao | | | | | | | | | +--impl | | | | | | | | | +--interfaces | | | | | | | | | +--pojo | | | | | | | +--service | | | | | | | +--impl | | | | | +--pom.xml | | | +--interfaces | | | +--src | | | | | +--main | | | | | +--java | | | | | +--com | | | | | +--example | | | | | +--exchange | | | | | +--service | | | | | +--interfaces | | | | | +--pojo | | | +--pom.xml | +--pom.xml
Now add configuration files. They are same as the one in previous tutorial. You can copy them from below:
currency-converter
package com.example.exchange.configuration; import com.jlupin.impl.container.application.spring.JLupinAbstractSpringApplicationContainer; import com.jlupin.interfaces.configuration.microservice.container.application.JLupinAbstractApplicationContainerProducer; import com.jlupin.interfaces.container.application.JLupinApplicationContainer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; public class CurrencyConverterJLupinConfiguration extends JLupinAbstractApplicationContainerProducer { @Override public JLupinApplicationContainer produceJLupinApplicationContainer() { return new JLupinAbstractSpringApplicationContainer() { @Override public AbstractApplicationContext getAbstractApplicationContext() { return new AnnotationConfigApplicationContext(CurrencyConverterSpringConfiguration.class); } }; } }
package com.example.exchange.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; @Configuration @ComponentScan("com.example.exchange") public class CurrencyConverterSpringConfiguration { }
exchange
package com.example.exchange.configuration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan({ "com.example.exchange", "com.jlupin.servlet.monitor.configuration" }) public class ExchangeSpringConfiguration { }
package com.example.exchange; import com.example.exchange.configuration.ExchangeSpringConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootApplicationStarter { public static void main(String[] args) throws Exception { SpringApplication.run(ExchangeSpringConfiguration.class, args); } }
exchange-rates
package com.example.exchange.configuration; import com.jlupin.impl.container.application.spring.JLupinAbstractSpringApplicationContainer; import com.jlupin.interfaces.configuration.microservice.container.application.JLupinAbstractApplicationContainerProducer; import com.jlupin.interfaces.container.application.JLupinApplicationContainer; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.AbstractApplicationContext; public class ExchangeRatesJLupinConfiguration extends JLupinAbstractApplicationContainerProducer { @Override public JLupinApplicationContainer produceJLupinApplicationContainer() { return new JLupinAbstractSpringApplicationContainer() { @Override public AbstractApplicationContext getAbstractApplicationContext() { return new AnnotationConfigApplicationContext(ExchangeRatesSpringConfiguration.class); } }; } }
package com.example.exchange.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; @Configuration @ComponentScan("com.example.exchange") public class ExchangeRatesSpringConfiguration { }
Configuration is done. Let's implement microservices.
common-pojo
We will use common enum with currencies through all microservices. Let's crate it inside common-pojo module.
package com.example.exchange.pojo; public enum Currency { EUR, USD, GBP }
exchange-rates
This microservice will be responsible for returning actual exchange rates. Add interface to interface module and implementation to implementation module.
package com.example.exchange.service.interfaces; import com.example.exchange.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.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; } } }
For this tutorial exchange rates are constant. Remember to enable microservice for remote invocation by modifying configuration file.
package com.example.exchange.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; @Configuration @ComponentScan("com.example.exchange") public class ExchangeRatesSpringConfiguration { @Bean(name = "jLupinRegularExpressionToRemotelyEnabled") public List getRemotelyBeanList() { List<String> list = new ArrayList<>(); list.add("exchangeRatesService"); return list; } }
That's all. Microservice is ready.
currency-converter
This microservice will communicate with exchange-rates microservice. We need to configure it to allow remote calls. Change configuration file to create bean of ExchangeRatesService type which will be proxy object.
package com.example.exchange.configuration; import com.example.exchange.service.interfaces.ExchangeRatesService; import com.jlupin.impl.client.util.JLupinClientUtil; import com.jlupin.interfaces.client.delegator.JLupinDelegator; import com.jlupin.interfaces.common.enums.PortType; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.example.exchange") public class CurrencyConverterSpringConfiguration { @Bean public JLupinDelegator getJLupinDelegator() { return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC); } @Bean(name = "exchangeRatesService") public ExchangeRatesService getExchangeRatesService() { return JLupinClientUtil.generateRemote(getJLupinDelegator(), "exchange-rates", ExchangeRatesService.class); } }
As you can see JLupin Platform gives tool to create proxy object which behaves like normal internal service but invocation is done remotely. And this is all. This few lines allows to autowire ExchangeRatesService.
Now create CurrencyConverterService. Put interface into interfaces module and implementation into implementation module.
package com.example.exchange.service.interfaces; import com.example.exchange.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.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; } }
You can see there how easy is using remote service. From CurrencyConverterServiceImpl point of view it is transparent if bean is local or remote service thanks to Spring Inversion of Control mechanism. Remember to enable microservice for remote invocation by modifying configuration file.
package com.example.exchange.configuration; import com.example.exchange.service.interfaces.ExchangeRatesService; import com.jlupin.impl.client.util.JLupinClientUtil; import com.jlupin.interfaces.client.delegator.JLupinDelegator; import com.jlupin.interfaces.common.enums.PortType; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; @Configuration @ComponentScan("com.example.exchange") public class CurrencyConverterSpringConfiguration { @Bean public JLupinDelegator getJLupinDelegator() { return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC); } @Bean(name = "exchangeRatesService") public ExchangeRatesService getExchangeRatesService() { return JLupinClientUtil.generateRemote(getJLupinDelegator(), "exchange-rates", ExchangeRatesService.class); } @Bean(name = "jLupinRegularExpressionToRemotelyEnabled") public List getRemotelyBeanList() { List<String> list = new ArrayList<>(); list.add("currencyConverterService"); return list; } }
Also update your currency-converter dependencies in pom.xml:
<project> [...] <dependencies> [...] <dependency> <groupId>com.example.exchange</groupId> <artifactId>exchange-rates-interfaces</artifactId> <version>1.0.0</version> </dependency> [...] </dependencies> [...] </project>
Next microservice is done. Now implement the last one.
exchange
This microservice will call currency-converter microservice. We need to configure it to allow communication. To do so edit Spring configuration file.
package com.example.exchange.configuration; import com.example.exchange.service.interfaces.CurrencyConverterService; import com.jlupin.impl.client.util.JLupinClientUtil; import com.jlupin.interfaces.client.delegator.JLupinDelegator; import com.jlupin.interfaces.common.enums.PortType; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan({ "com.example.exchange", "com.jlupin.servlet.monitor.configuration" }) public class ExchangeSpringConfiguration { @Bean public JLupinDelegator getJLupinDelegator() { return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC); } @Bean(name = "currencyConverterService") public CurrencyConverterService getCurrencyConverterService() { return JLupinClientUtil.generateRemote(getJLupinDelegator(), "currency-converter", CurrencyConverterService.class); } }
Also update your currency-converter dependencies in pom.xml:
<project> [...] <dependencies> [...] <dependency> <groupId>com.example.exchange</groupId> <artifactId>currency-converter-interfaces</artifactId> <version>1.0.0</version> </dependency> [...] </dependencies> [...] </project>
Again you can see created bean with type CurrencyConverterService. It can be now autowired in other services. 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.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.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.controller.exchange.in.ConvertIn; import com.example.exchange.controller.exchange.out.ConvertOut; import com.example.exchange.pojo.Currency; 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; } }
Ok, implementation is done. Just add configuration files to proper additional-files directories.
exchange-rates
configuration.yml
SERVERS: JLRMC: #JLupin Remote Method Calls Fast Protocol readTimeout: 480000 isWaitForFinishExecuteAllRequests: true waitToShutdownThreadsOnStop: 60000 backlog: 256 receiveBufferSize: 256 isReuseAddress: false threadPoolSize: 128 isLogPeriodicOnDebug: true isDestroyThreadOnTimeout: false threadExecutingTimeOut: 240000 isStartOnMainServerInitialize: true TRANSMISSION: readTimeout: 480000 isWaitForFinishExecuteAllRequests: false waitToShutdownThreadsOnStop: 60000 backlog: 0 receiveBufferSize: 0 isReuseAddress: false threadPoolSize: 8 isLogPeriodicOnDebug: true isDestroyThreadOnTimeout: false threadExecutingTimeOut: 3600000 isStartOnMainServerInitialize: true QUEUE: readTimeout: 480000 isWaitForFinishExecuteAllRequests: true waitToShutdownThreadsOnStop: 60000 backlog: 256 receiveBufferSize: 256 isReuseAddress: false threadPoolSize: 128 isLogPeriodicOnDebug: true isDestroyThreadOnTimeout: false threadExecutingTimeOut: 240000 isStartOnMainServerInitialize: true ENTRY_POINTS: QUEUE: threadAmount: 128 howOftenCheckingServerInMillis: 5000 repeatsAmount: 4 timeToWaitBetweenRepeatProbeInMillis: 1000 TRANSMISSION: MICROSERVICES_GRANT_ACCESS: MICROSERVICES_LIST: #- microserviceName: 'sampleMicroservice' # serviceName: 'sampleServiceName' # methodName: 'sampleMethodName' #- microserviceName: 'sampleMicroservice2' # serviceName: 'sampleServiceName2' # methodName: 'sampleMethodName2' PROPERTIES: platformVersion: '1.5.0.3' #jvmOptions1: '-Xms128M -Xmx256M -agentlib:jdwp=transport=dt_socket,address=12998,server=y,suspend=n' jvmOptions1: '-Xms128M -Xmx256M' #jvmOptions_2 - default the same as jvmOptions_1 #jvmOptions2: '-Xms128M -Xmx256M' externalPort: '8000' version: '1.0.0' switchDelayTime: 0 connectionSocketTimeoutInMillis: 1000 readTimeoutInMillis: 30000 isKeepAlive: false isOOBInline: false isTcpNoDelay: false isReuseAddress: false sendBufferSize: 0 receiveBufferSize: 0 soLinger: 0 trafficClass: 0 #javaExecutablePath: 'c:\\jvm\\bin\\java.exe' #additionalClassPath: 'c:\\temp\\*' isStartOnMainServerInitialize: true priorityStartOnMainServerInitialize: 4 waitForProcessInitResponseTimeInMillis: 90000 waitForProcessStartResponseTimeInMillis: 90000 waitForProcessDestroyResponseTimeInMillis: 30000 isAllFilesToJVMAppClassLoader: false isArchiveOnStart: false startLogMode: INFO isInitErrorCauseWithNetworkInformation: true isJmxEnabled: true jmxOptions: '-Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false' jmxPrimaryPort: -1 jmxSecondaryPort: -1 checkAvailableScript: 'function isAvailable(checkResponseTimeInMillis, jrmcActiveThreads, jrmcMaxThreads, queueActiveThreads, queueMaxThreads, servletActiveThreads, servletMaxThreads, jvmMaxMemoryInBytes, jvmTotalMemoryInBytes, jvmFreeMemoryInBytes, jvmProcessCpuLoadInPercentage, userAvailableFlag) { var isAvailableByUser = Boolean(userAvailableFlag); if(checkResponseTimeInMillis > 20000 || !isAvailableByUser) { return false; } return true; }' APPLICATION: applicationContainerProducerClassName: 'com.example.exchange.configuration.ExchangeRatesJLupinConfiguration' INITIALIZING_LOGGER: #directoryPath: '/logs/server' #fileName: 'file_name' fileExtension: 'log' fileSizeInMB: 20 maxFiles: 10 MEMORY_ERRORS: isRestartOnError: true howManyTimes: 4 percentageGrowth: 15 isHeapDump: true THREAD_POOLS: THREAD_POOL_1: size: 8 waitingTimeForTasksCompletionInMillis: 10000 #THREAD_POOL_2: # size: 8 # waitingTimeForTasksCompletionInMillis: 10000
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- ===================================================================== --> <!-- --> <!-- Log4j2 Configuration --> <!-- --> <!-- ===================================================================== --> <!-- | For more configuration information and examples see the Apache Log4j2 | website: https://logging.apache.org/log4j/2.x/index.html --> <Configuration status="WARN" dest="errors/exchange-rates_log4j2_status.log"> <!-- Extract log directory and file name into variables --> <Properties> <Property name="logDirectory">../logs/microservice/exchange-rates</Property> <Property name="logFileName">microservice</Property> </Properties> <Appenders> <!-- RollingFileAppender configured to role every day --> <RollingFile name="FILE"> <FileName>${logDirectory}/${logFileName}.log</FileName> <FilePattern>${logDirectory}/${logFileName}.%d{yyyy-MM-dd}.log</FilePattern> <!-- Compress log files to gzip --> <!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy --> <!-- <FilePattern>/.%d{yyyy-MM-dd}.log.gz</FilePattern> --> <!-- Do not truncate file --> <Append>true</Append> <!-- The default pattern: Date Priority [Category] (Thread) Message\n --> <PatternLayout pattern="%d %-5p [%c] (%t) %m%n"/> <Policies> <!-- Rollover every microservice start - very useful for debugging --> <!-- <OnStartupTriggeringPolicy /> --> <!-- Rollover at the top of each day --> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!-- Rollover if file size is greater than 200 MB --> <!-- <SizeBasedTriggeringPolicy size="200 MB"/> --> </Policies> <CreateOnDemand>true</CreateOnDemand> <!-- Keep last 10 log files --> <!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy --> <!-- <DefaultRolloverStrategy max="10" /> --> </RollingFile> <!-- AsyncAppender for high performance --> <Async name="ASYNC_FILE"> <BufferSize>1000</BufferSize> <AppenderRef ref="FILE"/> </Async> </Appenders> <Loggers> <!-- Setup for root logger with AsyncAppender --> <Root level="info"> <AppenderRef ref="ASYNC_FILE"/> </Root> </Loggers> </Configuration>
currency-converter
configuration.yml
SERVERS: JLRMC: #JLupin Remote Method Calls Fast Protocol readTimeout: 480000 isWaitForFinishExecuteAllRequests: true waitToShutdownThreadsOnStop: 60000 backlog: 256 receiveBufferSize: 256 isReuseAddress: false threadPoolSize: 128 isLogPeriodicOnDebug: true isDestroyThreadOnTimeout: false threadExecutingTimeOut: 240000 isStartOnMainServerInitialize: true TRANSMISSION: readTimeout: 480000 isWaitForFinishExecuteAllRequests: false waitToShutdownThreadsOnStop: 60000 backlog: 0 receiveBufferSize: 0 isReuseAddress: false threadPoolSize: 8 isLogPeriodicOnDebug: true isDestroyThreadOnTimeout: false threadExecutingTimeOut: 3600000 isStartOnMainServerInitialize: true QUEUE: readTimeout: 480000 isWaitForFinishExecuteAllRequests: true waitToShutdownThreadsOnStop: 60000 backlog: 256 receiveBufferSize: 256 isReuseAddress: false threadPoolSize: 128 isLogPeriodicOnDebug: true isDestroyThreadOnTimeout: false threadExecutingTimeOut: 240000 isStartOnMainServerInitialize: true ENTRY_POINTS: QUEUE: threadAmount: 128 howOftenCheckingServerInMillis: 5000 repeatsAmount: 4 timeToWaitBetweenRepeatProbeInMillis: 1000 TRANSMISSION: MICROSERVICES_GRANT_ACCESS: MICROSERVICES_LIST: #- microserviceName: 'sampleMicroservice' # serviceName: 'sampleServiceName' # methodName: 'sampleMethodName' #- microserviceName: 'sampleMicroservice2' # serviceName: 'sampleServiceName2' # methodName: 'sampleMethodName2' PROPERTIES: platformVersion: '1.5.0.3' #jvmOptions1: '-Xms128M -Xmx256M -agentlib:jdwp=transport=dt_socket,address=12998,server=y,suspend=n' jvmOptions1: '-Xms128M -Xmx256M' #jvmOptions_2 - default the same as jvmOptions_1 #jvmOptions2: '-Xms128M -Xmx256M' externalPort: '8000' version: '1.0.0' switchDelayTime: 0 connectionSocketTimeoutInMillis: 1000 readTimeoutInMillis: 30000 isKeepAlive: false isOOBInline: false isTcpNoDelay: false isReuseAddress: false sendBufferSize: 0 receiveBufferSize: 0 soLinger: 0 trafficClass: 0 #javaExecutablePath: 'c:\\jvm\\bin\\java.exe' #additionalClassPath: 'c:\\temp\\*' isStartOnMainServerInitialize: true priorityStartOnMainServerInitialize: 4 waitForProcessInitResponseTimeInMillis: 90000 waitForProcessStartResponseTimeInMillis: 90000 waitForProcessDestroyResponseTimeInMillis: 30000 isAllFilesToJVMAppClassLoader: false isArchiveOnStart: false startLogMode: INFO isInitErrorCauseWithNetworkInformation: true isJmxEnabled: true jmxOptions: '-Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false' jmxPrimaryPort: -1 jmxSecondaryPort: -1 checkAvailableScript: 'function isAvailable(checkResponseTimeInMillis, jrmcActiveThreads, jrmcMaxThreads, queueActiveThreads, queueMaxThreads, servletActiveThreads, servletMaxThreads, jvmMaxMemoryInBytes, jvmTotalMemoryInBytes, jvmFreeMemoryInBytes, jvmProcessCpuLoadInPercentage, userAvailableFlag) { var isAvailableByUser = Boolean(userAvailableFlag); if(checkResponseTimeInMillis > 20000 || !isAvailableByUser) { return false; } return true; }' APPLICATION: applicationContainerProducerClassName: 'com.example.exchange.configuration.CurrencyConverterJLupinConfiguration' INITIALIZING_LOGGER: #directoryPath: '/logs/server' #fileName: 'file_name' fileExtension: 'log' fileSizeInMB: 20 maxFiles: 10 MEMORY_ERRORS: isRestartOnError: true howManyTimes: 4 percentageGrowth: 15 isHeapDump: true THREAD_POOLS: THREAD_POOL_1: size: 8 waitingTimeForTasksCompletionInMillis: 10000 #THREAD_POOL_2: # size: 8 # waitingTimeForTasksCompletionInMillis: 10000
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- ===================================================================== --> <!-- --> <!-- Log4j2 Configuration --> <!-- --> <!-- ===================================================================== --> <!-- | For more configuration information and examples see the Apache Log4j2 | website: https://logging.apache.org/log4j/2.x/index.html --> <Configuration status="WARN" dest="errors/currency-converter_log4j2_status.log"> <!-- Extract log directory and file name into variables --> <Properties> <Property name="logDirectory">../logs/microservice/currency-converter</Property> <Property name="logFileName">microservice</Property> </Properties> <Appenders> <!-- RollingFileAppender configured to role every day --> <RollingFile name="FILE"> <FileName>${logDirectory}/${logFileName}.log</FileName> <FilePattern>${logDirectory}/${logFileName}.%d{yyyy-MM-dd}.log</FilePattern> <!-- Compress log files to gzip --> <!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy --> <!-- <FilePattern>/.%d{yyyy-MM-dd}.log.gz</FilePattern> --> <!-- Do not truncate file --> <Append>true</Append> <!-- The default pattern: Date Priority [Category] (Thread) Message\n --> <PatternLayout pattern="%d %-5p [%c] (%t) %m%n"/> <Policies> <!-- Rollover every microservice start - very useful for debugging --> <!-- <OnStartupTriggeringPolicy /> --> <!-- Rollover at the top of each day --> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!-- Rollover if file size is greater than 200 MB --> <!-- <SizeBasedTriggeringPolicy size="200 MB"/> --> </Policies> <CreateOnDemand>true</CreateOnDemand> <!-- Keep last 10 log files --> <!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy --> <!-- <DefaultRolloverStrategy max="10" /> --> </RollingFile> <!-- AsyncAppender for high performance --> <Async name="ASYNC_FILE"> <BufferSize>1000</BufferSize> <AppenderRef ref="FILE"/> </Async> </Appenders> <Loggers> <!-- Setup for root logger with AsyncAppender --> <Root level="info"> <AppenderRef ref="ASYNC_FILE"/> </Root> </Loggers> </Configuration>
exchange
servlet_configuration.yml
SERVERS: HTTP: type: spring_boot httpPrimaryPort: -1 httpSecondaryPort: -1 waitForFinishExecuteAllRequests: true waitToShutdownThreadsOnStop: 5000 springBootLoaderClassName: org.springframework.boot.loader.WarLauncher contextName: /exchange isStartOnMainServerInitialize: true httpStickySession: false TRANSMISSION: readTimeout: 480000 isWaitForFinishExecuteAllRequests: false waitToShutdownThreadsOnStop: 60000 backlog: 0 receiveBufferSize: 0 isReuseAddress: false threadPoolSize: 8 isLogPeriodicOnDebug: true isDestroyThreadOnTimeout: false threadExecutingTimeOut: 3600000 isStartOnMainServerInitialize: true PROPERTIES: platformVersion: '1.5.0.3' #jvmOptions1: '-Xms128M -Xmx512M -agentlib:jdwp=transport=dt_socket,address=12998,server=y,suspend=n' jvmOptions1: '-Xms128M -Xmx512M' #jvmOptions_2 - default the same as jvmOptions_1 #jvmOptions2: '-Xms128M -Xmx512M' externalPort: '8000' version: '1.0.0' switchDelayTime: 1000 connectionSocketTimeoutInMillis: 1000 readTimeoutInMillis: 30000 isKeepAlive: false isOOBInline: false isTcpNoDelay: false isReuseAddress: false sendBufferSize: 0 receiveBufferSize: 0 soLinger: 0 trafficClass: 0 #javaExecutablePath: 'c:\\jvm\\bin\\java.exe' #additionalClassPath: 'c:\\temp\\*' isStartOnMainServerInitialize: true priorityStartOnMainServerInitialize: 5 waitForProcessInitResponseTimeInMillis: 90000 waitForProcessStartResponseTimeInMillis: 90000 waitForProcessDestroyResponseTimeInMillis: 30000 isAllFilesToJVMAppClassLoader: true #isStackDumping: true isArchiveOnStart: false startLogMode: INFO isInitErrorCauseWithNetworkInformation: true isJmxEnabled: true jmxOptions: '-Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false' jmxPrimaryPort: -1 jmxSecondaryPort: -1 isExternalHealthcheck: false externalHealthcheckURI: '/sampleURI/' httpStickySessionCookieOptions: 'option1=value1' checkAvailableScript: 'function isAvailable(checkResponseTimeInMillis, jrmcActiveThreads, jrmcMaxThreads, queueActiveThreads, queueMaxThreads, servletActiveThreads, servletMaxThreads, jvmMaxMemoryInBytes, jvmTotalMemoryInBytes, jvmFreeMemoryInBytes, jvmProcessCpuLoadInPercentage, userAvailableFlag) { var isAvailableByUser = Boolean(userAvailableFlag); if(checkResponseTimeInMillis > 20000 || !isAvailableByUser) { return false; } return true; }' INITIALIZING_LOGGER: #directoryPath: '/logs/server' #fileName: 'file_name' fileExtension: 'log' fileSizeInMB: 20 maxFiles: 10 MEMORY_ERRORS: isRestartOnError: true howManyTimes: 4 percentageGrowth: 15 isHeapDump: true THREAD_POOLS: THREAD_POOL_1: size: 8 waitingTimeForTasksCompletionInMillis: 10000 #THREAD_POOL_2: # size: 8 # waitingTimeForTasksCompletionInMillis: 10000
log4j2.xml (put this also inside resources directory)
<?xml version="1.0" encoding="UTF-8"?> <!-- ===================================================================== --> <!-- --> <!-- Log4j2 Configuration --> <!-- --> <!-- ===================================================================== --> <!-- | For more configuration information and examples see the Apache Log4j2 | website: https://logging.apache.org/log4j/2.x/index.html --> <Configuration status="WARN" dest="errors/exchange_log4j2_status.log"> <!-- Extract log directory and file name into variables --> <Properties> <Property name="logDirectory">../logs/microservice/exchange</Property> <Property name="logFileName">microservice</Property> </Properties> <Appenders> <!-- RollingFileAppender configured to role every day --> <RollingFile name="FILE"> <FileName>${logDirectory}/${logFileName}.log</FileName> <FilePattern>${logDirectory}/${logFileName}.%d{yyyy-MM-dd}.log</FilePattern> <!-- Compress log files to gzip --> <!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy --> <!-- <FilePattern>/.%d{yyyy-MM-dd}.log.gz</FilePattern> --> <!-- Do not truncate file --> <Append>true</Append> <!-- The default pattern: Date Priority [Category] (Thread) Message\n --> <PatternLayout pattern="%d %-5p [%c] (%t) %m%n"/> <Policies> <!-- Rollover every microservice start - very useful for debugging --> <!-- <OnStartupTriggeringPolicy /> --> <!-- Rollover at the top of each day --> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!-- Rollover if file size is greater than 200 MB --> <!-- <SizeBasedTriggeringPolicy size="200 MB"/> --> </Policies> <CreateOnDemand>true</CreateOnDemand> <!-- Keep last 10 log files --> <!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy --> <!-- <DefaultRolloverStrategy max="10" /> --> </RollingFile> <!-- AsyncAppender for high performance --> <Async name="ASYNC_FILE"> <BufferSize>1000</BufferSize> <AppenderRef ref="FILE"/> </Async> </Appenders> <Loggers> <!-- Setup for root logger with AsyncAppender --> <Root level="info"> <AppenderRef ref="ASYNC_FILE"/> </Root> </Loggers> </Configuration>
Now everything is ready for deploying.
Deploying
Run server (start/start.sh or start/start.cmd in main server directory). Then run maven commands to deploy your microservices:
mvn clean package jlupin-platform:deploy@jlupin-deploy --projects exchange-rates/implementation --also-make mvn clean package jlupin-platform:deploy@jlupin-deploy --projects currency-converter/implementation --also-make mvn clean package jlupin-platform:deploy@jlupin-deploy --projects exchange/implementation --also-make
Check microservice's list to see your microservices (start/control.sh):
./control.sh microservice list
Zone Node Microservice Type Version #Services default NODE_1 currency-converter native 1.0.0 1 default NODE_1 queueMicroservice native 1.5.0.3 1 default NODE_1 exchange-rates native 1.0.0 1 default NODE_1 channelMicroservice native 1.5.0.3 1 default NODE_1 currency-converter-gbp native 1.5.0.3 1 default NODE_1 exchange servlet 1.0.0 1 default NODE_1 http-session-repository native 1.5.0.2 2 default NODE_1 currency-converter-chf native 1.5.0.3 1 default NODE_1 currency-converter-eur native 1.5.0.3 1
You can see that all microservices are on the list. Now you can check your application with request to created controller:
curl -X POST -H "Content-Type: application/json" -d "{\"value\":12.50, \"currency\":\"USD\"}" localhost:8000/exchange/convert
As a result you should see:
[{"value":11.17,"currency":"EUR"},{"value":12.50,"currency":"USD"},{"value":9.77,"currency":"GBP"}]
Done tutorial
You can download project which is result of making this tutorial from GitHub: https://github.com/jlupin/communication-between-microservices-jlp-1503
RATE & DISCUSS (0)