diff --git a/spring-boot-modules/spring-boot-microservices/README.md b/spring-boot-modules/spring-boot-microservices/README.md new file mode 100644 index 0000000000..d2008c51fc --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/README.md @@ -0,0 +1,13 @@ +--------------------------------- CustomerOrderApp installation steps---------------------------------- + +1. Clone or download sample project from GitHub repo: https://github.com/eugenp/tutorials/tree/master/spring-boot-modules/customer-order-app +2. Unzip project folder to local disk for example to: C:/baeldung-tutorials/customer-order-app +3. Run `mvn clean install -DskipTests=true` +4. Navigate to payment-service/payment-server module folder and type `mvn spring-boot:run` +5. Open another CMD PROMPT window. + Navigate to order-service/order-server module folder and type `mvn spring-boot:run` +6. Open another CMD PROMPT window. + Navigate to customer-service module folder and type `mvn spring-boot:run` + +7. Launch the Postman application from your machine and import the collection of POST requests located in the _postman_ folder + diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/.gitignore b/spring-boot-modules/spring-boot-microservices/customer-service/.gitignore new file mode 100644 index 0000000000..0e9415ada6 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/.gitignore @@ -0,0 +1,41 @@ +#https://github.com/spring-projects/spring-boot/blob/master/.gitignore + +*# +*.iml +*.ipr +*.iws +*.jar +*.sw? +*~ +.#* +.*.md.html +.DS_Store +.classpath +.factorypath +.gradle +.idea +.metadata +.project +.recommenders +.settings +.springBeans +/build +/code +MANIFEST.MF +_site/ +activemq-data +bin +build +build.log +dependency-reduced-pom.xml +dump.rdb +interpolated*.xml +lib/ +manifest.yml +overridedb.* +target +transaction-logs +.flattened-pom.xml +secrets.yml +.gradletasknamecache +.sts4-cache diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/pom.xml b/spring-boot-modules/spring-boot-microservices/customer-service/pom.xml new file mode 100644 index 0000000000..a02ce2e1d8 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/pom.xml @@ -0,0 +1,85 @@ + + + + CustomerOrderApp + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + com.baeldung.customerservice + customer-service + jar + + + 1.8 + 1.8 + 1.8 + UTF-8 + + + + + + org.springframework.boot + spring-boot-dependencies + 2.3.0.RELEASE + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-json + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-configuration-processor + + + junit + junit + test + + + com.baeldung.orderservice + order-client + 1.0-SNAPSHOT + compile + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + exec + + + + + + + + diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/Customer.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/Customer.java new file mode 100644 index 0000000000..7d10510cbc --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/Customer.java @@ -0,0 +1,14 @@ +package com.baeldung.customerservice; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Customer { + + private int id; + private String firstName; + private String lastName; + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerApplication.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerApplication.java new file mode 100644 index 0000000000..489129a3d2 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerApplication.java @@ -0,0 +1,25 @@ +package com.baeldung.customerservice; + +import com.baeldung.orderservice.client.OrderClient; +import com.baeldung.orderservice.client.OrderClientImpl; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; + +/** + * Spring Boot application starter class + */ +@SpringBootApplication +public class CustomerApplication { + public static void main(String[] args) { + SpringApplication.run(CustomerApplication.class, args); + } + + @Bean + public OrderClient getOrderClient() { + + return new OrderClientImpl(new RestTemplateBuilder()); + } + +} diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerService.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerService.java new file mode 100644 index 0000000000..ab8872de1c --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerService.java @@ -0,0 +1,56 @@ +package com.baeldung.customerservice; + +import com.baeldung.orderservice.client.OrderClient; +import com.baeldung.orderservice.client.OrderDTO; +import com.baeldung.orderservice.client.OrderResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +@RestController +public class CustomerService { + + @Autowired + private OrderClient orderClient; + + private List customers = Arrays.asList( + + new Customer(1, "John", "Smith"), + new Customer(2, "Deny", "Dominic")); + + + @GetMapping + public List getAllCustomers() { + return customers; + } + + @GetMapping("/{id}") + public Customer getCustomerById(@PathVariable int id) { + return customers.stream() + .filter(customer -> customer.getId() == id) + .findFirst() + .orElseThrow(IllegalArgumentException::new); + } + + + @PostMapping(value = "/order") + public String sendOrder(@RequestBody Map body) { + + OrderDTO dto = new OrderDTO(); + dto.setCustomerId((Integer) body.get("customerId")); + dto.setItemId((String) body.get("itemId")); + + OrderResponse response = orderClient.order(dto); + + return response.getStatus(); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/resources/application.properties new file mode 100644 index 0000000000..d439ae9b76 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/resources/application.properties @@ -0,0 +1,4 @@ +#Spring Boot server configuration +server.servlet.context-path=/customer-service +server.port=8001 + diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/test/java/com/baeldung/customerservice/CustomerServiceTest.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/java/com/baeldung/customerservice/CustomerServiceTest.java new file mode 100644 index 0000000000..1c44146811 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/java/com/baeldung/customerservice/CustomerServiceTest.java @@ -0,0 +1,33 @@ +package com.baeldung.customerservice; + +import com.baeldung.orderservice.client.OrderClient; +import com.baeldung.orderservice.client.OrderDTO; +import com.baeldung.orderservice.client.OrderResponse; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = CustomerApplication.class) +public class CustomerServiceTest { + + @Autowired + private OrderClient orderClient; + + @Test + public void testAddOrderSuccess(){ + + + OrderDTO dto = new OrderDTO(2,"A152"); + + OrderResponse response = orderClient.order(dto); + + Assert.assertNotNull("Order Id not generated", response.getOrderId()); + Assert.assertEquals("A152", response.getProductId()); + Assert.assertEquals("CREATED", response.getStatus()); + } + +} diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/test/resources/application.properties b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/resources/application.properties new file mode 100644 index 0000000000..1d50559005 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/resources/application.properties @@ -0,0 +1,2 @@ +local.server.port=8001 +server.servlet.context-path=/customer-service \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/order-service/.gitignore b/spring-boot-modules/spring-boot-microservices/order-service/.gitignore new file mode 100644 index 0000000000..0e9415ada6 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/.gitignore @@ -0,0 +1,41 @@ +#https://github.com/spring-projects/spring-boot/blob/master/.gitignore + +*# +*.iml +*.ipr +*.iws +*.jar +*.sw? +*~ +.#* +.*.md.html +.DS_Store +.classpath +.factorypath +.gradle +.idea +.metadata +.project +.recommenders +.settings +.springBeans +/build +/code +MANIFEST.MF +_site/ +activemq-data +bin +build +build.log +dependency-reduced-pom.xml +dump.rdb +interpolated*.xml +lib/ +manifest.yml +overridedb.* +target +transaction-logs +.flattened-pom.xml +secrets.yml +.gradletasknamecache +.sts4-cache diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/pom.xml b/spring-boot-modules/spring-boot-microservices/order-service/order-client/pom.xml new file mode 100644 index 0000000000..22176bb85e --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + com.baeldung.orderservice + order-service + 1.0-SNAPSHOT + + order-client + com.baeldung.orderservice + order-client + Order service client module + http://projects.spring.io/spring-boot/ + + diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClient.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClient.java new file mode 100644 index 0000000000..2dd6b13248 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClient.java @@ -0,0 +1,6 @@ +package com.baeldung.orderservice.client; + +public interface OrderClient { + + OrderResponse order(OrderDTO orderDTO); +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClientImpl.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClientImpl.java new file mode 100644 index 0000000000..70ec77fab6 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClientImpl.java @@ -0,0 +1,35 @@ +package com.baeldung.orderservice.client; + +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + + +@Component +public class OrderClientImpl implements OrderClient { + + private RestTemplate restTemplate; + + public OrderClientImpl(RestTemplateBuilder builder) { + + this.restTemplate = builder.build(); + } + + @Override + public OrderResponse order(OrderDTO orderDTO) { + + String serviceUrl = "http://localhost:8002/order-service"; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity request = new HttpEntity<>(orderDTO, headers); + + OrderResponse orderResponse = restTemplate.postForObject(serviceUrl + "/create", request, OrderResponse.class); + + return orderResponse; + + } +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderDTO.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderDTO.java new file mode 100644 index 0000000000..c31c9f6bec --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderDTO.java @@ -0,0 +1,16 @@ +package com.baeldung.orderservice.client; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OrderDTO { + + private int customerId; + private String itemId; + +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderResponse.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderResponse.java new file mode 100644 index 0000000000..e8d2059cbb --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderResponse.java @@ -0,0 +1,15 @@ +package com.baeldung.orderservice.client; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class OrderResponse { + + private int orderId; + private String productId; + private String status; +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/resources/application.properties new file mode 100644 index 0000000000..53e503689f --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=8002 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/pom.xml b/spring-boot-modules/spring-boot-microservices/order-service/order-server/pom.xml new file mode 100644 index 0000000000..722bfa5aac --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/pom.xml @@ -0,0 +1,29 @@ + + + + order-service + com.baeldung.orderservice + 1.0-SNAPSHOT + + 4.0.0 + + com.baeldung.orderservice + order-server + + + com.baeldung.orderservice + order-client + 1.0-SNAPSHOT + compile + + + com.baeldung.paymentservice + payment-client + 1.0-SNAPSHOT + compile + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/Order.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/Order.java new file mode 100644 index 0000000000..719305064f --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/Order.java @@ -0,0 +1,18 @@ +package com.baeldung.orderservice; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Order { + + private Integer id; + private Integer customerId; + private String itemId; + private String date; + +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderApplication.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderApplication.java new file mode 100644 index 0000000000..2d09479a57 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderApplication.java @@ -0,0 +1,24 @@ +package com.baeldung.orderservice; + +import com.baeldung.paymentservice.PaymentClient; +import com.baeldung.paymentservice.PaymentClientImpl; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; + +/** + * Spring Boot application starter class + */ +@SpringBootApplication +public class OrderApplication { + public static void main(String[] args) { + SpringApplication.run(OrderApplication.class, args); + } + + @Bean + public PaymentClient getPaymentClient() { + + return new PaymentClientImpl(new RestTemplateBuilder()); + } +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderService.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderService.java new file mode 100644 index 0000000000..5ad66e1052 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderService.java @@ -0,0 +1,75 @@ +package com.baeldung.orderservice; + +import com.baeldung.orderservice.client.OrderDTO; +import com.baeldung.orderservice.client.OrderResponse; +import com.baeldung.paymentservice.PaymentClient; +import com.baeldung.paymentservice.PaymentDTO; +import com.baeldung.paymentservice.PaymentResponse; +import org.apache.commons.lang.time.DateFormatUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@RestController +public class OrderService { + + @Autowired + private PaymentClient paymentClient; + + private List orders = Arrays.asList( + + new Order(1, 1, "A101", "2020/02/14"), + new Order(2, 1, "A101", "2020/02/14"), + new Order(3, 2, "A150", "2020/02/17")); + + @GetMapping + public List getAllOrders() { + return orders; + } + + @GetMapping("/{id}") + public List getOrdersByCustomer(@PathVariable int id) { + return orders.stream() + .filter(order -> order.getCustomerId() == id).collect(Collectors.toList()); + } + + @PostMapping("/create") + public OrderResponse createOrder(@RequestBody OrderDTO request) { + + int lastIndex = orders.size(); + Order order = new Order(); + order.setId(lastIndex + 1); + order.setCustomerId(request.getCustomerId()); + order.setItemId(request.getItemId()); + String date = DateFormatUtils.format(new Date(), "yyyy/MM/dd"); + order.setDate(date); + + return new OrderResponse(order.getId(), order.getItemId(), "CREATED"); + } + + @PostMapping("/pay/{orderNumber}") + public PaymentResponse sendPayment(@PathVariable String orderNumber, @RequestBody Map body) { + + PaymentDTO dto = new PaymentDTO(); + dto.setFirstName((String) body.get("firstName")); + dto.setLastName((String) body.get("lastName")); + dto.setCardNumber((String) body.get("cardNumber")); + dto.setAmount((Double) body.get("amount")); + dto.setCurrency((String) body.get("currency")); + + PaymentResponse paymentResponse = paymentClient.pay(orderNumber, dto); + + return paymentResponse; + + } +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/resources/application.properties new file mode 100644 index 0000000000..f4fe5e7079 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/resources/application.properties @@ -0,0 +1,4 @@ +#Spring Boot server configuration +server.servlet.context-path=/order-service +server.port=8002 + diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/test/java/com/baeldung/orderservice/OrderServiceTest.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/test/java/com/baeldung/orderservice/OrderServiceTest.java new file mode 100644 index 0000000000..2630f908be --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/test/java/com/baeldung/orderservice/OrderServiceTest.java @@ -0,0 +1,35 @@ +package com.baeldung.orderservice; + +import com.baeldung.paymentservice.PaymentClient; +import com.baeldung.paymentservice.PaymentDTO; +import com.baeldung.paymentservice.PaymentResponse; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = OrderApplication.class) +public class OrderServiceTest { + + @Autowired + private PaymentClient paymentClient; + + + @Test + public void testSendPaySuccess(){ + + + PaymentDTO dto = new PaymentDTO("Sasa","Milenkovic","4260-6720-3283-7081",150.0,"USD"); + + PaymentResponse response = paymentClient.pay("A152", dto); + + Assert.assertNotNull("Payment Id not generated", response.getPaymentId()); + Assert.assertEquals("CREDITCARD", response.getPaymentMethod()); + Assert.assertEquals("Sasa Milenkovic", response.getCustomerFullName()); + Assert.assertEquals(new Double(150.0), response.getAmount()); + Assert.assertEquals("USD", response.getCurrency()); + } +} diff --git a/spring-boot-modules/spring-boot-microservices/order-service/pom.xml b/spring-boot-modules/spring-boot-microservices/order-service/pom.xml new file mode 100644 index 0000000000..603b845cef --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/order-service/pom.xml @@ -0,0 +1,108 @@ + + + + CustomerOrderApp + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + com.baeldung.orderservice + order-service + pom + + order-client + order-server + + + + 1.8 + 2.6 + 1.8 + 1.8 + UTF-8 + com.baeldung.orderservice.OrderApplication + + + + + + org.springframework.boot + spring-boot-dependencies + 2.3.0.RELEASE + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + commons-lang + commons-lang + ${commons-lang.version} + + + org.springframework.boot + spring-boot-starter-json + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-configuration-processor + + + org.springframework.boot + spring-boot-test-autoconfigure + test + + + junit + junit + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + ${orderservice.mainclass} + + + + + repackage + + + exe + + + + start-application + + com.baeldung.orderservice.OrderApplication + ../order-server/target/classes + + + start + + + + + + + + diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/.gitignore b/spring-boot-modules/spring-boot-microservices/payment-service/.gitignore new file mode 100644 index 0000000000..0e9415ada6 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/.gitignore @@ -0,0 +1,41 @@ +#https://github.com/spring-projects/spring-boot/blob/master/.gitignore + +*# +*.iml +*.ipr +*.iws +*.jar +*.sw? +*~ +.#* +.*.md.html +.DS_Store +.classpath +.factorypath +.gradle +.idea +.metadata +.project +.recommenders +.settings +.springBeans +/build +/code +MANIFEST.MF +_site/ +activemq-data +bin +build +build.log +dependency-reduced-pom.xml +dump.rdb +interpolated*.xml +lib/ +manifest.yml +overridedb.* +target +transaction-logs +.flattened-pom.xml +secrets.yml +.gradletasknamecache +.sts4-cache diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/pom.xml b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/pom.xml new file mode 100644 index 0000000000..19c1bb7e39 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + payment-service + com.baeldung.paymentservice + 1.0-SNAPSHOT + + + + com.baeldung.paymentservice + payment-client + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClient.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClient.java new file mode 100644 index 0000000000..f9e24725b8 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClient.java @@ -0,0 +1,6 @@ +package com.baeldung.paymentservice; + +public interface PaymentClient { + + PaymentResponse pay (String orderNumber, PaymentDTO paymentDTO); +} diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClientImpl.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClientImpl.java new file mode 100644 index 0000000000..87609b098e --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClientImpl.java @@ -0,0 +1,35 @@ +package com.baeldung.paymentservice; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +public class PaymentClientImpl implements PaymentClient { + + private RestTemplate restTemplate; + + public PaymentClientImpl(RestTemplateBuilder builder) { + + this.restTemplate = builder.build(); + } + + @Override + public PaymentResponse pay(String orderNumber, PaymentDTO paymentDTO) { + + String serviceUrl = "http://localhost:8003/payment-service"; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity request = new HttpEntity<>(paymentDTO, headers); + + PaymentResponse paymentResponse = restTemplate.postForObject(serviceUrl + "/pay/" + orderNumber, request, PaymentResponse.class); + + return paymentResponse; + + } +} diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentDTO.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentDTO.java new file mode 100644 index 0000000000..cd81b78366 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentDTO.java @@ -0,0 +1,17 @@ +package com.baeldung.paymentservice; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PaymentDTO { + + private String firstName; + private String lastName; + private String cardNumber; + private double amount; + private String currency; +} diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentResponse.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentResponse.java new file mode 100644 index 0000000000..4a155d4571 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentResponse.java @@ -0,0 +1,18 @@ +package com.baeldung.paymentservice; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PaymentResponse{ + + private String paymentId; + private String paymentMethod; + private String customerFullName; + private Double amount; + private String currency; + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/pom.xml b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/pom.xml new file mode 100644 index 0000000000..eb429553dd --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + + com.baeldung.paymentservice + payment-service + 1.0-SNAPSHOT + + com.baeldung.paymentservice + payment-server + payment-server + + + com.baeldung.paymentservice + payment-client + 1.0-SNAPSHOT + compile + + + diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/CardValidator.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/CardValidator.java new file mode 100644 index 0000000000..e4f0a3a68a --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/CardValidator.java @@ -0,0 +1,31 @@ +package com.baeldung.paymentservice; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CardValidator { + + public static boolean validate(String cardNumber){ + + boolean isValid = false; + + String regex = "^(?:(?4[0-9]{12}(?:[0-9]{3})?)|" + + "(?5[1-5][0-9]{14})|" + + "(?6(?:011|5[0-9]{2})[0-9]{12})|" + + "(?3[47][0-9]{13})|" + + "(?3(?:0[0-5]|[68][0-9])?[0-9]{11})|" + + "(?(?:2131|1800|35[0-9]{3})[0-9]{11}))$"; + + + Pattern pattern = Pattern.compile(regex); + cardNumber = cardNumber.replaceAll("-", ""); + Matcher matcher = pattern.matcher(cardNumber); + + if(matcher.matches()){ + + isValid = true; + } + + return isValid; + } +} diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/Payment.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/Payment.java new file mode 100644 index 0000000000..9789195c98 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/Payment.java @@ -0,0 +1,19 @@ +package com.baeldung.paymentservice; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Payment { + + private String paymentId; + private String paymentMethod; + private String customerFullName; + private double amount; + private String currency; + +} + diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentApplication.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentApplication.java new file mode 100644 index 0000000000..0e9336dcfe --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.paymentservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * + * Spring Boot application starter class + */ +@SpringBootApplication +public class PaymentApplication { + public static void main(String[] args) { + SpringApplication.run(PaymentApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentService.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentService.java new file mode 100644 index 0000000000..f44e342cd7 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentService.java @@ -0,0 +1,39 @@ +package com.baeldung.paymentservice; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.smartcardio.CardException; +import java.util.UUID; + + +@RestController +public class PaymentService { + + + @PostMapping("/pay/{orderNum}") + public PaymentResponse createPayment(@PathVariable String orderNum, @RequestBody PaymentDTO paymentDTO) { + + Payment payment = new Payment(); + payment.setPaymentId(UUID.randomUUID().toString().replace("-", "")); + String firstName = paymentDTO.getFirstName(); + String lastName = paymentDTO.getLastName(); + payment.setCustomerFullName(firstName + " " + lastName); + String cardNumber = paymentDTO.getCardNumber(); + + if(CardValidator.validate(cardNumber)){ + payment.setPaymentMethod("CREDITCARD"); + } else try { + throw new CardException("Card with number:"+ cardNumber + " is invalid"); + } catch (CardException e) { + e.printStackTrace(); + } + payment.setAmount(paymentDTO.getAmount()); + payment.setCurrency(paymentDTO.getCurrency()); + + return new PaymentResponse(payment.getPaymentId(), payment.getPaymentMethod(), payment.getCustomerFullName(), payment.getAmount(), payment.getCurrency()); + + } +} diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/resources/application.properties new file mode 100644 index 0000000000..8f3550946e --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/resources/application.properties @@ -0,0 +1,3 @@ +#Spring Boot server configuration +server.servlet.context-path=/payment-service +server.port=8003 diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/pom.xml b/spring-boot-modules/spring-boot-microservices/payment-service/pom.xml new file mode 100644 index 0000000000..474ab6fe93 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/payment-service/pom.xml @@ -0,0 +1,110 @@ + + + + CustomerOrderApp + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + com.baeldung.paymentservice + payment-service + pom + + payment-client + payment-server + + + + 1.8 + 2.6 + 1.8 + 1.8 + UTF-8 + com.baeldung.paymentservice.PaymentApplication + + + + + + org.springframework.boot + spring-boot-dependencies + 2.3.0.RELEASE + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + commons-lang + commons-lang + ${commons-lang.version} + + + + org.springframework.boot + spring-boot-starter-json + + + + org.springframework.boot + spring-boot-test + test + + + + org.springframework.boot + spring-boot-test-autoconfigure + test + + + junit + junit + test + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + ${paymentservice.mainclass} + + + + + repackage + + + exe + + + + start-application + + com.baeldung.paymentservice.PaymentApplication + ../payment-server/target/classes + + + start + + + + + + + + diff --git a/spring-boot-modules/spring-boot-microservices/pom.xml b/spring-boot-modules/spring-boot-microservices/pom.xml new file mode 100644 index 0000000000..1cdd7595d4 --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + com.baeldung + CustomerOrderApp + pom + 1.0-SNAPSHOT + CustomerOrderApp + http://maven.apache.org + + + org.springframework.boot + spring-boot-starter-parent + 2.3.0.RELEASE + + + + + UTF-8 + 1.8 + 1.8 + + + + customer-service + order-service + payment-service + + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-autoconfigure + + + diff --git a/spring-boot-modules/spring-boot-microservices/postman/customer-order.postman_collection b/spring-boot-modules/spring-boot-microservices/postman/customer-order.postman_collection new file mode 100644 index 0000000000..aa9960aead --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/postman/customer-order.postman_collection @@ -0,0 +1,87 @@ +{ + "info": { + "_postman_id": "92594398-49cc-4a7c-b44f-1037307afbd3", + "name": "postman-requests", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Crete new Customer order", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "multipart/form-data", + "type": "text", + "disabled": true + }, + { + "key": "Accept-Charset", + "value": "utf-8", + "type": "text", + "disabled": true + }, + { + "key": "boundary", + "value": "nAp4nMEt-BuGuuLlq-6fnASQErGjSamaG", + "type": "text", + "disabled": true + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"customerId\":2,\n \"itemId\":\"A152\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8001/customer-service/order", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8001", + "path": [ + "customer-service", + "order" + ] + } + }, + "response": [] + }, + { + "name": "Send Order for payment", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n\t\n\"firstName\":\"John\",\n\"lastName\":\"Smith\",\n\"cardNumber\":\"4260-6720-3283-7081\",\n\"amount\":150.0,\n\"currency\":\"USD\"\n\t\n\t\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "localhost:8002/order-service/pay/A152", + "host": [ + "localhost" + ], + "port": "8002", + "path": [ + "order-service", + "pay", + "A152" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-microservices/src/main/java/com/baeldung/CustomerOrderApp.java b/spring-boot-modules/spring-boot-microservices/src/main/java/com/baeldung/CustomerOrderApp.java new file mode 100644 index 0000000000..15455ca16c --- /dev/null +++ b/spring-boot-modules/spring-boot-microservices/src/main/java/com/baeldung/CustomerOrderApp.java @@ -0,0 +1,23 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +/** + * Customer Order Spring Boot Main Application + * + * */ + +@SpringBootApplication +@ComponentScan(basePackages = "com.baeldung.*") +public class CustomerOrderApp +{ + + public static void main( String[] args ) + { + + SpringApplication.run(CustomerOrderApp.class,args); + + } +}