refactor: improve image fetching with retry mechanism and error handling

This commit is contained in:
Rodrigo Verdiani 2026-03-28 16:11:28 -03:00
parent 420b522edf
commit 3c8038041b
2 changed files with 21 additions and 15 deletions

View File

@ -1,7 +1,5 @@
package com.magamochi.image.queue.consumer; 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.ImageFetchCommand;
import com.magamochi.common.queue.command.ImageUpdateCommand; import com.magamochi.common.queue.command.ImageUpdateCommand;
import com.magamochi.image.queue.producer.ImageUpdateProducer; import com.magamochi.image.queue.producer.ImageUpdateProducer;
@ -22,10 +20,13 @@ public class ImageFetchConsumer {
public void receiveImageFetchCommand(ImageFetchCommand command) { public void receiveImageFetchCommand(ImageFetchCommand command) {
log.info("Received image fetch command: {}", command); log.info("Received image fetch command: {}", command);
var imageId = imageFetchService.fetchImage(command.url(), command.contentType()); try {
if (nonNull(imageId)) { var imageId = imageFetchService.fetchImage(command.url(), command.contentType());
imageUpdateProducer.publishImageUpdateCommand( imageUpdateProducer.publishImageUpdateCommand(
new ImageUpdateCommand(command.entityId(), imageId), command.contentType()); new ImageUpdateCommand(command.entityId(), imageId), command.contentType());
} catch (Exception e) {
log.error("Failed to fetch image from URL.", e);
} }
} }
} }

View File

@ -4,6 +4,7 @@ import static java.util.Objects.nonNull;
import com.google.common.util.concurrent.RateLimiter; import com.google.common.util.concurrent.RateLimiter;
import com.magamochi.common.model.enumeration.ContentType; import com.magamochi.common.model.enumeration.ContentType;
import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
@ -14,6 +15,7 @@ import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import org.springframework.resilience.annotation.Retryable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Log4j2 @Log4j2
@ -28,20 +30,23 @@ public class ImageFetchService {
HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build(); HttpClient.newBuilder().followRedirects(HttpClient.Redirect.NORMAL).build();
private final Tika tika = new Tika(); private final Tika tika = new Tika();
public UUID fetchImage(String imageUrl, ContentType contentType) { @Retryable(
try { maxRetries = 5,
var request = HttpRequest.newBuilder(URI.create(imageUrl.trim())).GET().build(); delay = 1000,
multiplier = 2,
maxDelay = 5000,
includes = Exception.class,
excludes = NoSuchAlgorithmException.class)
public UUID fetchImage(String imageUrl, ContentType contentType)
throws IOException, InterruptedException, NoSuchAlgorithmException {
var request = HttpRequest.newBuilder(URI.create(imageUrl.trim())).GET().build();
imageDownloadRateLimiter.acquire(); imageDownloadRateLimiter.acquire();
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray()); var response = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray());
var imageBytes = response.body(); var imageBytes = response.body();
return uploadImage(imageBytes, response, contentType); return uploadImage(imageBytes, response, contentType);
} catch (Exception e) {
log.error("Failed to fetch image from URL: {}", imageUrl, e);
return null;
}
} }
public UUID uploadImage( public UUID uploadImage(