REST 02: Currency
Entity
import java.math.BigDecimal;
import javax.validation.constraints.Size;
public class CurrencyConversion {
private Long id;
@Size(min=3, max=3, message="Currency code should be 3 letters")
private String from;
private String to;
private BigDecimal quantity;
private BigDecimal conversionMiltiple;
private BigDecimal totalCalculatedAmount;
private String environment;
public CurrencyConversion() {
}
public CurrencyConversion(Long id, String from, String to, BigDecimal quantity, BigDecimal conversionMiltiple,
BigDecimal totalCalculatedAmount, String environment) {
super();
this.id = id;
this.from = from;
this.to = to;
this.conversionMiltiple = conversionMiltiple;
this.quantity = quantity;
this.totalCalculatedAmount = totalCalculatedAmount;
this.environment = environment;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
// ...........
// other getters setters
}
Controller (with consumer and feign)
import java.math.BigDecimal;
import java.util.HashMap;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@Validated
public class CurrencyConversionController {
@Autowired
private CurrencyExchangeProxy proxy;
@GetMapping("/currency-conversion/from/{from}/to/{to}/quantity/{quantity}")
public CurrencyConversion calculateCurrencyConversion(
@Size(min=3, max=3) @PathVariable String from,
@PathVariable String to,
@Min(10) @PathVariable BigDecimal quantity
) {
HashMap<String, String> uriVariables = new HashMap<>();
uriVariables.put("from", from);
uriVariables.put("to", to);
ResponseEntity<CurrencyConversion> responseEntity = new RestTemplate().getForEntity
("http://localhost:8000/currency-exchange/from/{from}/to/{to}",
CurrencyConversion.class, uriVariables);
CurrencyConversion currencyConversion = responseEntity.getBody();
return new CurrencyConversion(currencyConversion.getId(),
from, to, quantity,
currencyConversion.getConversionMiltiple(),
quantity.multiply(currencyConversion.getConversionMiltiple()),
currencyConversion.getEnvironment()
);
}
@GetMapping("/currency-conversion-feign/from/{from}/to/{to}/quantity/{quantity}")
public CurrencyConversion calculateCurrencyConversionFeign(
@PathVariable String from,
@PathVariable String to,
@PathVariable BigDecimal quantity
) {
CurrencyConversion currencyConversion = proxy.retrieveExchangeValue(from, to);
return new CurrencyConversion(currencyConversion.getId(),
from, to, quantity,
currencyConversion.getConversionMiltiple(),
quantity.multiply(currencyConversion.getConversionMiltiple()),
currencyConversion.getEnvironment()+" feign"
);
}
}
Proxy
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name="currency-exchange", url="localhost:8000")
public interface CurrencyExchangeProxy {
@GetMapping("/currency-exchange/from/{from}/to/{to}")
public CurrencyConversion retrieveExchangeValue(
@PathVariable String from,
@PathVariable String to);
}
Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class CurrencyConversionServiceApplication {
public static void main(String[] args) {
SpringApplication.run(CurrencyConversionServiceApplication.class, args);
}
}
REST 02: Exchange
Entity
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class CurrencyExchange {
@Id
private Long id;
@Column(name="currency_from")
private String from;
@Column(name="currency_to")
private String to;
private BigDecimal conversionMiltiple;
private String environment;
public CurrencyExchange() {
}
public CurrencyExchange(Long id, String from, String to, BigDecimal conversionMiltiple) {
super();
this.id = id;
this.from = from;
this.to = to;
this.conversionMiltiple = conversionMiltiple;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFrom() {
return from;
}
// ...............
// Getters, setters
}
Controller JPA
import java.math.BigDecimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CurrencyExchangeController {
@Autowired
private CurrencyExchangeRepository repository;
@Autowired
private Environment environment;
@GetMapping("/currency-exchange/from/{from}/to/{to}")
public CurrencyExchange retrieveExchangeValue(
@PathVariable String from,
@PathVariable String to) {
//CurrencyExchange currencyExchange = new CurrencyExchange(1000L, from, to, BigDecimal.valueOf(50));
CurrencyExchange currencyExchange = repository.findByFromAndTo(from, to);
if(currencyExchange == null) {
throw new RuntimeException("Unable to find data for "+from+" and "+to);
}
String port = environment.getProperty("local.server.port");
currencyExchange.setEnvironment(port);
return currencyExchange;
}
}
Repository
import org.springframework.data.jpa.repository.JpaRepository;
public interface CurrencyExchangeRepository
extends JpaRepository<CurrencyExchange, Long> {
CurrencyExchange findByFromAndTo(String from, String to);
}
Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CurrencyExchangeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(CurrencyExchangeServiceApplication.class, args);
}
}
Settings
spring.application.name=currency-exchange
server.port=8000
spring.config.import=optional:configserver:http://localhost:8888
spring.jpa.show-sql=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.jpa.defer-datasource-initialization=true
spring.h2.console.enabled=true
Dependencies
<?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 https://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.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.im.microservices</groupId>
<artifactId>currency-exchange-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>currency-exchange-service</name>
<description>Currency Exchange Microservice</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>