Merge pull request 'refactor: add retry mechanism to Feign clients for improved resilience' (#36) from refactor-architecture into main
Reviewed-on: #36
This commit is contained in:
commit
baeffd6f15
@ -3,15 +3,28 @@ package com.magamochi.catalog.client;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.resilience.annotation.Retryable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@FeignClient(name = "aniList", url = "https://graphql.anilist.co")
|
||||
public interface AniListClient {
|
||||
@PostMapping
|
||||
@Retryable(
|
||||
maxRetries = 5,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
MangaResponse getManga(@RequestBody GraphQLRequest request);
|
||||
|
||||
@PostMapping
|
||||
@Retryable(
|
||||
maxRetries = 5,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
MangaSearchResponse searchManga(@RequestBody SearchGraphQLRequest request);
|
||||
|
||||
record GraphQLRequest(String query, Variables variables) {
|
||||
|
||||
@ -3,6 +3,7 @@ package com.magamochi.catalog.client;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.resilience.annotation.Retryable;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
@ -10,9 +11,21 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
@FeignClient(name = "jikan", url = "https://api.jikan.moe/v4/manga")
|
||||
public interface JikanClient {
|
||||
@GetMapping
|
||||
@Retryable(
|
||||
maxRetries = 3,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
SearchResponse mangaSearch(@RequestParam String q);
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@Retryable(
|
||||
maxRetries = 3,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
MangaResponse getMangaById(@PathVariable Long id);
|
||||
|
||||
record SearchResponse(List<MangaData> data) {
|
||||
|
||||
@ -4,18 +4,37 @@ import com.magamochi.model.dto.MangaDexMangaDTO;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.resilience.annotation.Retryable;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@FeignClient(name = "mangaDex", url = "https://api.mangadex.org")
|
||||
public interface MangaDexClient {
|
||||
@GetMapping("/manga/{id}")
|
||||
@Retryable(
|
||||
maxRetries = 3,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
MangaDexMangaDTO getManga(@PathVariable UUID id);
|
||||
|
||||
@GetMapping("/manga/{id}/feed")
|
||||
@Retryable(
|
||||
maxRetries = 3,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
MangaDexMangaFeedDTO getMangaFeed(
|
||||
@PathVariable UUID id, @RequestParam("contentRating[]") List<String> contentRating);
|
||||
|
||||
@GetMapping("/manga/{id}/feed")
|
||||
@Retryable(
|
||||
maxRetries = 3,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
MangaDexMangaFeedDTO getMangaFeed(
|
||||
@PathVariable UUID id,
|
||||
@RequestParam int limit,
|
||||
@ -23,6 +42,12 @@ public interface MangaDexClient {
|
||||
@RequestParam("contentRating[]") List<String> contentRating);
|
||||
|
||||
@GetMapping("/at-home/server/{chapterId}")
|
||||
@Retryable(
|
||||
maxRetries = 3,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
MangaChapterDataDTO getMangaChapter(@PathVariable UUID chapterId);
|
||||
|
||||
record MangaDexMangaFeedDTO(
|
||||
|
||||
@ -2,11 +2,18 @@ package com.magamochi.client;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.resilience.annotation.Retryable;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@FeignClient(name = "ntfy", url = "${ntfy.endpoint}")
|
||||
public interface NtfyClient {
|
||||
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Retryable(
|
||||
maxRetries = 3,
|
||||
delay = 1000,
|
||||
multiplier = 2,
|
||||
maxDelay = 5000,
|
||||
includes = Exception.class)
|
||||
void notify(@RequestBody Request dto);
|
||||
|
||||
record Request(String topic, String message, String title) {}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.magamochi.image.queue.consumer;
|
||||
|
||||
import static java.util.Objects.nonNull;
|
||||
|
||||
import com.magamochi.common.queue.command.ImageFetchCommand;
|
||||
import com.magamochi.common.queue.command.ImageUpdateCommand;
|
||||
import com.magamochi.image.queue.producer.ImageUpdateProducer;
|
||||
@ -21,8 +23,9 @@ public class ImageFetchConsumer {
|
||||
log.info("Received image fetch command: {}", command);
|
||||
|
||||
var imageId = imageFetchService.fetchImage(command.url(), command.contentType());
|
||||
|
||||
imageUpdateProducer.publishImageUpdateCommand(
|
||||
new ImageUpdateCommand(command.entityId(), imageId), command.contentType());
|
||||
if (nonNull(imageId)) {
|
||||
imageUpdateProducer.publishImageUpdateCommand(
|
||||
new ImageUpdateCommand(command.entityId(), imageId), command.contentType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user