diff --git a/pom.xml b/pom.xml
index 5df8603..44653a3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,6 +90,14 @@
org.springframework.boot
spring-boot-starter-actuator
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.retry
+ spring-retry
+
io.micrometer
diff --git a/src/main/java/com/backend/services/ProdAIService.java b/src/main/java/com/backend/services/ProdAIService.java
index 44582b9..0de3186 100644
--- a/src/main/java/com/backend/services/ProdAIService.java
+++ b/src/main/java/com/backend/services/ProdAIService.java
@@ -9,6 +9,7 @@
import org.springframework.ai.content.Media;
import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.retry.TransientAiException;
import org.springframework.context.annotation.Profile;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.ByteArrayResource;
@@ -33,7 +34,7 @@ public class ProdAIService implements MenuAIService {
private final DishRepository dishRepository;
@Retryable(
- retryFor = Exception.class,
+ retryFor = TransientAiException.class,
maxAttempts = 5,
backoff = @Backoff(delay = 1000, multiplier = 2) // 1s, 2s, 4s, 8s
)
@@ -130,4 +131,4 @@ private Dish convertToEntity(AIDishDTO dto) {
dish.setAllergens(dto.getAllergens());
return dish;
}
-}
\ No newline at end of file
+}
diff --git a/src/test/java/com/backend/servicesTests/ProdAIServiceRetryConfigTest.java b/src/test/java/com/backend/servicesTests/ProdAIServiceRetryConfigTest.java
new file mode 100644
index 0000000..f9e96b1
--- /dev/null
+++ b/src/test/java/com/backend/servicesTests/ProdAIServiceRetryConfigTest.java
@@ -0,0 +1,25 @@
+package com.backend.servicesTests;
+
+import com.backend.services.ProdAIService;
+import org.junit.jupiter.api.Test;
+import org.springframework.ai.retry.TransientAiException;
+import org.springframework.retry.annotation.Retryable;
+
+import java.lang.reflect.Method;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ProdAIServiceRetryConfigTest {
+
+ @Test
+ void parseMenuFromImageShouldRetryOnlyTransientAiExceptions() throws NoSuchMethodException {
+ Method method = ProdAIService.class.getMethod("parseMenuFromImage", byte[].class);
+ Retryable retryable = method.getAnnotation(Retryable.class);
+
+ assertThat(retryable).isNotNull();
+ assertThat(retryable.retryFor()).containsExactly(TransientAiException.class);
+ assertThat(retryable.maxAttempts()).isEqualTo(5);
+ assertThat(retryable.backoff().delay()).isEqualTo(1000L);
+ assertThat(retryable.backoff().multiplier()).isEqualTo(2.0);
+ }
+}