* Add code examples for article BAEL-4685

* Add tests for the endpoints.

* Rename RequestTimeoutTests.java to RequestTimeoutUnitTest.java
This commit is contained in:
Jordan Simpson
2021-03-12 01:04:20 -06:00
committed by GitHub
parent c9bc95a5e2
commit eea3ae3084
8 changed files with 189 additions and 0 deletions
@@ -0,0 +1,61 @@
package com.baeldung.requesttimeout;
import com.baeldung.requesttimeout.domain.Book;
import com.baeldung.requesttimeout.domain.BookRepository;
import io.github.resilience4j.timelimiter.TimeLimiter;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
@RestController
public class RequestTimeoutRestController {
private final BookRepository bookRepository;
private final WebClient webClient;
public RequestTimeoutRestController(BookRepository bookRepository, WebClient webClient) {
this.bookRepository = bookRepository;
this.webClient = webClient;
}
@GetMapping("/author/transactional")
@Transactional(timeout = 1)
public String getWithTransactionTimeout(@RequestParam String title) {
return getAuthor(title);
}
private final TimeLimiter ourTimeLimiter = TimeLimiter.of(TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(500)).build());
@GetMapping("/author/resilience4j")
public Callable<String> getWithResilience4jTimeLimiter(@RequestParam String title) {
return TimeLimiter.decorateFutureSupplier(ourTimeLimiter, () -> CompletableFuture.supplyAsync(() -> getAuthor(title)));
}
@GetMapping("/author/mvc-request-timeout")
public Callable<String> getWithMvcRequestTimeout(@RequestParam String title) {
return () -> getAuthor(title);
}
@GetMapping("/author/webclient")
public String getWithWebClient(@RequestParam String title) {
return webClient.get()
.uri(uriBuilder -> uriBuilder
.path("/author/transactional")
.queryParam("title", title)
.build())
.retrieve()
.bodyToMono(String.class)
.block();
}
private String getAuthor(String title) {
bookRepository.wasteTime();
return bookRepository.findById(title).map(Book::getAuthor).orElse("No book found for this title.");
}
}
@@ -0,0 +1,21 @@
package com.baeldung.requesttimeout.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import java.time.Duration;
@Configuration
public class WebClientConfiguration {
@Bean
public WebClient webClient() {
return WebClient.builder()
.baseUrl("http://localhost:8080")
.clientConnector(new ReactorClientHttpConnector(HttpClient.create().responseTimeout(Duration.ofMillis(250))))
.build();
}
}
@@ -0,0 +1,28 @@
package com.baeldung.requesttimeout.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Book {
@Id
private String title;
private String author;
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
@@ -0,0 +1,14 @@
package com.baeldung.requesttimeout.domain;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, String> {
default int wasteTime() {
int i = Integer.MIN_VALUE;
while(i < Integer.MAX_VALUE) {
i++;
}
return i;
}
}
@@ -0,0 +1 @@
spring.mvc.async.request-timeout=750