Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
making committed Dec 30, 2020
1 parent 903f6c6 commit e6056b8
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
import reactor.core.publisher.Mono;

import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -36,8 +34,8 @@ public CartController(CatalogClient catalogClient, CartClient cartClient, CartSe
}

@PostMapping(path = "cart")
public Mono<String> addCart(@ModelAttribute AddCartItemForm cartItem, Cart cart, Model model, @RegisteredOAuth2AuthorizedClient("sock") OAuth2AuthorizedClient authorizedClient) {
return this.catalogClient.getSock(cartItem.getId(), authorizedClient)
public Mono<String> addCart(@ModelAttribute AddCartItemForm cartItem, Cart cart, Model model) {
return this.catalogClient.getSock(cartItem.getId())
.map(item -> new CartItemRequest()
.itemId(item.getId().toString())
.quantity(cartItem.getQuantity())
Expand Down
40 changes: 25 additions & 15 deletions shop-ui/src/main/java/lol/maki/socks/catalog/CatalogClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancedExchangeFilterFunction;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;

import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient;
import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId;

@Component
public class CatalogClient {
Expand Down Expand Up @@ -49,42 +48,53 @@ public CatalogClient(WebClient.Builder builder, LoadBalancedExchangeFilterFuncti
this.props = props;
}

public Mono<SockResponse> getSock(UUID id, OAuth2AuthorizedClient authorizedClient) {
@CircuitBreaker(name = "catalog")
public Mono<SockResponse> getSock(UUID id) {
return this.webClient.get()
.uri(props.getCatalogUrl(), b -> b.path("catalogue/{id}").build(id))
.attributes(oauth2AuthorizedClient(authorizedClient))
.attributes(clientRegistrationId("sock"))
.retrieve()
.bodyToMono(SockResponse.class);
}

@CircuitBreaker(name = "catalog", fallbackMethod = "fallbackSock")
public Mono<SockResponse> getSockWithFallback(UUID id, OAuth2AuthorizedClient authorizedClient) {
return this.getSock(id, authorizedClient);
public Mono<SockResponse> getSockWithFallback(UUID id) {
return this.getSock(id);
}

@CircuitBreaker(name = "catalog", fallbackMethod = "fallbackSocks")
public Flux<SockResponse> getSocksWithFallback(CatalogOrder order, int page, int size, List<String> tags, OAuth2AuthorizedClient authorizedClient) {
@CircuitBreaker(name = "catalog")
public Flux<SockResponse> getSocks(CatalogOrder order, int page, int size, List<String> tags) {
return this.webClient.get()
.uri(props.getCatalogUrl(), b -> b.path("catalogue")
.queryParam("order", order)
.queryParam("page", page)
.queryParam("size", size)
.queryParam("tags", tags)
.build())
.attributes(oauth2AuthorizedClient(authorizedClient))
.attributes(clientRegistrationId("sock"))
.retrieve()
.bodyToFlux(SockResponse.class);
}

@CircuitBreaker(name = "catalog", fallbackMethod = "fallbackTags")
public Mono<TagsResponse> getTagsWithFallback(OAuth2AuthorizedClient authorizedClient) {
@CircuitBreaker(name = "catalog", fallbackMethod = "fallbackSocks")
public Flux<SockResponse> getSocksWithFallback(CatalogOrder order, int page, int size, List<String> tags) {
return this.getSocks(order, page, size, tags);
}

@CircuitBreaker(name = "catalog")
public Mono<TagsResponse> getTags() {
return this.webClient.get()
.uri(props.getCatalogUrl(), b -> b.path("tags").build())
.attributes(oauth2AuthorizedClient(authorizedClient))
.attributes(clientRegistrationId("sock"))
.retrieve()
.bodyToMono(TagsResponse.class);
}

@CircuitBreaker(name = "catalog", fallbackMethod = "fallbackTags")
public Mono<TagsResponse> getTagsWithFallback() {
return this.getTags();
}

@CircuitBreaker(name = "catalog", fallbackMethod = "fallbackImage")
public Mono<Resource> getImageWithFallback(String fileName) {
return this.webClient.get()
Expand All @@ -101,16 +111,16 @@ public Mono<Resource> headImageWithFallback(String fileName) {
.bodyToMono(Resource.class);
}

Mono<SockResponse> fallbackSock(UUID id, OAuth2AuthorizedClient authorizedClient, Throwable throwable) {
Mono<SockResponse> fallbackSock(UUID id, Throwable throwable) {
SockNotFoundException.throwIfNotFound(id, throwable);
return Mono.just(fallbackSock);
}

Flux<SockResponse> fallbackSocks(CatalogOrder order, int page, int size, List<String> tags, OAuth2AuthorizedClient authorizedClient, Throwable throwable) {
Flux<SockResponse> fallbackSocks(CatalogOrder order, int page, int size, List<String> tags, Throwable throwable) {
return Flux.just(fallbackSock);
}

Mono<TagsResponse> fallbackTags(OAuth2AuthorizedClient authorizedClient, Throwable throwable) {
Mono<TagsResponse> fallbackTags(Throwable throwable) {
return Mono.fromCallable(TagsResponse::new);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package lol.maki.socks.catalog.web;

import java.time.Duration;
import java.util.List;
import java.util.UUID;

Expand All @@ -14,9 +15,9 @@

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -38,20 +39,20 @@ public CatalogController(CatalogClient catalogClient) {
}

@GetMapping(path = "details/{id}")
public String details(@PathVariable("id") UUID id, Model model, Cart cart, @RegisteredOAuth2AuthorizedClient("sock") OAuth2AuthorizedClient authorizedClient) {
final Mono<SockResponse> sock = this.catalogClient.getSockWithFallback(id, authorizedClient);
final Flux<SockResponse> relatedProducts = sock.flatMapMany(s -> this.catalogClient.getSocksWithFallback(CatalogOrder.PRICE, 1, 4, s.getTag(), authorizedClient));
final Mono<TagsResponse> tags = this.catalogClient.getTagsWithFallback(authorizedClient);
public String details(@PathVariable("id") UUID id, Model model, Cart cart) {
final Mono<SockResponse> sock = this.catalogClient.getSockWithFallback(id);
final Flux<SockResponse> relatedProducts = sock.flatMapMany(s -> this.catalogClient.getSocksWithFallback(CatalogOrder.PRICE, 1, 4, s.getTag()));
final Mono<TagsResponse> tags = this.catalogClient.getTagsWithFallback();
model.addAttribute("sock", sock);
model.addAttribute("relatedProducts", relatedProducts);
model.addAttribute("tags", tags);
return "shop-details";
}

@GetMapping(path = "tags/{tag}")
public String tag(@PathVariable("tag") List<String> tag, @RequestParam(name = "order", defaultValue = "price") CatalogOrder order, Model model, Cart cart, @RegisteredOAuth2AuthorizedClient("sock") OAuth2AuthorizedClient authorizedClient) {
final Flux<SockResponse> socks = this.catalogClient.getSocksWithFallback(order, 1, 10, tag, authorizedClient);
final Mono<TagsResponse> tags = this.catalogClient.getTagsWithFallback(authorizedClient);
public String tag(@PathVariable("tag") List<String> tag, @RequestParam(name = "order", defaultValue = "price") CatalogOrder order, Model model, Cart cart) {
final Flux<SockResponse> socks = this.catalogClient.getSocksWithFallback(order, 1, 10, tag);
final Mono<TagsResponse> tags = this.catalogClient.getTagsWithFallback();
model.addAttribute("socks", socks);
model.addAttribute("tags", tags);
model.addAttribute("order", order.toString());
Expand All @@ -60,17 +61,20 @@ public String tag(@PathVariable("tag") List<String> tag, @RequestParam(name = "o

@ResponseBody
@GetMapping(path = "images/{fileName:.+}")
public Mono<Resource> getImage(@PathVariable String fileName) {
if (fileName.startsWith("img/")) {
return Mono.just(new ClassPathResource(fileName));
}
return this.catalogClient.getImageWithFallback(fileName);
public Mono<ResponseEntity<Resource>> getImage(@PathVariable String fileName) {
Mono<Resource> image = fileName.startsWith("img/") ? Mono.just(new ClassPathResource(fileName)) : this.catalogClient.getImageWithFallback(fileName);
return image.map(body -> ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(Duration.ofDays(7)))
.body(body));
}

@ResponseBody
@RequestMapping(method = HEAD, path = "images/{fileName:.+}")
public Mono<Resource> headImage(@PathVariable String fileName) {
return this.catalogClient.headImageWithFallback(fileName);
public Mono<ResponseEntity<Resource>> headImage(@PathVariable String fileName) {
return this.catalogClient.headImageWithFallback(fileName)
.map(body -> ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(Duration.ofDays(7)))
.body(body));
}

@ExceptionHandler(SockNotFoundException.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -25,9 +23,9 @@ public HomeController(CatalogClient catalogClient) {
}

@GetMapping(path = "/")
public String home(Model model, Cart cart, @RegisteredOAuth2AuthorizedClient("sock") OAuth2AuthorizedClient authorizedClient) {
final Flux<SockResponse> socks = this.catalogClient.getSocksWithFallback(CatalogOrder.PRICE, 1, 6, List.of("featured"), authorizedClient);
final Mono<TagsResponse> tags = this.catalogClient.getTagsWithFallback(authorizedClient);
public String home(Model model, Cart cart) {
final Flux<SockResponse> socks = this.catalogClient.getSocksWithFallback(CatalogOrder.PRICE, 1, 6, List.of("featured"));
final Mono<TagsResponse> tags = this.catalogClient.getTagsWithFallback();
model.addAttribute("socks", socks);
model.addAttribute("tags", tags);
return "index";
Expand Down
2 changes: 1 addition & 1 deletion shop-ui/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ management.metrics.export.wavefront.uri=https://wavefront.surf
management.metrics.export.wavefront.enabled=false
server.compression.enabled=true
server.compression.min-response-size=1KB
spring.resources.cache.cachecontrol.max-age=1d
spring.web.resources.cache.cachecontrol.max-age=7d
spring.codec.max-in-memory-size=10MB
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=10s
Expand Down

0 comments on commit e6056b8

Please sign in to comment.