From 33f7ffeb6add2990b00574b2bd54d2ac29b215ff Mon Sep 17 00:00:00 2001 From: Ranga Rao Karanam Date: Sat, 9 Sep 2017 14:41:01 +0530 Subject: [PATCH] Step17 --- .../currency-exchange-service/.DS_Store | Bin 0 -> 6148 bytes .../currency-exchange-service/pom.xml | 123 +++ .../CurrencyExchangeController.java | 32 + .../CurrencyExchangeServiceApplication.java | 12 + .../ExchangeValue.java | 61 ++ .../ExchangeValueRepository.java | 8 + .../src/main/resources/application.properties | 5 + .../src/main/resources/data.sql | 6 + ...rrencyExchangeServiceApplicationTests.java | 16 + 03.microservices/step17.md | 761 ++++++++++++++++++ 03.microservices/step17.zip | Bin 0 -> 23932 bytes 11 files changed, 1024 insertions(+) create mode 100644 03.microservices/currency-exchange-service/.DS_Store create mode 100644 03.microservices/currency-exchange-service/pom.xml create mode 100644 03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeController.java create mode 100644 03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplication.java create mode 100644 03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValue.java create mode 100644 03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValueRepository.java create mode 100644 03.microservices/currency-exchange-service/src/main/resources/application.properties create mode 100644 03.microservices/currency-exchange-service/src/main/resources/data.sql create mode 100644 03.microservices/currency-exchange-service/src/test/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplicationTests.java create mode 100644 03.microservices/step17.md create mode 100644 03.microservices/step17.zip diff --git a/03.microservices/currency-exchange-service/.DS_Store b/03.microservices/currency-exchange-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-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 + + + + + + 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 new file mode 100644 index 00000000..51554b61 --- /dev/null +++ b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeController.java @@ -0,0 +1,32 @@ +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; +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; + } +} diff --git a/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplication.java b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplication.java new file mode 100644 index 00000000..a2cfa381 --- /dev/null +++ b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplication.java @@ -0,0 +1,12 @@ +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); + } +} diff --git a/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValue.java b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValue.java new file mode 100644 index 00000000..a7dfe033 --- /dev/null +++ b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValue.java @@ -0,0 +1,61 @@ +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; + } + +} diff --git a/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValueRepository.java b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValueRepository.java new file mode 100644 index 00000000..bc6328c6 --- /dev/null +++ b/03.microservices/currency-exchange-service/src/main/java/com/in28minutes/microservices/currencyexchangeservice/ExchangeValueRepository.java @@ -0,0 +1,8 @@ +package com.in28minutes.microservices.currencyexchangeservice; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ExchangeValueRepository extends + JpaRepository{ + ExchangeValue findByFromAndTo(String from, String to); +} diff --git a/03.microservices/currency-exchange-service/src/main/resources/application.properties b/03.microservices/currency-exchange-service/src/main/resources/application.properties new file mode 100644 index 00000000..78b15c1f --- /dev/null +++ b/03.microservices/currency-exchange-service/src/main/resources/application.properties @@ -0,0 +1,5 @@ +spring.application.name=currency-exchange-service +server.port=8000 + +spring.jpa.show-sql=true +spring.h2.console.enabled=true \ No newline at end of file diff --git a/03.microservices/currency-exchange-service/src/main/resources/data.sql b/03.microservices/currency-exchange-service/src/main/resources/data.sql new file mode 100644 index 00000000..dd914c5f --- /dev/null +++ b/03.microservices/currency-exchange-service/src/main/resources/data.sql @@ -0,0 +1,6 @@ +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); \ No newline at end of file diff --git a/03.microservices/currency-exchange-service/src/test/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplicationTests.java b/03.microservices/currency-exchange-service/src/test/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplicationTests.java new file mode 100644 index 00000000..f4f82fe1 --- /dev/null +++ b/03.microservices/currency-exchange-service/src/test/java/com/in28minutes/microservices/currencyexchangeservice/CurrencyExchangeServiceApplicationTests.java @@ -0,0 +1,16 @@ +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() { + } + +} diff --git a/03.microservices/step17.md b/03.microservices/step17.md new file mode 100644 index 00000000..daa2b1bd --- /dev/null +++ b/03.microservices/step17.md @@ -0,0 +1,761 @@ + +## Complete Code Example + + +### /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 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 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/step17.zip b/03.microservices/step17.zip new file mode 100644 index 0000000000000000000000000000000000000000..b49ee04304ab2050525697ea273f21135c0e20e6 GIT binary patch literal 23932 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