From 928200e79bfa67b8e909d7f74b7dd55506e89e06 Mon Sep 17 00:00:00 2001 From: Ranga Rao Karanam Date: Sat, 9 Sep 2017 15:30:37 +0530 Subject: [PATCH] Step20 --- .../currency-conversion-service/.DS_Store | Bin 0 -> 6148 bytes .../currency-conversion-service/pom.xml | 114 ++ .../CurrencyConversionBean.java | 86 ++ .../CurrencyConversionController.java | 37 + .../CurrencyConversionServiceApplication.java | 12 + .../src/main/resources/application.properties | 2 + ...encyConversionServiceApplicationTests.java | 16 + .../CurrencyExchangeController.java | 2 - 03.microservices/step20.md | 1062 +++++++++++++++++ 03.microservices/step20.zip | Bin 0 -> 32254 bytes 10 files changed, 1329 insertions(+), 2 deletions(-) create mode 100644 03.microservices/currency-conversion-service/.DS_Store create mode 100644 03.microservices/currency-conversion-service/pom.xml create mode 100644 03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionBean.java create mode 100644 03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionController.java create mode 100644 03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplication.java create mode 100644 03.microservices/currency-conversion-service/src/main/resources/application.properties create mode 100644 03.microservices/currency-conversion-service/src/test/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplicationTests.java create mode 100644 03.microservices/step20.md create mode 100644 03.microservices/step20.zip diff --git a/03.microservices/currency-conversion-service/.DS_Store b/03.microservices/currency-conversion-service/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + 4.0.0 + + com.in28minutes.microservices + currency-conversion-service + 0.0.1-SNAPSHOT + jar + + currency-conversion-service + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M3 + + + + + UTF-8 + UTF-8 + 1.8 + Finchley.M2 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + diff --git a/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionBean.java b/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionBean.java new file mode 100644 index 00000000..3d039066 --- /dev/null +++ b/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionBean.java @@ -0,0 +1,86 @@ +package com.in28minutes.microservices.currencyconversionservice; + +import java.math.BigDecimal; + +public class CurrencyConversionBean { + private Long id; + private String from; + private String to; + private BigDecimal conversionMultiple; + private BigDecimal quantity; + private BigDecimal totalCalculatedAmount; + private int port; + + public CurrencyConversionBean() { + + } + + public CurrencyConversionBean(Long id, String from, String to, BigDecimal conversionMultiple, BigDecimal quantity, + BigDecimal totalCalculatedAmount, int port) { + super(); + this.id = id; + this.from = from; + this.to = to; + this.conversionMultiple = conversionMultiple; + this.quantity = quantity; + this.totalCalculatedAmount = totalCalculatedAmount; + this.port = port; + } + + 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; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public BigDecimal getConversionMultiple() { + return conversionMultiple; + } + + public void setConversionMultiple(BigDecimal conversionMultiple) { + this.conversionMultiple = conversionMultiple; + } + + public BigDecimal getQuantity() { + return quantity; + } + + public void setQuantity(BigDecimal quantity) { + this.quantity = quantity; + } + + public BigDecimal getTotalCalculatedAmount() { + return totalCalculatedAmount; + } + + public void setTotalCalculatedAmount(BigDecimal totalCalculatedAmount) { + this.totalCalculatedAmount = totalCalculatedAmount; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + +} diff --git a/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionController.java b/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionController.java new file mode 100644 index 00000000..4a3aa63e --- /dev/null +++ b/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionController.java @@ -0,0 +1,37 @@ +package com.in28minutes.microservices.currencyconversionservice; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.http.ResponseEntity; +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 +public class CurrencyConversionController { + + @GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}") + public CurrencyConversionBean convertCurrency(@PathVariable String from, + @PathVariable String to, + @PathVariable BigDecimal quantity + ){ + + Map uriVariables = new HashMap<>(); + uriVariables.put("from", from); + uriVariables.put("to", to); + + ResponseEntity responseEntity = new RestTemplate().getForEntity( + "http://localhost:8000/currency-exchange/from/{from}/to/{to}", + CurrencyConversionBean.class, + uriVariables ); + + CurrencyConversionBean response = responseEntity.getBody(); + + return new CurrencyConversionBean(response.getId(),from,to,response.getConversionMultiple(), + quantity,quantity.multiply(response.getConversionMultiple()),response.getPort()); + } + +} diff --git a/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplication.java b/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplication.java new file mode 100644 index 00000000..532dd3b4 --- /dev/null +++ b/03.microservices/currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplication.java @@ -0,0 +1,12 @@ +package com.in28minutes.microservices.currencyconversionservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CurrencyConversionServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(CurrencyConversionServiceApplication.class, args); + } +} diff --git a/03.microservices/currency-conversion-service/src/main/resources/application.properties b/03.microservices/currency-conversion-service/src/main/resources/application.properties new file mode 100644 index 00000000..e1042fe2 --- /dev/null +++ b/03.microservices/currency-conversion-service/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.application.name=currency-conversion-service +server.port=8100 \ No newline at end of file diff --git a/03.microservices/currency-conversion-service/src/test/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplicationTests.java b/03.microservices/currency-conversion-service/src/test/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplicationTests.java new file mode 100644 index 00000000..055eb7f8 --- /dev/null +++ b/03.microservices/currency-conversion-service/src/test/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplicationTests.java @@ -0,0 +1,16 @@ +package com.in28minutes.microservices.currencyconversionservice; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CurrencyConversionServiceApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeController.java b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeController.java index 51554b61..03d07576 100644 --- a/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeController.java +++ b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeController.java @@ -1,7 +1,5 @@ package com.in28minutes.microservices.currencyexchangeservice; -import java.math.BigDecimal; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; diff --git a/03.microservices/step20.md b/03.microservices/step20.md new file mode 100644 index 00000000..82d72661 --- /dev/null +++ b/03.microservices/step20.md @@ -0,0 +1,1062 @@ + +## Complete Code Example + + +### /currency-conversion-service/pom.xml + +```xml + + + 4.0.0 + + com.in28minutes.microservices + currency-conversion-service + 0.0.1-SNAPSHOT + jar + + currency-conversion-service + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M3 + + + + + UTF-8 + UTF-8 + 1.8 + Finchley.M2 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + +``` +--- + +### /currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionBean.java + +```java +package com.in28minutes.microservices.currencyconversionservice; + +import java.math.BigDecimal; + +public class CurrencyConversionBean { + private Long id; + private String from; + private String to; + private BigDecimal conversionMultiple; + private BigDecimal quantity; + private BigDecimal totalCalculatedAmount; + private int port; + + public CurrencyConversionBean() { + + } + + public CurrencyConversionBean(Long id, String from, String to, BigDecimal conversionMultiple, BigDecimal quantity, + BigDecimal totalCalculatedAmount, int port) { + super(); + this.id = id; + this.from = from; + this.to = to; + this.conversionMultiple = conversionMultiple; + this.quantity = quantity; + this.totalCalculatedAmount = totalCalculatedAmount; + this.port = port; + } + + 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; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public BigDecimal getConversionMultiple() { + return conversionMultiple; + } + + public void setConversionMultiple(BigDecimal conversionMultiple) { + this.conversionMultiple = conversionMultiple; + } + + public BigDecimal getQuantity() { + return quantity; + } + + public void setQuantity(BigDecimal quantity) { + this.quantity = quantity; + } + + public BigDecimal getTotalCalculatedAmount() { + return totalCalculatedAmount; + } + + public void setTotalCalculatedAmount(BigDecimal totalCalculatedAmount) { + this.totalCalculatedAmount = totalCalculatedAmount; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + +} +``` +--- + +### /currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionController.java + +```java +package com.in28minutes.microservices.currencyconversionservice; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.http.ResponseEntity; +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 +public class CurrencyConversionController { + + @GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}") + public CurrencyConversionBean convertCurrency(@PathVariable String from, + @PathVariable String to, + @PathVariable BigDecimal quantity + ){ + + Map uriVariables = new HashMap<>(); + uriVariables.put("from", from); + uriVariables.put("to", to); + + ResponseEntity responseEntity = new RestTemplate().getForEntity( + "http://localhost:8000/currency-exchange/from/{from}/to/{to}", + CurrencyConversionBean.class, + uriVariables ); + + CurrencyConversionBean response = responseEntity.getBody(); + + return new CurrencyConversionBean(response.getId(),from,to,response.getConversionMultiple(), + quantity,quantity.multiply(response.getConversionMultiple()),response.getPort()); + } + +} +``` +--- + +### /currency-conversion-service/src/main/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplication.java + +```java +package com.in28minutes.microservices.currencyconversionservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CurrencyConversionServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(CurrencyConversionServiceApplication.class, args); + } +} +``` +--- + +### /currency-conversion-service/src/main/resources/application.properties + +```properties +spring.application.name=currency-conversion-service +server.port=8100 +``` +--- + +### /currency-conversion-service/src/test/java/com/in28minutes/microservices/currencyconversionservice/CurrencyConversionServiceApplicationTests.java + +```java +package com.in28minutes.microservices.currencyconversionservice; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CurrencyConversionServiceApplicationTests { + + @Test + public void contextLoads() { + } + +} +``` +--- + +### /currency-exchange-service/pom.xml + +```xml + + + 4.0.0 + + com.in28minutes.microservices + currency-exchange-service + 0.0.1-SNAPSHOT + jar + + currency-exchange-service + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M3 + + + + + UTF-8 + UTF-8 + 1.8 + Finchley.M2 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + + + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + +``` +--- + +### /currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeController.java + +```java +package com.in28minutes.microservices.currencyexchangeservice; + +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 Environment environment; + + @Autowired + private ExchangeValueRepository repository; + + @GetMapping("/currency-exchange/from/{from}/to/{to}") + public ExchangeValue retrieveExchangeValue + (@PathVariable String from, @PathVariable String to){ + + ExchangeValue exchangeValue = + repository.findByFromAndTo(from, to); + + exchangeValue.setPort( + Integer.parseInt(environment.getProperty("local.server.port"))); + + return exchangeValue; + } +} +``` +--- + +### /currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplication.java + +```java +package com.in28minutes.microservices.currencyexchangeservice; + +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); + } +} +``` +--- + +### /currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValue.java + +```java +package com.in28minutes.microservices.currencyexchangeservice; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class ExchangeValue { + + @Id + private Long id; + + @Column(name="currency_from") + private String from; + + @Column(name="currency_to") + private String to; + + private BigDecimal conversionMultiple; + private int port; + + public ExchangeValue() { + + } + + + public ExchangeValue(Long id, String from, String to, BigDecimal conversionMultiple) { + super(); + this.id = id; + this.from = from; + this.to = to; + this.conversionMultiple = conversionMultiple; + } + + public Long getId() { + return id; + } + + public String getFrom() { + return from; + } + + public String getTo() { + return to; + } + + public BigDecimal getConversionMultiple() { + return conversionMultiple; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + +} +``` +--- + +### /currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValueRepository.java + +```java +package com.in28minutes.microservices.currencyexchangeservice; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ExchangeValueRepository extends + JpaRepository{ + ExchangeValue findByFromAndTo(String from, String to); +} +``` +--- + +### /currency-exchange-service/src/main/resources/application.properties + +```properties +spring.application.name=currency-exchange-service +server.port=8000 + +spring.jpa.show-sql=true +spring.h2.console.enabled=true +``` +--- + +### /currency-exchange-service/src/main/resources/data.sql + +``` +insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) +values(10001,'USD','INR',65,0); +insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) +values(10002,'EUR','INR',75,0); +insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) +values(10003,'AUD','INR',25,0); +``` +--- + +### /currency-exchange-service/src/test/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplicationTests.java + +```java +package com.in28minutes.microservices.currencyexchangeservice; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CurrencyExchangeServiceApplicationTests { + + @Test + public void contextLoads() { + } + +} +``` +--- + +### /git-localconfig-repo/limits-service-dev.properties + +```properties +limits-service.minimum=1 +``` +--- + +### /git-localconfig-repo/limits-service-qa.properties + +```properties +limits-service.minimum=2 +limits-service.maximum=222 +``` +--- + +### /git-localconfig-repo/limits-service.properties + +```properties +limits-service.minimum=8 +limits-service.maximum=888 +``` +--- + +### /limits-service/pom.xml + +```xml + + + 4.0.0 + + com.in28minutes.microservices + limits-service + 0.0.1-SNAPSHOT + jar + + limits-service + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M3 + + + + + UTF-8 + UTF-8 + 1.8 + Finchley.M2 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + +``` +--- + +### /limits-service/src/main/java/com/in28minutes/microservices/limitsservice/bean/LimitConfiguration.java + +```java +package com.in28minutes.microservices.limitsservice.bean; + +public class LimitConfiguration { + private int maximum; + private int minimum; + + protected LimitConfiguration() { + + } + + public LimitConfiguration(int maximum, int minimum) { + super(); + this.maximum = maximum; + this.minimum = minimum; + } + + public int getMaximum() { + return maximum; + } + + public int getMinimum() { + return minimum; + } + +} +``` +--- + +### /limits-service/src/main/java/com/in28minutes/microservices/limitsservice/Configuration.java + +```java +package com.in28minutes.microservices.limitsservice; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties("limits-service") +public class Configuration { + + private int minimum; + private int maximum; + + public void setMinimum(int minimum) { + this.minimum = minimum; + } + + public void setMaximum(int maximum) { + this.maximum = maximum; + } + + public int getMinimum() { + return minimum; + } + + public int getMaximum() { + return maximum; + } + +} +``` +--- + +### /limits-service/src/main/java/com/in28minutes/microservices/limitsservice/LimitsConfigurationController.java + +```java +package com.in28minutes.microservices.limitsservice; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.in28minutes.microservices.limitsservice.bean.LimitConfiguration; + +@RestController +public class LimitsConfigurationController { + + @Autowired + private Configuration configuration; + + @GetMapping("/limits") + public LimitConfiguration retrieveLimitsFromConfigurations() { + return new LimitConfiguration(configuration.getMaximum(), + configuration.getMinimum()); + } + +} +``` +--- + +### /limits-service/src/main/java/com/in28minutes/microservices/limitsservice/LimitsServiceApplication.java + +```java +package com.in28minutes.microservices.limitsservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class LimitsServiceApplication { + public static void main(String[] args) { + SpringApplication.run(LimitsServiceApplication.class, args); + } +} +``` +--- + +### /limits-service/src/main/resources/bootstrap.properties + +```properties +spring.application.name=limits-service +spring.cloud.config.uri=http://localhost:8888 +spring.profiles.active=qa +``` +--- + +### /limits-service/src/test/java/com/in28minutes/microservices/limitsservice/LimitsServiceApplicationTests.java + +```java +package com.in28minutes.microservices.limitsservice; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class LimitsServiceApplicationTests { + + @Test + public void contextLoads() { + } + +} +``` +--- + +### /spring-cloud-config-server/pom.xml + +```xml + + + 4.0.0 + + com.in28minutes.microservices + spring-cloud-config-server + 0.0.1-SNAPSHOT + jar + + spring-cloud-config-server + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M3 + + + + + UTF-8 + UTF-8 + 1.8 + Finchley.M2 + + + + + org.springframework.cloud + spring-cloud-config-server + + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + +``` +--- + +### /spring-cloud-config-server/src/main/java/com/in28minutes/microservices/springcloudconfigserver/SpringCloudConfigServerApplication.java + +```java +package com.in28minutes.microservices.springcloudconfigserver; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; + +@EnableConfigServer +@SpringBootApplication +public class SpringCloudConfigServerApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringCloudConfigServerApplication.class, args); + } +} +``` +--- + +### /spring-cloud-config-server/src/main/resources/application.properties + +```properties +spring.application.name=spring-cloud-config-server +server.port=8888 +spring.cloud.config.server.git.uri=file:///in28Minutes/git/spring-micro-services/03.microservices/git-localconfig-repo +``` +--- + +### /spring-cloud-config-server/src/test/java/com/in28minutes/microservices/springcloudconfigserver/SpringCloudConfigServerApplicationTests.java + +```java +package com.in28minutes.microservices.springcloudconfigserver; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringCloudConfigServerApplicationTests { + + @Test + public void contextLoads() { + } + +} +``` +--- diff --git a/03.microservices/step20.zip b/03.microservices/step20.zip new file mode 100644 index 0000000000000000000000000000000000000000..247a04f9ee01f7727323db61db5bada77cc6ee1b GIT binary patch literal 32254 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 Xv3