diff --git a/gateway/pom.xml b/gateway/pom.xml
index 8bea519..97cfbe4 100644
--- a/gateway/pom.xml
+++ b/gateway/pom.xml
@@ -1,43 +1,36 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
-
-
- dev.snowdrop
- snowdrop-dependencies
- 2.2.6.SP1-redhat-00001
-
-
+
io.konveyor.demo
gateway
2.0.0-SNAPSHOT
- 11
- 11
- 1.4.0.Final
- 1.18.2
- latest
- 2.2.6.RELEASE
- registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift:${openjdk18-openshift.version}
+ 3.13.0
+ 17
+ 3.2.5
+ 3.2.4
+ 2023.0.1
+ 2.1.2
- org.jboss.arquillian
- arquillian-bom
- ${arquillian.version}
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
pom
import
- org.arquillian.cube
- arquillian-cube-bom
- ${arquillian-cube.version}
- import
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
pom
+ import
@@ -47,48 +40,44 @@
org.springframework.boot
spring-boot-starter-web
-
- org.springframework.boot
- spring-boot-starter-tomcat
-
-
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
- spring-boot-starter-data-jpa
+ spring-boot-starter-aop
- org.springframework.cloud
- spring-cloud-starter-netflix-hystrix
- 2.1.5.RELEASE
+ org.springframework.data
+ spring-data-commons
- ch.qos.logback
- logback-core
+ io.micrometer
+ micrometer-registry-prometheus
+
+
- ch.qos.logback
- logback-classic
+ io.micrometer
+ micrometer-tracing-bridge-otel
+
- org.projectlombok
- lombok
+ io.opentelemetry
+ opentelemetry-exporter-otlp
+
- io.opentracing.contrib
- opentracing-spring-jaeger-web-starter
+ org.springframework.cloud
+ spring-cloud-starter-circuitbreaker-resilience4j
- io.opentracing.contrib
- opentracing-spring-cloud-starter
- 0.5.4
+ org.projectlombok
+ lombok
+ true
+
org.springframework.boot
@@ -96,25 +85,21 @@
test
- com.h2database
- h2
- test
-
-
- io.rest-assured
- rest-assured
- test
-
-
- org.awaitility
- awaitility
+ org.assertj
+ assertj-core
test
- org.assertj
- assertj-core
+ org.springframework.cloud
+ spring-cloud-starter-contract-stub-runner
test
+
+
+
+
+
+
@@ -123,27 +108,18 @@
org.springframework.boot
spring-boot-maven-plugin
-
- local
-
exec
+
+
+ org.projectlombok
+ lombok
+
+
-
-
-
- repackage
-
-
-
-
- redhat-early-access
- Red Hat Early Access Repository
- https://maven.repository.redhat.com/earlyaccess/all/
-
redhat-ga
Red Hat GA Repository
@@ -151,100 +127,10 @@
-
- redhat-early-access
- Red Hat Early Access Repository
- https://maven.repository.redhat.com/earlyaccess/all/
-
redhat-ga
Red Hat GA Repository
https://maven.repository.redhat.com/ga/
-
-
- local
-
-
-
-
-
- openshift
-
-
- org.postgresql
- postgresql
- runtime
-
-
-
- true
-
-
-
- openshift-manual
-
-
- org.postgresql
- postgresql
- runtime
-
-
-
-
-
-
- io.fabric8
- fabric8-maven-plugin
-
-
- fmp
- package
-
- resource
- build
-
-
-
-
-
-
-
-
- openshift-it
-
-
-
- org.apache.maven.plugins
- maven-failsafe-plugin
-
-
-
- integration-test
- verify
-
-
-
-
-
-
-
-
-
- io.fabric8
- kubernetes-client
- 1.4.34
- test
-
-
- io.fabric8
- openshift-client
- 1.4.34
- test
-
-
-
-
-
\ No newline at end of file
diff --git a/gateway/src/main/java/META-INF/MANIFEST.MF b/gateway/src/main/java/META-INF/MANIFEST.MF
deleted file mode 100644
index 5e94951..0000000
--- a/gateway/src/main/java/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Class-Path:
-
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/Application.java b/gateway/src/main/java/io/konveyor/demo/gateway/Application.java
index 35afaec..b36379c 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/Application.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/Application.java
@@ -2,37 +2,10 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
-import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
-import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
-import org.springframework.context.annotation.Bean;
-import org.springframework.web.client.RestTemplate;
-import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
-
-@SpringBootApplication(exclude = {
- DataSourceAutoConfiguration.class,
- DataSourceTransactionManagerAutoConfiguration.class,
- HibernateJpaAutoConfiguration.class
- })
-@EnableCircuitBreaker
-public class Application
-{
-
+@SpringBootApplication
+public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
- }
-
-
- @Bean
- public RestTemplate restTemplate() {
- return new RestTemplate();
- }
-
- @Bean
- public HystrixCommandAspect hystrixAspect() {
- return new HystrixCommandAspect();
- }
-
+ }
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/command/ProductCommand.java b/gateway/src/main/java/io/konveyor/demo/gateway/command/ProductCommand.java
deleted file mode 100644
index 072f23d..0000000
--- a/gateway/src/main/java/io/konveyor/demo/gateway/command/ProductCommand.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package io.konveyor.demo.gateway.command;
-
-import io.konveyor.demo.gateway.model.OrderItem;
-import io.konveyor.demo.gateway.model.Product;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import com.netflix.hystrix.HystrixCommand;
-import com.netflix.hystrix.HystrixCommandGroupKey;
-import com.netflix.hystrix.HystrixThreadPoolKey;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class ProductCommand extends HystrixCommand{
- private OrderItem item;
-
- String inventoryServiceURL;
-
- RestTemplate restTemplate;
-
- public ProductCommand(OrderItem item, String inventoryServiceURL, RestTemplate restTemplate){
- super( HystrixCommandGroupKey.Factory.asKey( "Products" ), HystrixThreadPoolKey.Factory.asKey( "ProductsThreads" ) );
- this.item = item;
- this.inventoryServiceURL = inventoryServiceURL;
- this.restTemplate = restTemplate;
- }
-
- @Override
- protected OrderItem run() throws Exception {
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromHttpUrl(inventoryServiceURL)
- .pathSegment( "{product}");
- Product p = restTemplate.getForObject(
- builder.buildAndExpand(item.getProduct().getId()).toUriString(),
- Product.class);
- if (p != null) {
- item.setProduct(p);
- }
- return item;
- }
-
- @Override
- protected OrderItem getFallback() {
- log.warn( "Failed to obtain product, " + getFailedExecutionException().getMessage() + " for order line " + item );
- return item;
- }
-
-}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/controller/CustomersController.java b/gateway/src/main/java/io/konveyor/demo/gateway/controller/CustomersController.java
index b36d2b7..8c0cd9f 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/controller/CustomersController.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/controller/CustomersController.java
@@ -1,52 +1,40 @@
package io.konveyor.demo.gateway.controller;
-import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
-import io.konveyor.demo.gateway.model.Customer;
-import io.konveyor.demo.gateway.service.CustomersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
-import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
+import io.konveyor.demo.gateway.model.Customer;
+import io.konveyor.demo.gateway.service.CustomersService;
import lombok.extern.slf4j.Slf4j;
@RestController
-@RequestMapping("/customers")
-@Component
+@RequestMapping(path = "/customers", produces = MediaType.APPLICATION_JSON_VALUE)
@Slf4j
public class CustomersController {
-
@Autowired
private CustomersService customerService;
-
- @Autowired
- Tracer tracer;
-
- @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
- public Customer getById(@PathVariable("id") Long id) {
- Customer c;
- Span span = tracer.buildSpan("getById").start();
- try{
- log.debug("Entering CustomerController.getById()");
- c = customerService.getById(id);
- if (c == null) {
- throw new ResourceNotFoundException("Requested customer doesn't exist");
- }
- log.debug("Returning element: " + c);
- } finally {
- span.finish();
+
+ @GetMapping("/{id}")
+ public Customer getById(@PathVariable("id") Long id) {
+ log.debug("Entering CustomerController.getById()");
+ var c = customerService.getById(id);
+
+ if (c == null) {
+ throw new ResourceNotFoundException("Requested customer doesn't exist");
}
+
+ log.debug("Returning element: " + c);
return c;
}
- @RequestMapping
+ @GetMapping
public Page findAll(Pageable pageable){
return customerService.findAll(pageable);
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/controller/InventoryController.java b/gateway/src/main/java/io/konveyor/demo/gateway/controller/InventoryController.java
index 051fbfe..1969be6 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/controller/InventoryController.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/controller/InventoryController.java
@@ -1,52 +1,42 @@
package io.konveyor.demo.gateway.controller;
-import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
-import io.konveyor.demo.gateway.model.Product;
-import io.konveyor.demo.gateway.service.InventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
-import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
+import io.konveyor.demo.gateway.model.Product;
+import io.konveyor.demo.gateway.service.InventoryService;
import lombok.extern.slf4j.Slf4j;
@RestController
-@RequestMapping("/products")
-@Component
+@RequestMapping(path = "/products", produces = MediaType.APPLICATION_JSON_VALUE)
@Slf4j
public class InventoryController {
-
+
@Autowired
private InventoryService inventoryService;
-
- @Autowired
- Tracer tracer;
-
- @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
- public Product getById(@PathVariable("id") Long id) {
- Product p;
- Span span = tracer.buildSpan("getById").start();
- try{
- log.debug("Entering InventoryController.getById()");
- p = inventoryService.getById(id);
- if (p == null) {
- throw new ResourceNotFoundException("Requested product doesn't exist");
- }
- log.debug("Returning element: " + p);
- } finally {
- span.finish();
+
+
+ @GetMapping("/{id}")
+ public Product getById(@PathVariable("id") Long id) {
+ log.debug("Entering InventoryController.getById()");
+ var p = inventoryService.getById(id);
+
+ if (p == null) {
+ throw new ResourceNotFoundException("Requested product doesn't exist");
}
+
+ log.debug("Returning element: " + p);
return p;
}
-
- @RequestMapping
+
+ @GetMapping
public Page findAll(Pageable pageable){
return inventoryService.findAll(pageable);
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/controller/OrdersController.java b/gateway/src/main/java/io/konveyor/demo/gateway/controller/OrdersController.java
index 82f9864..31c4f44 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/controller/OrdersController.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/controller/OrdersController.java
@@ -1,52 +1,41 @@
package io.konveyor.demo.gateway.controller;
-import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
-import io.konveyor.demo.gateway.model.Order;
-import io.konveyor.demo.gateway.service.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
-import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
+import io.konveyor.demo.gateway.model.Order;
+import io.konveyor.demo.gateway.service.OrdersService;
import lombok.extern.slf4j.Slf4j;
@RestController
-@RequestMapping("/orders")
-@Component
+@RequestMapping(path = "/orders", produces = MediaType.APPLICATION_JSON_VALUE)
@Slf4j
public class OrdersController {
@Autowired
private OrdersService orderService;
-
- @Autowired
- Tracer tracer;
-
- @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
- public Order getById(@PathVariable("id") Long id) {
- Order o;
- Span span = tracer.buildSpan("getById").start();
- try{
- log.debug("Entering OrderController.getById()");
- o = orderService.getById(id);
- if (o == null) {
- throw new ResourceNotFoundException("Requested order doesn't exist");
- }
- log.debug("Returning element: " + o);
- } finally {
- span.finish();
+
+ @GetMapping("/{id}")
+ public Order getById(@PathVariable("id") Long id) {
+ log.debug("Entering OrderController.getById()");
+ var o = orderService.getById(id);
+
+ if (o == null) {
+ throw new ResourceNotFoundException("Requested order doesn't exist");
}
+
+ log.debug("Returning element: " + o);
return o;
}
-
- @RequestMapping
+
+ @GetMapping
public Page findAll(Pageable pageable){
return orderService.findAll(pageable);
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/exception/handler/ExceptionHandlingController.java b/gateway/src/main/java/io/konveyor/demo/gateway/exception/handler/ExceptionHandlingController.java
index 5a96490..9326bf7 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/exception/handler/ExceptionHandlingController.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/exception/handler/ExceptionHandlingController.java
@@ -1,19 +1,18 @@
package io.konveyor.demo.gateway.exception.handler;
-import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import io.konveyor.demo.gateway.exception.ResourceNotFoundException;
import lombok.extern.slf4j.Slf4j;
-@ControllerAdvice
+@RestControllerAdvice
@Slf4j
public class ExceptionHandlingController {
- @ResponseStatus(value = HttpStatus.NOT_FOUND,
- reason = "Order not found")
+ @ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Order not found")
@ExceptionHandler(ResourceNotFoundException.class)
public void resourceNotFound(ResourceNotFoundException e) {
log.warn("Resource not found: " + e.getMessage());
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/model/Customer.java b/gateway/src/main/java/io/konveyor/demo/gateway/model/Customer.java
index baed07b..8ba3957 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/model/Customer.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/model/Customer.java
@@ -1,16 +1,17 @@
package io.konveyor.demo.gateway.model;
-import java.io.Serializable;
-
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
-public class Customer implements Serializable{
-
- private static final long serialVersionUID = -647167746768043097L;
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder(toBuilder = true)
+public class Customer {
private Long id;
private String username;
private String name;
@@ -19,5 +20,4 @@ public class Customer implements Serializable{
private String zipCode;
private String city;
private String country;
-
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/model/Order.java b/gateway/src/main/java/io/konveyor/demo/gateway/model/Order.java
index 4eea5bc..f5b1cea 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/model/Order.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/model/Order.java
@@ -1,31 +1,24 @@
package io.konveyor.demo.gateway.model;
-import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
-import io.konveyor.demo.gateway.serialization.CustomerDeserializer;
-
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-
+import io.konveyor.demo.gateway.serialization.CustomerDeserializer;
import lombok.Data;
-import lombok.ToString;
-@ToString(exclude = "items")
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
-public class Order implements Serializable {
-
- private static final long serialVersionUID = -1703065930151811237L;
+public class Order {
private Long id;
private Customer customer;
- @JsonFormat
- (shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy", timezone="CET")
+
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy", timezone="CET")
private Date date;
private List items;
@@ -39,7 +32,7 @@ public BigDecimal getTotalAmmount() {
return new BigDecimal(0);
}
}
-
+
@JsonProperty("customer")
public Customer getCustomer() {
return this.customer;
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderItem.java b/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderItem.java
index 9c68fc6..ef89892 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderItem.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderItem.java
@@ -1,27 +1,26 @@
package io.konveyor.demo.gateway.model;
-import java.io.Serializable;
import java.math.BigDecimal;
-import io.konveyor.demo.gateway.serialization.ProductDeserializer;
-
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-
+import io.konveyor.demo.gateway.serialization.ProductDeserializer;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
-public class OrderItem implements Serializable {
-
- private static final long serialVersionUID = 95662333489566465L;
-
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder(toBuilder = true)
+public class OrderItem {
private Product product;
private Integer quantity;
private BigDecimal price;
-
-
+
@JsonProperty("product")
public Product getProduct() {
return this.product;
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderSummary.java b/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderSummary.java
index cc74959..2dddba6 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderSummary.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/model/OrderSummary.java
@@ -1,14 +1,11 @@
package io.konveyor.demo.gateway.model;
-import java.io.Serializable;
import java.util.Date;
import lombok.Data;
@Data
-public class OrderSummary implements Serializable{
-
- private static final long serialVersionUID = 5290825002214978384L;
+public class OrderSummary {
private long id;
private String customerName;
private Date date;
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/model/Product.java b/gateway/src/main/java/io/konveyor/demo/gateway/model/Product.java
index 8689f53..16972f4 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/model/Product.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/model/Product.java
@@ -1,16 +1,17 @@
package io.konveyor.demo.gateway.model;
-import java.io.Serializable;
-
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
-public class Product implements Serializable{
-
- private static final long serialVersionUID = 1647872601694471121L;
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder(toBuilder = true)
+public class Product {
private Long id;
private String name;
private String description;
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/repository/CustomerRepository.java b/gateway/src/main/java/io/konveyor/demo/gateway/repository/CustomerRepository.java
index bf91a26..ebe03d9 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/repository/CustomerRepository.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/repository/CustomerRepository.java
@@ -3,82 +3,72 @@
import java.util.ArrayList;
import java.util.List;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.domain.Pageable;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
-import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.client.RestClient;
+import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
+import io.github.resilience4j.retry.annotation.Retry;
import io.konveyor.demo.gateway.model.Customer;
import io.konveyor.demo.util.PaginatedResponse;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.micrometer.tracing.annotation.NewSpan;
+import io.micrometer.tracing.annotation.SpanTag;
import lombok.extern.slf4j.Slf4j;
-@Component
+@Repository
@Slf4j
-public class CustomerRepository extends GenericRepository{
-
- @Autowired
- Tracer tracer;
-
- @Autowired
- RestTemplate restTemplate;
-
- @Value("${services.customers.url}")
- String customersServiceURL;
-
- @HystrixCommand(commandKey = "Customers", fallbackMethod = "getFallbackCustomer", commandProperties = {
- @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
- })
- public Customer getCustomerById(Long id) {
- Span span = tracer.buildSpan("getCustomerById").start();
+public class CustomerRepository extends GenericRepository {
+ private final RestClient restClient;
+
+ public CustomerRepository(RestClient.Builder restClientBuilder, @Value("${services.customers.url}") String customersServiceURL) {
+ this.restClient = restClientBuilder.baseUrl(customersServiceURL)
+ .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
+ .build();
+ }
+
+ @CircuitBreaker(name = "Customers", fallbackMethod = "getFallbackCustomer")
+ @Retry(name = "Customers", fallbackMethod = "getFallbackCustomer")
+ @NewSpan
+ public Customer getCustomerById(@SpanTag Long id) {
log.debug("Entering OrdersService.getCustomerById()");
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromHttpUrl(customersServiceURL)
- .pathSegment( "{customer}");
- Customer c = restTemplate.getForObject(
- builder.buildAndExpand(id).toUriString(),
- Customer.class);
+
+ var c = this.restClient.get()
+ .uri("/{id}", id)
+ .retrieve()
+ .body(Customer.class);
+
//Trigger fallback if no result is obtained.
if (c == null) {
throw new RuntimeException();
}
+
log.debug(c.toString());
- span.finish();
return c;
}
-
- @HystrixCommand(commandKey = "AllCustomers", fallbackMethod = "getFallbackCustomers", commandProperties = {
- @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
- })
- public List findAll(Pageable pageable) {
- Span span = tracer.buildSpan("findAll").start();
+
+ @CircuitBreaker(name = "AllCustomers", fallbackMethod = "getFallbackCustomers")
+ @Retry(name = "AllCustomers", fallbackMethod = "getFallbackCustomer")
+ @NewSpan
+ public List findAll(@SpanTag Pageable pageable) {
log.debug("Entering CustomerRepository.findAll()");
- UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(customersServiceURL)
+
+ return this.restClient.get()
+ .uri(uriBuilder -> uriBuilder
.queryParam("page", pageable.getPageNumber())
.queryParam("size", pageable.getPageSize())
- .queryParam("sort", getSortString(pageable));
- ResponseEntity> responseEntity =
- restTemplate.exchange(
- builder.toUriString(),
- HttpMethod.GET,
- null,
- new ParameterizedTypeReference>() {}
- );
- List customers = responseEntity.getBody().getContent();
- span.finish();
- return customers;
+ .queryParam("sort", getSortString(pageable))
+ .build()
+ )
+ .retrieve()
+ .body(new ParameterizedTypeReference>() {})
+ .getContent();
}
- public Customer getFallbackCustomer(Long id, Throwable e) {
+ public Customer getFallbackCustomer(Long id, Exception e) {
log.warn("Failed to obtain Customer, " + e.getMessage() + " for customer with id " + id);
Customer c = new Customer();
c.setId(id);
@@ -92,9 +82,8 @@ public Customer getFallbackCustomer(Long id, Throwable e) {
return c;
}
- public List getFallbackCustomers(Pageable pageable, Throwable e) {
+ public List getFallbackCustomers(Pageable pageable, Exception e) {
log.warn("Failed to obtain Customers, " + e.getMessage());
- return new ArrayList();
+ return new ArrayList<>();
}
-
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/repository/InventoryRepository.java b/gateway/src/main/java/io/konveyor/demo/gateway/repository/InventoryRepository.java
index 862e27e..9e3c8ee 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/repository/InventoryRepository.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/repository/InventoryRepository.java
@@ -1,129 +1,122 @@
package io.konveyor.demo.gateway.repository;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import io.konveyor.demo.gateway.command.ProductCommand;
-import io.konveyor.demo.gateway.model.OrderItem;
-import io.konveyor.demo.gateway.model.Product;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.domain.Pageable;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.client.RestClient;
-import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
-import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
-
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
+import io.github.resilience4j.retry.annotation.Retry;
+import io.konveyor.demo.gateway.model.OrderItem;
+import io.konveyor.demo.gateway.model.Product;
+import io.micrometer.tracing.annotation.NewSpan;
+import io.micrometer.tracing.annotation.SpanTag;
import lombok.extern.slf4j.Slf4j;
-import rx.Observable;
-@Component
+@Repository
@Slf4j
-public class InventoryRepository extends GenericRepository{
-
- @Autowired
- Tracer tracer;
-
- @Autowired
- RestTemplate restTemplate;
-
- @Value("${hystrix.threadpool.ProductsThreads.coreSize}")
- private int threadSize;
-
- @Value("${services.inventory.url}")
- String inventoryServiceURL;
-
- public List getProductDetails(List items){
- Span span = tracer.buildSpan("getProductDetails").start();
+public class InventoryRepository extends GenericRepository {
+ private final ApplicationContext applicationContext;
+ private final RestClient restClient;
+
+ public InventoryRepository(ApplicationContext applicationContext, RestClient.Builder restClientBuilder, @Value("${services.inventory.url}") String inventoryServiceURL) {
+ this.applicationContext = applicationContext;
+ this.restClient = restClientBuilder.baseUrl(inventoryServiceURL)
+ .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
+ .build();
+ }
+
+ @CircuitBreaker(name = "ProductDetails", fallbackMethod = "getFallbackProduct")
+ @Retry(name = "ProductDetails", fallbackMethod = "getFallbackProduct")
+ public Product getProduct(OrderItem item) {
+ return this.restClient.get()
+ .uri("/{id}", item.getProduct().getId())
+ .retrieve()
+ .body(Product.class);
+ }
+
+ @NewSpan
+ public List getProductDetails(@SpanTag List items) {
log.debug("Entering InventoryRepository.getProductDetails()");
- List detailedItems = new ArrayList<>();
- for(int index= 0; index < items.size();) {
- List> observables = new ArrayList<>();
- int batchLimit = Math.min( index + threadSize, items.size() );
- for( int batchIndex = index; batchIndex < batchLimit; batchIndex++ )
- {
- observables.add( new ProductCommand( items.get(batchIndex), inventoryServiceURL, restTemplate ).toObservable() );
- }
- log.info("Will get product detail from " + observables.size() + " items");
- Observable zipped = Observable.zip( observables, objects->
- {
- OrderItem[] detailed = new OrderItem[objects.length];
- for( int batchIndex = 0; batchIndex < objects.length; batchIndex++ )
- {
- detailed[batchIndex] = (OrderItem)objects[batchIndex];
+
+ return items.stream()
+ .map(item -> {
+ // Need to do this so that the annotations work
+ // If its just a local method call then none of the AOP stuff takes effect
+ var product = this.applicationContext.getBean(InventoryRepository.class).getProduct(item);
+ var i = item.toBuilder();
+
+ if (product != null) {
+ i.product(product);
}
- return detailed;
- } );
- Collections.addAll( detailedItems, zipped.toBlocking().first() );
- index += threadSize;
- }
- span.finish();
- return detailedItems;
+
+ return i.build();
+
+ })
+ .toList();
}
-
- @HystrixCommand(commandKey = "AllProducts", fallbackMethod = "getFallbackProducts", commandProperties = {
- @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
- })
- public List findAll(Pageable pageable) {
- Span span = tracer.buildSpan("findAll").start();
+
+ @CircuitBreaker(name = "AllProducts", fallbackMethod = "getFallbackProducts")
+ @Retry(name = "AllProducts", fallbackMethod = "getFallbackProducts")
+ @NewSpan
+ public List findAll(@SpanTag Pageable pageable) {
log.debug("Entering InventoryRepository.findAll()");
- UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(inventoryServiceURL)
+
+ return this.restClient.get()
+ .uri(uriBuilder -> uriBuilder
.queryParam("page", pageable.getPageNumber())
.queryParam("size", pageable.getPageSize())
- .queryParam("sort", getSortString(pageable));
- ResponseEntity> responseEntity =
- restTemplate.exchange(
- builder.toUriString(),
- HttpMethod.GET,
- null,
- new ParameterizedTypeReference>() {}
- );
- List orders = responseEntity.getBody();
- span.finish();
- return orders;
+ .queryParam("sort", getSortString(pageable))
+ .build()
+ )
+ .retrieve()
+ .body(new ParameterizedTypeReference<>() {});
}
-
- @HystrixCommand(commandKey = "Products", fallbackMethod = "getFallbackProduct", commandProperties = {
- @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
- })
- public Product getProductById(Long id) {
- Span span = tracer.buildSpan("getProductById").start();
+
+ @CircuitBreaker(name = "Products", fallbackMethod = "getFallbackProduct")
+ @Retry(name = "Products", fallbackMethod = "getFallbackProduct")
+ @NewSpan
+ public Product getProductById(@SpanTag Long id) {
log.debug("Entering InventoryRepository.getProductById()");
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromHttpUrl(inventoryServiceURL)
- .pathSegment( "{product}");
- Product p = restTemplate.getForObject(
- builder.buildAndExpand(id).toUriString(),
- Product.class);
+
+ var p = this.restClient.get()
+ .uri("/{id}", id)
+ .retrieve()
+ .body(Product.class);
+
//Trigger fallback if no result is obtained.
if (p == null) {
throw new RuntimeException();
}
log.debug(p.toString());
- span.finish();
return p;
}
-
- public List getFallbackProducts(Pageable pageable, Throwable e) {
+
+ public List getFallbackProducts(Pageable pageable, Exception e) {
log.warn("Failed to obtain Products, " + e.getMessage());
- return new ArrayList();
+ return new ArrayList<>();
}
-
- public Product getFallbackProduct(Long id, Throwable e) {
+
+ public Product getFallbackProduct(Long id, Exception e) {
log.warn("Failed to obtain Product, " + e.getMessage() + " for Product with id " + id);
- Product p = new Product();
- p.setId(id);
- p.setName("Unknown");
- p.setDescription("Unknown");
- return p;
+
+ return Product.builder()
+ .id(id)
+ .name("Unknown")
+ .description("Unknown")
+ .build();
}
+ public Product getFallbackProduct(OrderItem item, Exception e) {
+ return Product.builder()
+ .id(item.getProduct().getId())
+ .build();
+ }
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/repository/OrderRepository.java b/gateway/src/main/java/io/konveyor/demo/gateway/repository/OrderRepository.java
index cf4a300..f22e802 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/repository/OrderRepository.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/repository/OrderRepository.java
@@ -3,87 +3,81 @@
import java.util.ArrayList;
import java.util.List;
-import io.konveyor.demo.gateway.model.Order;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.domain.Pageable;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
-import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Repository;
+import org.springframework.web.client.RestClient;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
+import io.github.resilience4j.retry.annotation.Retry;
+import io.konveyor.demo.gateway.model.Order;
+import io.micrometer.tracing.annotation.NewSpan;
+import io.micrometer.tracing.annotation.SpanTag;
import lombok.extern.slf4j.Slf4j;
-@Component
+@Repository
@Slf4j
public class OrderRepository extends GenericRepository {
- @Autowired
- Tracer tracer;
-
- @Autowired
- RestTemplate restTemplate;
-
- @Value("${services.orders.url}")
- String ordersServiceURL;
-
- @HystrixCommand(commandKey = "Orders", fallbackMethod = "getFallbackOrder", commandProperties = {
- @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
- })
- public Order getOrderById(Long id) {
- Span span = tracer.buildSpan("getOrderById").start();
+ private final RestClient restClient;
+
+ public OrderRepository(RestClient.Builder restClientBuilder, @Value("${services.orders.url}") String ordersServiceURL) {
+ this.restClient = restClientBuilder.baseUrl(ordersServiceURL)
+ .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
+ .build();
+ }
+
+ @CircuitBreaker(name = "Orders", fallbackMethod = "getFallbackOrder")
+ @Retry(name = "Orders", fallbackMethod = "getFallbackOrder")
+ @NewSpan
+ public Order getOrderById(@SpanTag Long id) {
log.debug("Entering OrderRepository.getOrderById()");
- UriComponentsBuilder builder = UriComponentsBuilder
- .fromHttpUrl(ordersServiceURL)
- .pathSegment( "{order}");
- Order o = restTemplate.getForObject(
- builder.buildAndExpand(id).toUriString(),
- Order.class);
- if (o == null)
- log.debug("Obtained null order");
- else
- log.debug(o.toString());
- span.finish();
+
+ var o = this.restClient.get()
+ .uri("/{id}", id)
+ .retrieve()
+ .body(Order.class);
+
+ if (log.isDebugEnabled()) {
+ if (o == null) {
+ log.debug("Obtained null order");
+ }
+ else {
+ log.debug(o.toString());
+ }
+ }
+
return o;
}
- @HystrixCommand(commandKey = "AllOrders", fallbackMethod = "getFallbackOrders", commandProperties = {
- @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
- })
- public List findAll(Pageable pageable) {
- Span span = tracer.buildSpan("findAll").start();
+ @CircuitBreaker(name = "AllOrders", fallbackMethod = "getFallbackOrders")
+ @Retry(name = "AllOrders", fallbackMethod = "getFallbackOrders")
+ @NewSpan
+ public List findAll(@SpanTag Pageable pageable) {
log.debug("Entering OrderRepository.findAll()");
- UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(ordersServiceURL)
+
+ return this.restClient.get()
+ .uri(uriBuilder -> uriBuilder
.queryParam("page", pageable.getPageNumber())
.queryParam("size", pageable.getPageSize())
- .queryParam("sort", getSortString(pageable));
- ResponseEntity> responseEntity =
- restTemplate.exchange(
- builder.toUriString(),
- HttpMethod.GET,
- null,
- new ParameterizedTypeReference>() {}
- );
- List orders = responseEntity.getBody();
- span.finish();
- return orders;
+ .queryParam("sort", getSortString(pageable))
+ .build()
+ )
+ .retrieve()
+ .body(new ParameterizedTypeReference<>() {});
}
- public Order getFallbackOrder(Long id, Throwable e) {
+ public Order getFallbackOrder(Long id, Exception e) {
log.warn("Failed to obtain Order, " + e.getMessage() + " for order with id " + id);
return null;
}
- public List getFallbackOrders(Pageable pageable, Throwable e) {
+ public List getFallbackOrders(Pageable pageable, Exception e) {
log.warn("Failed to obtain Orders, " + e.getMessage());
- return new ArrayList();
+ return new ArrayList<>();
}
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/service/CustomersService.java b/gateway/src/main/java/io/konveyor/demo/gateway/service/CustomersService.java
index cf8f6d1..bb5b6ed 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/service/CustomersService.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/service/CustomersService.java
@@ -1,43 +1,34 @@
package io.konveyor.demo.gateway.service;
-import java.util.List;
-
-import io.konveyor.demo.gateway.model.Customer;
-import io.konveyor.demo.gateway.repository.CustomerRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.konveyor.demo.gateway.model.Customer;
+import io.konveyor.demo.gateway.repository.CustomerRepository;
+import io.micrometer.tracing.annotation.NewSpan;
+import io.micrometer.tracing.annotation.SpanTag;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class CustomersService {
-
- @Autowired
- private Tracer tracer;
-
@Autowired
private CustomerRepository customerRepository;
-
- public Page findAll(Pageable pageable) {
- Span span = tracer.buildSpan("findAll").start();
+
+ @NewSpan
+ public Page findAll(@SpanTag Pageable pageable) {
log.debug("Entering OrdersService.findAll()");
- List orders = customerRepository.findAll(pageable);
- span.finish();
+
+ var orders = customerRepository.findAll(pageable);
return new PageImpl(orders, pageable, orders.size());
}
- public Customer getById(Long id) {
- Span span = tracer.buildSpan("getById").start();
+ @NewSpan
+ public Customer getById(@SpanTag Long id) {
log.debug("Entering CustomersService.getById()");
- Customer c = customerRepository.getCustomerById(id);
- span.finish();
- return c;
+ return customerRepository.getCustomerById(id);
}
-
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/service/InventoryService.java b/gateway/src/main/java/io/konveyor/demo/gateway/service/InventoryService.java
index 0502392..2a57a89 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/service/InventoryService.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/service/InventoryService.java
@@ -1,42 +1,34 @@
package io.konveyor.demo.gateway.service;
-import java.util.List;
-
-import io.konveyor.demo.gateway.model.Product;
-import io.konveyor.demo.gateway.repository.InventoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.konveyor.demo.gateway.model.Product;
+import io.konveyor.demo.gateway.repository.InventoryRepository;
+import io.micrometer.tracing.annotation.NewSpan;
+import io.micrometer.tracing.annotation.SpanTag;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class InventoryService {
- @Autowired
- private Tracer tracer;
-
@Autowired
private InventoryRepository inventoryRepository;
-
- public Page findAll(Pageable pageable) {
- Span span = tracer.buildSpan("findAll").start();
+
+ @NewSpan
+ public Page findAll(@SpanTag Pageable pageable) {
log.debug("Entering OrdersService.findAll()");
- List orders = inventoryRepository.findAll(pageable);
- span.finish();
+
+ var orders = inventoryRepository.findAll(pageable);
return new PageImpl(orders, pageable, orders.size());
}
- public Product getById(Long id) {
- Span span = tracer.buildSpan("getById").start();
+ @NewSpan
+ public Product getById(@SpanTag Long id) {
log.debug("Entering CustomersService.getById()");
- Product p = inventoryRepository.getProductById(id);
- span.finish();
- return p;
+ return inventoryRepository.getProductById(id);
}
-
}
diff --git a/gateway/src/main/java/io/konveyor/demo/gateway/service/OrdersService.java b/gateway/src/main/java/io/konveyor/demo/gateway/service/OrdersService.java
index 63642b9..742a171 100644
--- a/gateway/src/main/java/io/konveyor/demo/gateway/service/OrdersService.java
+++ b/gateway/src/main/java/io/konveyor/demo/gateway/service/OrdersService.java
@@ -1,28 +1,22 @@
package io.konveyor.demo.gateway.service;
-import java.util.List;
-
-import io.konveyor.demo.gateway.model.Order;
-import io.konveyor.demo.gateway.repository.CustomerRepository;
-import io.konveyor.demo.gateway.repository.InventoryRepository;
-import io.konveyor.demo.gateway.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
-import io.opentracing.Span;
-import io.opentracing.Tracer;
+import io.konveyor.demo.gateway.model.Order;
+import io.konveyor.demo.gateway.repository.CustomerRepository;
+import io.konveyor.demo.gateway.repository.InventoryRepository;
+import io.konveyor.demo.gateway.repository.OrderRepository;
+import io.micrometer.tracing.annotation.NewSpan;
+import io.micrometer.tracing.annotation.SpanTag;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class OrdersService {
-
- @Autowired
- private Tracer tracer;
-
@Autowired
private OrderRepository orderRepository;
@@ -31,29 +25,30 @@ public class OrdersService {
@Autowired
private InventoryRepository inventoryRepository;
-
- public Order getById(Long id) {
- Span span = tracer.buildSpan("getById").start();
+
+ @NewSpan
+ public Order getById(@SpanTag Long id) {
log.debug("Entering OrdersService.getById()");
Order o = orderRepository.getOrderById(id);
+
if (o != null) {
o.setCustomer(customerRepository.getCustomerById(o.getCustomer().getId()));
o.setItems(inventoryRepository.getProductDetails(o.getItems()));
}
- span.finish();
+
return o;
}
- public Page findAll(Pageable pageable) {
- Span span = tracer.buildSpan("findAll").start();
+ @NewSpan
+ public Page findAll(@SpanTag Pageable pageable) {
log.debug("Entering OrdersService.findAll()");
- List orders = orderRepository.findAll(pageable);
- for (Order o : orders) {
+ var orders = orderRepository.findAll(pageable);
+
+ orders.forEach(o -> {
o.setCustomer(customerRepository.getCustomerById(o.getCustomer().getId()));
o.setItems(inventoryRepository.getProductDetails(o.getItems()));
- }
- span.finish();
- return new PageImpl(orders, pageable, orders.size());
- }
+ });
+ return new PageImpl<>(orders, pageable, orders.size());
+ }
}
diff --git a/gateway/src/main/java/io/konveyor/demo/util/PaginatedResponse.java b/gateway/src/main/java/io/konveyor/demo/util/PaginatedResponse.java
index 8bb5c18..4e3052d 100644
--- a/gateway/src/main/java/io/konveyor/demo/util/PaginatedResponse.java
+++ b/gateway/src/main/java/io/konveyor/demo/util/PaginatedResponse.java
@@ -1,20 +1,17 @@
package io.konveyor.demo.util;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.JsonNode;
+import java.util.ArrayList;
+import java.util.List;
+
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
-import java.util.ArrayList;
-import java.util.List;
-public class PaginatedResponse extends PageImpl {
- /**
- *
- */
- private static final long serialVersionUID = -8776767744571311395L;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+public class PaginatedResponse extends PageImpl {
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public PaginatedResponse(@JsonProperty("content") List content,
@JsonProperty("number") int number,
diff --git a/gateway/src/main/resources/application.properties b/gateway/src/main/resources/application.properties
index eadc1e9..1fd9de8 100644
--- a/gateway/src/main/resources/application.properties
+++ b/gateway/src/main/resources/application.properties
@@ -1,18 +1,17 @@
+spring.application.name=gateway
+
services.orders.url=http://orders:8080/orders
services.inventory.url=http://inventory:8080/products
services.customers.url=http://customers:8080/customers-tomcat-1.0.0-SNAPSHOT/customers
-hystrix.command.ProductsCall.execution.isolation.thread.timeoutInMilliseconds=2000
-hystrix.threadpool.ProductsThreads.coreSize=20
-hystrix.threadpool.ProductsThreads.maxQueueSize=200
-hystrix.threadpool.ProductsThreads.queueSizeRejectionThreshold=200
+resilience4j.circuitbreaker.configs.default.register-health-indicator=true
+resilience4j.timelimiter.configs.default.timeout-duration=1s
+resilience4j.retry.configs.default.max-attempts=1
-# Disable Opentracing Spring Cloud Starter modules. Tracer registration is to be
-# performed manually for Hystrix
-opentracing.spring.cloud.jdbc.enabled=false
-opentracing.spring.cloud.feign.enabled=false
-opentracing.spring.cloud.jms.enabled=false
-opentracing.spring.cloud.zuul.enabled=false
-opentracing.spring.cloud.websocket.enabled=false
-opentracing.spring.cloud.hystrix.strategy.enabled=true
-opentracing.spring.cloud.async.enabled=false
\ No newline at end of file
+management.endponts.web.exposure.include=*
+management.endpoint.health.show-details=always
+management.health.circuitbreakers.enabled=true
+management.info.git.mode=full
+management.observations.annotations.enabled=true
+management.otlp.tracing.endpoint=http://otel-collector:4318/v1/traces
+management.tracing.sampling.probability=1.0
\ No newline at end of file
diff --git a/gateway/src/test/java/io/konveyor/demo/gateway/controller/OrdersControllerTest.java b/gateway/src/test/java/io/konveyor/demo/gateway/controller/OrdersControllerTest.java
index 657fb7b..43b4d20 100644
--- a/gateway/src/test/java/io/konveyor/demo/gateway/controller/OrdersControllerTest.java
+++ b/gateway/src/test/java/io/konveyor/demo/gateway/controller/OrdersControllerTest.java
@@ -1,41 +1,36 @@
package io.konveyor.demo.gateway.controller;
-import static io.restassured.RestAssured.*;
-import static org.hamcrest.Matchers.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import io.konveyor.demo.gateway.model.Customer;
-import io.konveyor.demo.gateway.model.Order;
-import io.konveyor.demo.gateway.model.OrderItem;
-import io.konveyor.demo.gateway.model.Product;
-import io.konveyor.demo.gateway.service.OrdersService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
-import org.springframework.beans.factory.annotation.Value;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
-import io.restassured.RestAssured;
+import io.konveyor.demo.gateway.model.Customer;
+import io.konveyor.demo.gateway.model.Order;
+import io.konveyor.demo.gateway.model.OrderItem;
+import io.konveyor.demo.gateway.model.Product;
+import io.konveyor.demo.gateway.service.OrdersService;
-@RunWith(SpringRunner.class)
-@SpringBootTest(
- webEnvironment = WebEnvironment.RANDOM_PORT)
-@TestPropertySource(
- locations = "classpath:application-test.properties")
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@AutoConfigureMockMvc
public class OrdersControllerTest {
-
- @Value("${local.server.port}")
- private int port;
-
+ @Autowired
+ private MockMvc mockMvc;
+
@MockBean
private OrdersService service;
@@ -47,14 +42,14 @@ public class OrdersControllerTest {
private Customer customer;
- @Before
- public void setUp() {
+ @BeforeEach
+ void setUp() {
order = new Order();
- order.setId(new Long(1));
+ order.setId(1L);
order.setDate(new GregorianCalendar(2018, 4, 30).getTime());
customer = new Customer();
- customer.setId(new Long(1));
+ customer.setId(1L);
customer.setName("Test Customer");
customer.setSurname("Test Customer");
customer.setUsername("testcustomer");
@@ -64,7 +59,7 @@ public void setUp() {
customer.setAddress("Test Address");
product = new Product();
- product.setId(new Long(1));
+ product.setId(1L);
product.setName("Test Product");
product.setDescription("Test Description");
@@ -73,48 +68,50 @@ public void setUp() {
item.setQuantity(3);
item.setProduct(product);
- List items = new ArrayList();
- items.add(item);
-
+ List items = List.of(item);
+
order.setItems(items);
order.setCustomer(customer);
-
- RestAssured.baseURI = String.format("http://localhost:%d/orders", port);
}
@Test
- public void getByIdExisting() {
- Mockito.when(service.getById(new Long (1)))
+ void getByIdExisting() throws Exception {
+ Mockito.when(service.getById(1L))
.thenReturn(order);
-
- when().get(new Long(1).toString())
- .then()
- .statusCode(200)
- .body("id", is(1))
- .body("date", is("30-05-2018"))
- .body("customer.id", is(1))
- .body("customer.name", is("Test Customer"))
- .body("customer.surname", is("Test Customer"))
- .body("customer.username", is("testcustomer"))
- .body("customer.zipCode", is("28080"))
- .body("customer.city", is("Madrid"))
- .body("customer.country", is("Spain"))
- .body("customer.address", is("Test Address"))
- .body("items.size()", is(1))
- .body("items.get(0).quantity", is(3))
- .body("items.get(0).price", is(30))
- .body("items.get(0).product.id", is(1))
- .body("items.get(0).product.name", is("Test Product"))
- .body("items.get(0).product.description", is("Test Description"));
+
+ this.mockMvc.perform(get("/orders/{id}", 1L))
+ .andExpect(status().isOk())
+ .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
+ .andExpect(jsonPath("$.id").value(1L))
+ .andExpect(jsonPath("$.date").value("30-05-2018"))
+ .andExpect(jsonPath("$.customer.id").value(1L))
+ .andExpect(jsonPath("$.customer.name").value("Test Customer"))
+ .andExpect(jsonPath("$.customer.surname").value("Test Customer"))
+ .andExpect(jsonPath("$.customer.username").value("testcustomer"))
+ .andExpect(jsonPath("$.customer.zipCode").value("28080"))
+ .andExpect(jsonPath("$.customer.city").value("Madrid"))
+ .andExpect(jsonPath("$.customer.country").value("Spain"))
+ .andExpect(jsonPath("$.customer.address").value("Test Address"))
+ .andExpect(jsonPath("$.items.size()").value(1))
+ .andExpect(jsonPath("$.items[0].quantity").value(3))
+ .andExpect(jsonPath("$.items[0].price").value(30))
+ .andExpect(jsonPath("$.items[0].product.id").value(1L))
+ .andExpect(jsonPath("$.items[0].product.name").value("Test Product"))
+ .andExpect(jsonPath("$.items[0].product.description").value("Test Description"));
+
+ Mockito.verify(service).getById(1L);
+ Mockito.verifyNoMoreInteractions(service);
}
@Test
- public void getByIdNonExisting() {
- Mockito.when(service.getById(new Long (1)))
+ void getByIdNonExisting() throws Exception {
+ Mockito.when(service.getById(1L))
.thenReturn(null);
-
- when().get(new Long(1).toString())
- .then()
- .statusCode(404);
+
+ this.mockMvc.perform(get("/orders/{id}", 1L))
+ .andExpect(status().isNotFound());
+
+ Mockito.verify(service).getById(1L);
+ Mockito.verifyNoMoreInteractions(service);
}
}
diff --git a/gateway/src/test/java/io/konveyor/demo/gateway/model/OrderTest.java b/gateway/src/test/java/io/konveyor/demo/gateway/model/OrderTest.java
index 9746a30..80f0449 100644
--- a/gateway/src/test/java/io/konveyor/demo/gateway/model/OrderTest.java
+++ b/gateway/src/test/java/io/konveyor/demo/gateway/model/OrderTest.java
@@ -6,7 +6,7 @@
import java.util.ArrayList;
import java.util.List;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
public class OrderTest {
diff --git a/gateway/src/test/java/io/konveyor/demo/gateway/repository/CustomerRepositoryTest.java b/gateway/src/test/java/io/konveyor/demo/gateway/repository/CustomerRepositoryTest.java
index c47c486..e32996a 100644
--- a/gateway/src/test/java/io/konveyor/demo/gateway/repository/CustomerRepositoryTest.java
+++ b/gateway/src/test/java/io/konveyor/demo/gateway/repository/CustomerRepositoryTest.java
@@ -1,95 +1,122 @@
package io.konveyor.demo.gateway.repository;
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.*;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.*;
-import java.util.Properties;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import io.konveyor.demo.gateway.model.Customer;
-import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.web.client.RestTemplate;
-
-import io.jaegertracing.Configuration;
-import io.opentracing.Tracer;
-
-@RunWith(SpringRunner.class)
-public class CustomerRepositoryTest {
-
- @TestConfiguration
- static class CustomerRepositoryTestContextConfiguration {
- @Bean
- public Tracer tracer() {
- return new Configuration("gateway").getTracer();
- }
-
- @Bean
- public static PropertySourcesPlaceholderConfigurer properties() {
- final PropertySourcesPlaceholderConfigurer pspc =
- new PropertySourcesPlaceholderConfigurer();
- final Properties properties = new Properties();
- properties.setProperty("services.customers.url", "http://customers.svc:8080/customers");
- pspc.setProperties(properties);
- return pspc;
- }
-
- @Bean
- public CustomerRepository repository() {
- return new CustomerRepository();
- }
- }
-
- @MockBean
- RestTemplate restTemplate;
-
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability;
+import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
+import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JAutoConfiguration;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.client.MockRestServiceServer;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.github.resilience4j.springboot3.circuitbreaker.autoconfigure.CircuitBreakerAutoConfiguration;
+import io.github.resilience4j.springboot3.circuitbreaker.autoconfigure.CircuitBreakerMetricsAutoConfiguration;
+import io.github.resilience4j.springboot3.retry.autoconfigure.RetryAutoConfiguration;
+import io.github.resilience4j.springboot3.timelimiter.autoconfigure.TimeLimiterAutoConfiguration;
+import io.konveyor.demo.gateway.model.Customer;
+
+@RestClientTest(
+ components = CustomerRepository.class,
+ properties = "services.customers.url=/customers"
+)
+@ImportAutoConfiguration({ AopAutoConfiguration.class, Resilience4JAutoConfiguration.class, RetryAutoConfiguration.class, CircuitBreakerAutoConfiguration.class, CircuitBreakerMetricsAutoConfiguration.class, TimeLimiterAutoConfiguration.class })
+@AutoConfigureObservability
+class CustomerRepositoryTest {
+ @Autowired
+ private MockRestServiceServer server;
+
+ @Autowired
+ private CustomerRepository repository;
+
@Autowired
- CustomerRepository repository;
-
- private Customer customer;
-
- @Before
- public void setup() {
- customer = new Customer();
- customer.setId(new Long(1));
- customer.setName("Test Customer");
- customer.setSurname("Test Customer");
- customer.setUsername("testcustomer");
- customer.setZipCode("28080");
- customer.setCountry("Spain");
- customer.setCity("Madrid");
- customer.setAddress("Test Address");
+ private ObjectMapper objectMapper;
+
+ private static Customer CUSTOMER;
+ private String customerJson;
+
+ @BeforeAll
+ static void createCustomer() {
+ CUSTOMER = new Customer();
+ CUSTOMER.setId(1L);
+ CUSTOMER.setName("Test Customer");
+ CUSTOMER.setSurname("Test Customer");
+ CUSTOMER.setUsername("testcustomer");
+ CUSTOMER.setZipCode("28080");
+ CUSTOMER.setCountry("Spain");
+ CUSTOMER.setCity("Madrid");
+ CUSTOMER.setAddress("Test Address");
+ }
+
+ @BeforeEach
+ void createCustomerJson() throws JsonProcessingException {
+ this.customerJson = this.objectMapper.writeValueAsString(CUSTOMER);
+ this.server.reset();
+ }
+
+ @Test
+ void getCustomerByIdExistingTest() {
+ this.server.expect(requestTo("/customers/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(customerJson, MediaType.APPLICATION_JSON));
+
+ var customer = repository.getCustomerById(1L);
+
+ assertThat(customer)
+ .isNotNull()
+ .usingRecursiveComparison()
+ .isEqualTo(CUSTOMER);
+
+ this.server.verify();
}
-
+
@Test
- public void getCustomerByIdExistingTest() {
- Mockito.when(restTemplate.getForObject("http://customers.svc:8080/customers/1", Customer.class))
- .thenReturn((Customer)SerializationUtils.clone(customer));
-
- Customer found = repository.getCustomerById(new Long(1));
- assertThat(found).isEqualTo(customer);
+ void getCustomerByIdNonExistingTest() {
+ this.server.expect(requestTo("/customers/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess());
+
+
+ var fallbackCustomer = repository.getFallbackCustomer(1L, new Exception());
+
+ assertThat(repository.getCustomerById(1L))
+ .isNotNull()
+ .usingRecursiveComparison()
+ .isEqualTo(fallbackCustomer);
+
+ this.server.verify();
}
-
- @Test(expected = RuntimeException.class)
- public void getCustomerByIdNonExistingTest() {
-
- Mockito.when(restTemplate.getForObject("http://customers.svc:8080/customers/1", Customer.class))
- .thenReturn(null);
-
- repository.getCustomerById(new Long(1));
+
+ @Test
+ void fallsBack() {
+ var fallbackCustomer = repository.getFallbackCustomer(1L, new Exception());
+
+ this.server.expect(requestTo("/customers/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withServerError());
+
+ assertThat(repository.getCustomerById(1L))
+ .isNotNull()
+ .usingRecursiveComparison()
+ .isEqualTo(fallbackCustomer);
+
+ this.server.verify();
}
-
+
@Test
- public void getFallbackCustomerTest() {
+ void getFallbackCustomerTest() {
Customer c = new Customer();
- c.setId(new Long(1));
+ c.setId(1L);
c.setUsername("Unknown");
c.setName("Unknown");
c.setSurname("Unknown");
@@ -97,9 +124,11 @@ public void getFallbackCustomerTest() {
c.setCity("Unknown");
c.setCountry("Unknown");
c.setZipCode("Unknown");
-
- Customer found = repository.getFallbackCustomer(new Long(1), new Exception());
-
- assertThat(found).isEqualTo(c);
+
+ var customer = repository.getFallbackCustomer(1L, new Exception());
+
+ assertThat(customer)
+ .usingRecursiveComparison()
+ .isEqualTo(c);
}
}
diff --git a/gateway/src/test/java/io/konveyor/demo/gateway/repository/InventoryRepositoryTest.java b/gateway/src/test/java/io/konveyor/demo/gateway/repository/InventoryRepositoryTest.java
index 67325cc..a2dc018 100644
--- a/gateway/src/test/java/io/konveyor/demo/gateway/repository/InventoryRepositoryTest.java
+++ b/gateway/src/test/java/io/konveyor/demo/gateway/repository/InventoryRepositoryTest.java
@@ -1,63 +1,49 @@
package io.konveyor.demo.gateway.repository;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.*;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability;
+import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
+import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JAutoConfiguration;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.client.MockRestServiceServer;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.github.resilience4j.springboot3.circuitbreaker.autoconfigure.CircuitBreakerAutoConfiguration;
+import io.github.resilience4j.springboot3.circuitbreaker.autoconfigure.CircuitBreakerMetricsAutoConfiguration;
+import io.github.resilience4j.springboot3.retry.autoconfigure.RetryAutoConfiguration;
+import io.github.resilience4j.springboot3.timelimiter.autoconfigure.TimeLimiterAutoConfiguration;
import io.konveyor.demo.gateway.model.OrderItem;
import io.konveyor.demo.gateway.model.Product;
-import org.mockito.Mockito;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.web.client.RestClientException;
-import org.springframework.web.client.RestTemplate;
-
-import io.jaegertracing.Configuration;
-import io.opentracing.Tracer;
-
-@RunWith(SpringRunner.class)
-public class InventoryRepositoryTest {
-
- @TestConfiguration
- static class CustomerRepositoryTestContextConfiguration {
- @Bean
- public Tracer tracer() {
- return new Configuration("gateway").getTracer();
- }
-
- @Bean
- public static PropertySourcesPlaceholderConfigurer properties() {
- final PropertySourcesPlaceholderConfigurer pspc =
- new PropertySourcesPlaceholderConfigurer();
- final Properties properties = new Properties();
- properties.setProperty("services.inventory.url", "http://inventory.svc:8080/products");
- properties.setProperty("hystrix.threadpool.ProductsThreads.coreSize", "20");
- pspc.setProperties(properties);
- return pspc;
- }
-
- @Bean
- public InventoryRepository repository() {
- return new InventoryRepository();
- }
- }
-
- @MockBean
- RestTemplate restTemplate;
+
+@RestClientTest(
+ components = InventoryRepository.class,
+ properties = "services.inventory.url=/products"
+)
+@ImportAutoConfiguration({ AopAutoConfiguration.class, Resilience4JAutoConfiguration.class, RetryAutoConfiguration.class, CircuitBreakerAutoConfiguration.class, CircuitBreakerMetricsAutoConfiguration.class, TimeLimiterAutoConfiguration.class })
+@AutoConfigureObservability
+class InventoryRepositoryTest {
+ @Autowired
+ private MockRestServiceServer server;
@Autowired
- InventoryRepository repository;
+ private InventoryRepository repository;
+
+ @Autowired
+ private ObjectMapper objectMapper;
private List items;
@@ -65,42 +51,40 @@ public InventoryRepository repository() {
private Product product2;
- @Before
- public void setup() {
+ @BeforeEach
+ void setup() {
product1 = new Product();
- product1.setId(new Long(1));
+ product1.setId(1L);
product1.setName("Test Product 1");
product1.setDescription("Test Description 1");
product2 = new Product();
- product2.setId(new Long(2));
+ product2.setId(2L);
product2.setName("Test Product 2");
product2.setDescription("Test Description 2");
OrderItem item1 = new OrderItem();
item1.setPrice(new BigDecimal(30));
item1.setQuantity(3);
- item1.setProduct((Product)SerializationUtils.clone(product1));
+ item1.setProduct(new Product(product1.getId(), product1.getName(), product1.getDescription()));
OrderItem item2 = new OrderItem();
item2.setPrice(new BigDecimal(50));
item2.setQuantity(2);
- item2.setProduct((Product)SerializationUtils.clone(product2));
-
- items = new ArrayList();
+ item2.setProduct(new Product(product2.getId(), product2.getName(), product2.getDescription()));
- items.add(item1);
- items.add(item2);
+ items = List.of(item1, item2);
+
+ this.server.reset();
}
@Test
- public void getProductDetailsExistingTest() {
-
+ void getProductDetailsExistingTest() throws JsonProcessingException {
Product p1 = new Product();
- p1.setId(new Long(1));
+ p1.setId(1L);
Product p2 = new Product();
- p2.setId(new Long(2));
+ p2.setId(2L);
OrderItem i1 = new OrderItem();
i1.setPrice(new BigDecimal(30));
@@ -112,30 +96,32 @@ public void getProductDetailsExistingTest() {
i2.setQuantity(2);
i2.setProduct(p2);
- List incomplete = new ArrayList();
-
- incomplete.add(i1);
- incomplete.add(i2);
-
- Mockito.when(restTemplate.getForObject("http://inventory.svc:8080/products/1", Product.class))
- .thenReturn(product1);
-
- Mockito.when(restTemplate.getForObject("http://inventory.svc:8080/products/2", Product.class))
- .thenReturn(product2);
-
- List found = repository.getProductDetails(incomplete);
+ List incomplete = List.of(i1, i2);
+
+ this.server.expect(requestTo("/products/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(objectMapper.writeValueAsString(product1), MediaType.APPLICATION_JSON));
+
+ this.server.expect(requestTo("/products/2"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(objectMapper.writeValueAsString(product2), MediaType.APPLICATION_JSON));
+
+ var found = repository.getProductDetails(incomplete);
- assertThat(found).isEqualTo(items);
+ assertThat(found)
+ .usingRecursiveFieldByFieldElementComparator()
+ .isEqualTo(items);
+
+ this.server.verify();
}
@Test
- public void getProductDetailsOneNonExistingTest() {
-
+ void getProductDetailsOneNonExistingTest() throws JsonProcessingException {
Product p1 = new Product();
- p1.setId(new Long(1));
+ p1.setId(1L);
Product p2 = new Product();
- p2.setId(new Long(2));
+ p2.setId(2L);
OrderItem i1 = new OrderItem();
i1.setPrice(new BigDecimal(30));
@@ -147,32 +133,34 @@ public void getProductDetailsOneNonExistingTest() {
i2.setQuantity(2);
i2.setProduct(p2);
- List incomplete = new ArrayList();
-
- incomplete.add(i1);
- incomplete.add(i2);
-
- Mockito.when(restTemplate.getForObject("http://inventory.svc:8080/products/1", Product.class))
- .thenReturn(null);
-
- Mockito.when(restTemplate.getForObject("http://inventory.svc:8080/products/2", Product.class))
- .thenReturn(product2);
-
- List found = repository.getProductDetails(incomplete);
+ List incomplete = List.of(i1, i2);
+
+ server.expect(requestTo("/products/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess());
+
+ server.expect(requestTo("/products/2"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(objectMapper.writeValueAsString(product2), MediaType.APPLICATION_JSON));
+
+ var found = repository.getProductDetails(incomplete);
items.get(0).setProduct(p1);
-
- assertThat(found).isEqualTo(items);
+
+ assertThat(found)
+ .usingRecursiveFieldByFieldElementComparator()
+ .isEqualTo(items);
+
+ server.verify();
}
@Test
- public void getProductDetailsRestExceptionTest() {
-
+ void getProductDetailsRestExceptionTest() {
Product p1 = new Product();
- p1.setId(new Long(1));
+ p1.setId(1L);
Product p2 = new Product();
- p2.setId(new Long(2));
+ p2.setId(2L);
OrderItem i1 = new OrderItem();
i1.setPrice(new BigDecimal(30));
@@ -184,21 +172,22 @@ public void getProductDetailsRestExceptionTest() {
i2.setQuantity(2);
i2.setProduct(p2);
- List incomplete = new ArrayList();
-
- incomplete.add(i1);
- incomplete.add(i2);
-
- Mockito.when(restTemplate.getForObject("http://inventory.svc:8080/products/1", Product.class))
- .thenThrow(new RestClientException("Failed 1"));
-
- Mockito.when(restTemplate.getForObject("http://inventory.svc:8080/products/2", Product.class))
- .thenThrow(new RestClientException("Failed 2"));
-
+ List incomplete = List.of(i1, i2);
+
+ server.expect(requestTo("/products/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withServerError());
+
+ server.expect(requestTo("/products/2"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withServerError());
+
List found = repository.getProductDetails(incomplete);
- assertThat(found).isEqualTo(incomplete);
+ assertThat(found)
+ .usingRecursiveFieldByFieldElementComparator()
+ .isEqualTo(incomplete);
+
+ server.verify();
}
-
-
}
diff --git a/gateway/src/test/java/io/konveyor/demo/gateway/repository/OrderRepositoryTest.java b/gateway/src/test/java/io/konveyor/demo/gateway/repository/OrderRepositoryTest.java
index 08e6575..bb82837 100644
--- a/gateway/src/test/java/io/konveyor/demo/gateway/repository/OrderRepositoryTest.java
+++ b/gateway/src/test/java/io/konveyor/demo/gateway/repository/OrderRepositoryTest.java
@@ -1,113 +1,136 @@
package io.konveyor.demo.gateway.repository;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.*;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.*;
import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.GregorianCalendar;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
import java.util.List;
-import java.util.Properties;
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability;
+import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;
+import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JAutoConfiguration;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.client.MockRestServiceServer;
+
+import io.github.resilience4j.springboot3.circuitbreaker.autoconfigure.CircuitBreakerAutoConfiguration;
+import io.github.resilience4j.springboot3.circuitbreaker.autoconfigure.CircuitBreakerMetricsAutoConfiguration;
+import io.github.resilience4j.springboot3.retry.autoconfigure.RetryAutoConfiguration;
+import io.github.resilience4j.springboot3.timelimiter.autoconfigure.TimeLimiterAutoConfiguration;
import io.konveyor.demo.gateway.model.Customer;
import io.konveyor.demo.gateway.model.Order;
import io.konveyor.demo.gateway.model.OrderItem;
import io.konveyor.demo.gateway.model.Product;
-import org.mockito.Mockito;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.web.client.RestTemplate;
-
-import io.jaegertracing.Configuration;
-import io.opentracing.Tracer;
-
-@RunWith(SpringRunner.class)
-public class OrderRepositoryTest {
-
- @TestConfiguration
- static class CustomerRepositoryTestContextConfiguration {
- @Bean
- public Tracer tracer() {
- return new Configuration("gateway").getTracer();
- }
-
- @Bean
- public static PropertySourcesPlaceholderConfigurer properties() {
- final PropertySourcesPlaceholderConfigurer pspc =
- new PropertySourcesPlaceholderConfigurer();
- final Properties properties = new Properties();
- properties.setProperty("services.orders.url", "http://orders.svc:8080/orders");
- pspc.setProperties(properties);
- return pspc;
- }
-
- @Bean
- public OrderRepository repository() {
- return new OrderRepository();
- }
- }
-
- @MockBean
- RestTemplate restTemplate;
-
+
+@RestClientTest(
+ components = OrderRepository.class,
+ properties = "services.orders.url=/orders"
+)
+@ImportAutoConfiguration({ AopAutoConfiguration.class, Resilience4JAutoConfiguration.class, RetryAutoConfiguration.class, CircuitBreakerAutoConfiguration.class, CircuitBreakerMetricsAutoConfiguration.class, TimeLimiterAutoConfiguration.class })
+@AutoConfigureObservability
+class OrderRepositoryTest {
@Autowired
- OrderRepository repository;
+ private MockRestServiceServer server;
+ @Autowired
+ private OrderRepository repository;
+
private Order order;
- @Before
- public void setup() {
+ @BeforeEach
+ void setup() {
order = new Order();
- order.setId(new Long(1));
- order.setDate(new GregorianCalendar(2018, 4, 30).getTime());
+ order.setId(11L);
+ order.setDate(Date.from(LocalDate.of(2018, 04, 30).atStartOfDay(ZoneId.of("CET")).toInstant()));
Product p = new Product();
- p.setId(new Long(1));
+ p.setId(1L);
Customer c = new Customer();
- c.setId(new Long(1));
+ c.setId(1L);
OrderItem i = new OrderItem();
i.setPrice(new BigDecimal(30));
i.setQuantity(3);
i.setProduct(p);
- List items = new ArrayList();
- items.add(i);
-
+ List items = List.of(i);
+
order.setItems(items);
order.setCustomer(c);
}
@Test
- public void getOrderByIdExistingTest() {
- Mockito.when(restTemplate.getForObject("http://orders.svc:8080/orders/1", Order.class))
- .thenReturn((Order)SerializationUtils.clone(order));
-
- Order found = repository.getOrderById(new Long(1));
+ void getOrderByIdExistingTest() {
+ var json = """
+ {
+ "id": 11,
+ "date": "30-04-2018",
+ "items": [
+ {
+ "quantity": 3,
+ "price": 30,
+ "productUID": 1
+ }
+ ],
+ "totalAmmount": 90,
+ "customerUID": 1
+ }
+ """;
+
+ this.server.expect(requestTo("/orders/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess(json, MediaType.APPLICATION_JSON));
+
+ Order found = repository.getOrderById(1L);
- assertThat(found).isEqualTo(order);
+ assertThat(found)
+ .usingRecursiveComparison()
+ .isEqualTo(order);
+
+ this.server.verify();
}
@Test
- public void getOrderByIdNonExistingTest() {
- Mockito.when(restTemplate.getForObject("http://orders.svc:8080/orders/1", Order.class))
- .thenReturn(null);
-
- Order found = repository.getOrderById(new Long(1));
+ void getOrderByIdNonExistingTest() {
+ this.server.expect(requestTo("/orders/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withSuccess());
+
+ Order found = repository.getOrderById(1L);
- assertThat(found).isNull();
+ assertThat(found)
+ .isNull();
+ this.server.verify();
}
@Test
- public void getFallbackCustomerTest() {
- assertThat(repository.getFallbackOrder(new Long(1), new Exception())).isNull();
+ void getFallbackCustomerTest() {
+ assertThat(repository.getFallbackOrder(1L, new Exception())).isNull();
+ }
+
+ @Test
+ void fallsBack() {
+ var fallbackOrder = repository.getFallbackOrder(1L, new Exception());
+
+ this.server.expect(requestTo("/orders/1"))
+ .andExpect(method(HttpMethod.GET))
+ .andRespond(withServerError());
+
+ assertThat(repository.getOrderById(1L))
+ .usingRecursiveComparison()
+ .isEqualTo(fallbackOrder);
+
+ this.server.verify();
}
}
diff --git a/gateway/src/test/java/io/konveyor/demo/gateway/service/OrdersServiceTest.java b/gateway/src/test/java/io/konveyor/demo/gateway/service/OrdersServiceTest.java
index c171191..fe31767 100644
--- a/gateway/src/test/java/io/konveyor/demo/gateway/service/OrdersServiceTest.java
+++ b/gateway/src/test/java/io/konveyor/demo/gateway/service/OrdersServiceTest.java
@@ -3,14 +3,19 @@
import static org.assertj.core.api.Assertions.assertThat;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
-import org.apache.commons.lang.SerializationUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.annotation.Bean;
+
import io.konveyor.demo.gateway.model.Customer;
import io.konveyor.demo.gateway.model.Order;
import io.konveyor.demo.gateway.model.OrderItem;
@@ -18,60 +23,46 @@
import io.konveyor.demo.gateway.repository.CustomerRepository;
import io.konveyor.demo.gateway.repository.InventoryRepository;
import io.konveyor.demo.gateway.repository.OrderRepository;
-import org.mockito.Mockito;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.test.context.junit4.SpringRunner;
-import io.jaegertracing.Configuration;
-import io.opentracing.Tracer;
+@SpringBootTest
+class OrdersServiceTest {
-@RunWith(SpringRunner.class)
-public class OrdersServiceTest {
-
@TestConfiguration
- static class OrdersServiceTestContextConfiguration {
+ static class OrdersServiceTestContextConfiguration {
@Bean
public OrdersService ordersService() {
return new OrdersService();
}
-
- @Bean
- public Tracer tracer() {
- return new Configuration("gateway").getTracer();
- }
}
-
+
@Autowired
- OrdersService ordersService;
-
+ private OrdersService ordersService;
+
@MockBean
private OrderRepository orderRepository;
-
+
@MockBean
private CustomerRepository customerRepository;
-
+
@MockBean
private InventoryRepository inventoryRepository;
-
+
private Order order;
-
+
private OrderItem item;
-
+
private Product product;
-
+
private Customer customer;
-
- @Before
- public void setup() {
+
+ @BeforeEach
+ void setup() {
order = new Order();
- order.setId(new Long(1));
+ order.setId(1L);
order.setDate(new GregorianCalendar(2018, 5, 30).getTime());
-
+
customer = new Customer();
- customer.setId(new Long(1));
+ customer.setId(1L);
customer.setName("Test Customer");
customer.setSurname("Test Customer");
customer.setUsername("testcustomer");
@@ -79,71 +70,69 @@ public void setup() {
customer.setCountry("Spain");
customer.setCity("Madrid");
customer.setAddress("Test Address");
-
+
product = new Product();
- product.setId(new Long(1));
+ product.setId(1L);
product.setName("Test Product");
product.setDescription("Test Description");
-
+
item = new OrderItem();
item.setPrice(new BigDecimal(30));
item.setQuantity(3);
item.setProduct(product);
-
- List items = new ArrayList();
- items.add(item);
-
+
+ List items = List.of(item);
order.setItems(items);
order.setCustomer(customer);
}
-
+
@Test
- public void getByIdWithExistingOrderTest() {
+ void getByIdWithExistingOrderTest() {
Order o = new Order();
- o.setId(new Long(1));
+ o.setId(1L);
o.setDate(new GregorianCalendar(2018, 5, 30).getTime());
-
+
Product p = new Product();
- p.setId(new Long(1));
-
+ p.setId(1L);
+
Customer c = new Customer();
- c.setId(new Long(1));
-
+ c.setId(1L);
+
OrderItem i = new OrderItem();
i.setPrice(new BigDecimal(30));
i.setQuantity(3);
i.setProduct(p);
-
- List items = new ArrayList();
- items.add(item);
-
- List detaileditems = new ArrayList();
- detaileditems.add((OrderItem)SerializationUtils.clone(item));
-
+
+ List items = List.of(item);
+
+ List detaileditems = List.of(new OrderItem(item.getProduct(), item.getQuantity(), item.getPrice()));
+
o.setItems(items);
o.setCustomer(c);
-
- Mockito.when(orderRepository.getOrderById(new Long(1)))
+
+ Mockito.when(orderRepository.getOrderById(1L))
.thenReturn(o);
-
- Mockito.when(customerRepository.getCustomerById(new Long(1)))
- .thenReturn((Customer)SerializationUtils.clone(customer));
-
+
+ Mockito.when(customerRepository.getCustomerById(1L))
+ .thenReturn(customer.toBuilder().build());
+
Mockito.when(inventoryRepository.getProductDetails(items))
- .thenReturn(detaileditems);
-
- Order found = ordersService.getById(new Long(1));
-
- assertThat(found).isEqualTo(order);
+ .thenReturn(detaileditems);
+
+ Order found = ordersService.getById(1L);
+
+ assertThat(found)
+ .usingRecursiveComparison()
+ .isEqualTo(order);
}
-
+
@Test
- public void getByIdWithNonExistingOrderTest() {
- Mockito.when(orderRepository.getOrderById(new Long(1)))
- .thenReturn(null);
-
- Order found = ordersService.getById(new Long(1));
-
+ void getByIdWithNonExistingOrderTest() {
+ Mockito.when(orderRepository.getOrderById(1L))
+ .thenReturn(null);
+
+ Order found = ordersService.getById(1L);
+
assertThat(found).isNull();
}
}
diff --git a/gateway/src/test/resources/application-test.properties b/gateway/src/test/resources/application-test.properties
deleted file mode 100644
index 0a69bdf..0000000
--- a/gateway/src/test/resources/application-test.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-services.orders.url=http://orders-rhoar.192.168.42.215.nip.io/orders
-services.inventory.url=http://inventory-rhoar.192.168.42.215.nip.io/products
-services.customers.url=http://customers-rhoar.192.168.42.215.nip.io/customers
-
-hystrix.command.ProductsCall.execution.isolation.thread.timeoutInMilliseconds=2000
-
-hystrix.threadpool.ProductsThreads.coreSize=20
-hystrix.threadpool.ProductsThreads.maxQueueSize=200
-hystrix.threadpool.ProductsThreads.queueSizeRejectionThreshold=200
-
-# Disable Opentracing Spring Cloud Starter modules. Tracer registration is to be
-# performed manually for Hystrix
-opentracing.spring.cloud.jdbc.enabled=false
-opentracing.spring.cloud.feign.enabled=false
-opentracing.spring.cloud.jms.enabled=false
-opentracing.spring.cloud.zuul.enabled=false
-opentracing.spring.cloud.websocket.enabled=false
-opentracing.spring.cloud.hystrix.strategy.enabled=true
-opentracing.spring.cloud.async.enabled=false
\ No newline at end of file
diff --git a/gateway/src/test/resources/bootstrap.properties b/gateway/src/test/resources/bootstrap.properties
deleted file mode 100644
index 5312ef6..0000000
--- a/gateway/src/test/resources/bootstrap.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-spring.application.name=gateway
-#Point to a non existing configmap to force loading the test properties file specified
-#in the integration tests.
-spring.cloud.kubernetes.config.name=gateway-test-config
diff --git a/inventory/pom.xml b/inventory/pom.xml
index 61e7dc2..1258af4 100644
--- a/inventory/pom.xml
+++ b/inventory/pom.xml
@@ -1,8 +1,5 @@
-
-
+
+
4.0.0
com.redhat.coolstore
inventory
@@ -34,7 +31,7 @@
io.quarkus
- quarkus-resteasy-reactive-jackson
+ quarkus-rest-jackson
org.springframework.boot
diff --git a/orders/src/main/java/io/konveyor/demo/orders/config/OtelDataSourceConfig.java b/orders/src/main/java/io/konveyor/demo/orders/config/OtelDataSourceConfig.java
new file mode 100644
index 0000000..1d60c5a
--- /dev/null
+++ b/orders/src/main/java/io/konveyor/demo/orders/config/OtelDataSourceConfig.java
@@ -0,0 +1,30 @@
+package io.konveyor.demo.orders.config;
+
+import javax.sql.DataSource;
+
+import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.instrumentation.jdbc.datasource.JdbcTelemetry;
+
+/**
+ * This class is needed to allow tracing down to the JDBC level.
+ * Taken from https://opentelemetry.io/docs/languages/java/automatic/spring-boot/#jdbc-instrumentation
+ */
+@Configuration
+public class OtelDataSourceConfig {
+ @Bean
+ public DataSource dataSource(DataSourceProperties dataSourceProperties, OpenTelemetry openTelemetry) {
+ var dataSource = DataSourceBuilder.create()
+ .driverClassName(dataSourceProperties.determineDriverClassName())
+ .url(dataSourceProperties.determineUrl())
+ .username(dataSourceProperties.getUsername())
+ .password(dataSourceProperties.getPassword())
+ .build();
+
+ return JdbcTelemetry.create(openTelemetry).wrap(dataSource);
+ }
+}
\ No newline at end of file
diff --git a/orders/src/main/resources/application.properties b/orders/src/main/resources/application.properties
index f7f17ce..55e2064 100644
--- a/orders/src/main/resources/application.properties
+++ b/orders/src/main/resources/application.properties
@@ -1,3 +1,5 @@
+spring.application.name=orders
+
spring.datasource.url=jdbc:h2:mem:orders;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=orders
spring.datasource.password=orders
@@ -10,5 +12,5 @@ management.endponts.web.exposure.include=*
management.endpoint.health.show-details=always
management.info.git.mode=full
management.observations.annotations.enabled=true
-management.otlp.tracing.endpoint=http://localhost:4318/traces
+management.otlp.tracing.endpoint=http://otel-collector:4318/v1/traces
management.tracing.sampling.probability=1.0
\ No newline at end of file