feat(recipe/application): implementado servicio para la búsqueda de recetas…

feat(recipe/application): implementado servicio para la búsqueda de recetas mediante la conexión con el micro servicio
parent 66cdd85e
package com.example.apprecetas.recipe.application;
import com.example.apprecetas.recipe.domain.entity.Recipe;
import java.util.List;
public interface SearchAIRecipesUseCase {
record SearchResult(String sessionId, List<Recipe> recipes) {
}
SearchResult searchRecipes(String ingredients);
List<Recipe> searchMoreRecipes(String sessionId);
Recipe getRecipeDetail(String sessionId, int index);
}
package com.example.apprecetas.recipe.application.impl;
import com.example.apprecetas.exception.PythonApiException;
import com.example.apprecetas.recipe.application.SearchAIRecipesUseCase;
import com.example.apprecetas.recipe.domain.entity.Recipe;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class SearchAIRecipesUseCaseImpl implements SearchAIRecipesUseCase {
private final WebClient webClient;
// Clase auxiliar interna para la respuesta de Python
private static class PythonSearchResponse {
public String sessionId;
public List<Recipe> recipes;
}
public SearchResult searchRecipes(String ingredients) {
String token = SecurityContextHolder.getContext().getAuthentication().getName();
PythonSearchResponse response = webClient.post()
.uri("/recipe/search")
.header("Authorization", "Bearer " + token)
.bodyValue(Map.of("ingredients", ingredients))
.retrieve()
.onStatus(HttpStatusCode::isError, clientResponse ->
clientResponse.bodyToMono(String.class)
.flatMap(errorBody -> {
HttpStatus status = HttpStatus.resolve(clientResponse.statusCode().value());
return Mono.error(new PythonApiException(status, errorBody));
})
)
.bodyToMono(PythonSearchResponse.class)
.block();
if (response != null)
return new SearchResult(response.sessionId, response.recipes);
return new SearchResult(null, List.of());
}
public List<Recipe> searchMoreRecipes(String sessionId) {
if (sessionId == null || sessionId.isBlank())
throw new IllegalArgumentException("El ID de sesión no puede ser nulo.");
String token = SecurityContextHolder.getContext().getAuthentication().getName();
PythonSearchResponse response = webClient.post()
.uri("/recipe/search/more")
.header("X-Session-ID", sessionId)
.header("Authorization", "Bearer " + token)
.retrieve()
.onStatus(HttpStatusCode::isError, clientResponse ->
clientResponse.bodyToMono(String.class)
.flatMap(errorBody -> {
HttpStatus status = HttpStatus.resolve(clientResponse.statusCode().value());
return Mono.error(new PythonApiException(status, errorBody));
})
)
.bodyToMono(PythonSearchResponse.class)
.block();
return (response != null) ? response.recipes : List.of();
}
public Recipe getRecipeDetail(String sessionId, int index) {
if (sessionId == null || sessionId.isBlank())
throw new IllegalArgumentException("El ID de sesión no puede ser nulo.");
String token = SecurityContextHolder.getContext().getAuthentication().getName();
return webClient.post()
.uri("/recipe/detail/{index}", index)
.header("X-Session-ID", sessionId) // Se pasa el ID recibido como parámetro
.header("Authorization", "Bearer " + token)
.retrieve()
.onStatus(HttpStatusCode::isError, clientResponse ->
clientResponse.bodyToMono(String.class)
.flatMap(errorBody -> {
HttpStatus status = HttpStatus.resolve(clientResponse.statusCode().value());
return Mono.error(new PythonApiException(status, errorBody));
})
)
.bodyToMono(Recipe.class)
.block();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment