Update api/src/main/java/fr/gameovergne/api/service/prestashop/PrestashopClient.java
This commit is contained in:
@@ -3,104 +3,71 @@ package fr.gameovergne.api.service.prestashop;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@Service
|
||||
public class PrestashopClient {
|
||||
|
||||
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 basicAuth; // valeur déjà en Base64, sans le "Basic "
|
||||
private final String basicAuth; // valeur déjà encodée Base64 (sans le "Basic ")
|
||||
|
||||
public PrestashopClient(
|
||||
@Value("${prestashop.base-url}") String baseUrl,
|
||||
@Value("${prestashop.basic-auth}") String basicAuth
|
||||
) {
|
||||
@Value("${prestashop.basic-auth}") String basicAuth) {
|
||||
this.baseUrl = baseUrl;
|
||||
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);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
|
||||
|
||||
HttpEntity<Void> entity = new HttpEntity<>(headers);
|
||||
|
||||
try {
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(url)) // si l’URL est invalide, ça lèvera IllegalArgumentException
|
||||
.header("Authorization", "Basic " + basicAuth)
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
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())
|
||||
ResponseEntity<String> response = restTemplate.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
entity,
|
||||
String.class
|
||||
);
|
||||
|
||||
} catch (IOException | InterruptedException e) {
|
||||
if (e instanceof InterruptedException) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.info("[PrestaShop] Réponse HTTP {} pour {}", response.getStatusCode(), url);
|
||||
|
||||
// Si Presta renvoie autre chose que 2xx, on propage une 502 au front
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
throw new RuntimeException("PrestaShop returned non-2xx status: " + response.getStatusCode());
|
||||
}
|
||||
log.error("[PrestaShop] Erreur I/O pour {}", url, e);
|
||||
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() + "\"}");
|
||||
|
||||
return response.getBody();
|
||||
} catch (RestClientException e) {
|
||||
log.error("[PrestaShop] Erreur lors de l'appel à {}", url, e);
|
||||
throw new RuntimeException("Erreur lors de l'appel à PrestaShop", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String buildUrl(String path, String query) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// baseUrl, ex: https://shop.gameovergne.fr
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user