Update api/src/main/java/fr/gameovergne/api/service/prestashop/PrestashopClient.java

This commit is contained in:
2025-11-25 18:20:41 +00:00
parent 47edec0d33
commit b289a53154

View File

@@ -3,104 +3,71 @@ package fr.gameovergne.api.service.prestashop;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders; import org.springframework.http.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import java.io.IOException; import org.springframework.web.client.RestTemplate;
import java.net.URI; import org.springframework.web.util.UriComponentsBuilder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;
@Service @Service
public class PrestashopClient { public class PrestashopClient {
private static final Logger log = LoggerFactory.getLogger(PrestashopClient.class); private static final Logger log = LoggerFactory.getLogger(PrestashopClient.class);
private final HttpClient httpClient = HttpClient.newHttpClient(); private final RestTemplate restTemplate = new RestTemplate();
private final String baseUrl; private final String baseUrl;
private final String basicAuth; // valeur déjà en Base64, sans le "Basic " private final String basicAuth; // valeur déjà encodée Base64 (sans le "Basic ")
public PrestashopClient( public PrestashopClient(
@Value("${prestashop.base-url}") String baseUrl, @Value("${prestashop.base-url}") String baseUrl,
@Value("${prestashop.basic-auth}") String basicAuth @Value("${prestashop.basic-auth}") String basicAuth) {
) {
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
this.basicAuth = basicAuth; this.basicAuth = basicAuth;
} }
public ResponseEntity<String> get(String path, String query) { /**
String url = buildUrl(path, query); * Appel GET générique sur l'API PrestaShop.
*
* @param path ex: "/categories"
* @param query ex: "display=%5Bid,name,active%5D&output_format=JSON" ou null
* @return corps de la réponse JSON brute
*/
public String get(String path, String query) {
String url = UriComponentsBuilder
.fromHttpUrl(baseUrl)
.path("/api")
.path(path)
.query(query)
.build(true) // true = ne ré-encode pas les caractères déjà encodés (%5B ...)
.toUriString();
log.info("[PrestaShop] Appel URL = {}", url); log.info("[PrestaShop] Appel URL = {}", url);
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
HttpEntity<Void> entity = new HttpEntity<>(headers);
try { try {
HttpRequest request = HttpRequest.newBuilder() ResponseEntity<String> response = restTemplate.exchange(
.uri(URI.create(url)) // si lURL est invalide, ça lèvera IllegalArgumentException url,
.header("Authorization", "Basic " + basicAuth) HttpMethod.GET,
.GET() entity,
.build(); String.class
HttpResponse<String> response =
httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.info("[PrestaShop] Réponse HTTP {} pour {}", response.statusCode(), url);
HttpHeaders springHeaders = new HttpHeaders();
for (Map.Entry<String, List<String>> entry : response.headers().map().entrySet()) {
springHeaders.put(entry.getKey(), entry.getValue());
}
return new ResponseEntity<>(
response.body(),
springHeaders,
HttpStatus.valueOf(response.statusCode())
); );
} catch (IOException | InterruptedException e) { log.info("[PrestaShop] Réponse HTTP {} pour {}", response.getStatusCode(), url);
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt(); // Si Presta renvoie autre chose que 2xx, on propage une 502 au front
} if (!response.getStatusCode().is2xxSuccessful()) {
log.error("[PrestaShop] Erreur I/O pour {}", url, e); throw new RuntimeException("PrestaShop returned non-2xx status: " + response.getStatusCode());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("{\"error\":\"" + e.getClass().getSimpleName() + "\",\"message\":\"" + e.getMessage() + "\"}");
} catch (Exception e) {
// <-- ICI on récupère IllegalArgumentException, etc.
log.error("[PrestaShop] Erreur inattendue pour {}", url, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("{\"error\":\"" + e.getClass().getSimpleName() + "\",\"message\":\"" + e.getMessage() + "\"}");
}
} }
private String buildUrl(String path, String query) { return response.getBody();
StringBuilder sb = new StringBuilder(); } catch (RestClientException e) {
log.error("[PrestaShop] Erreur lors de l'appel à {}", url, e);
// baseUrl, ex: https://shop.gameovergne.fr throw new RuntimeException("Erreur lors de l'appel à PrestaShop", e);
sb.append(baseUrl);
if (baseUrl.endsWith("/")) {
sb.setLength(sb.length() - 1);
} }
// /api
sb.append("/api");
// path, ex: "/suppliers"
if (path != null && !path.isBlank()) {
if (!path.startsWith("/")) {
sb.append('/');
}
sb.append(path);
}
// query : on NE RÉ-ENCODE PAS, on colle tel quel (déjà encodée par Angular / le navigateur)
if (query != null && !query.isBlank()) {
sb.append('?').append(query);
}
return sb.toString();
} }
} }