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.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 l’URL 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()) {
|
||||||
|
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)
|
return response.getBody();
|
||||||
.body("{\"error\":\"" + e.getClass().getSimpleName() + "\",\"message\":\"" + e.getMessage() + "\"}");
|
} catch (RestClientException e) {
|
||||||
} catch (Exception e) {
|
log.error("[PrestaShop] Erreur lors de l'appel à {}", url, e);
|
||||||
// <-- ICI on récupère IllegalArgumentException, etc.
|
throw new RuntimeException("Erreur lors de l'appel à PrestaShop", e);
|
||||||
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) {
|
|
||||||
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