Refactor PrestashopClient and PrestashopProxyController to enhance API request handling and improve error logging

This commit is contained in:
Vincent Guillet
2025-11-25 21:35:11 +01:00
parent 21cdb3dc30
commit 4b29e116cf
2 changed files with 192 additions and 65 deletions

View File

@@ -16,38 +16,65 @@ public class PrestashopProxyController {
this.prestashopClient = prestashopClient; this.prestashopClient = prestashopClient;
} }
// Utilitaire pour extraire /products, /products/446, etc.
private String extractPath(HttpServletRequest request) { private String extractPath(HttpServletRequest request) {
return request.getRequestURI().replaceFirst("^/api/ps", ""); String fullPath = request.getRequestURI(); // ex: /api/ps/products/446
String contextPath = request.getContextPath(); // souvent ""
String relative = fullPath.substring(contextPath.length()); // /api/ps/products/446
return relative.replaceFirst("^/api/ps", ""); // => /products/446
} }
// ---------- GET ----------
@GetMapping("/**") @GetMapping("/**")
public ResponseEntity<String> proxyGet(HttpServletRequest request) { public ResponseEntity<String> proxyGet(HttpServletRequest request) {
String path = extractPath(request); String path = extractPath(request);
return ResponseEntity.ok(prestashopClient.get(path)); String query = request.getQueryString();
String body = prestashopClient.get(path, query);
return ResponseEntity
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(body);
} }
// ---------- POST ----------
@PostMapping("/**")
public ResponseEntity<String> proxyPost(HttpServletRequest request, @RequestBody String xmlBody) {
String path = extractPath(request);
String body = prestashopClient.post(path, xmlBody);
return ResponseEntity.ok(body);
}
// ---------- PUT ----------
@PutMapping("/**") @PutMapping("/**")
public ResponseEntity<String> proxyPut(HttpServletRequest request, @RequestBody String xmlBody) { public ResponseEntity<String> proxyPut(HttpServletRequest request,
@RequestBody String body) {
String path = extractPath(request); String path = extractPath(request);
String body = prestashopClient.put(path, xmlBody); String query = request.getQueryString();
return ResponseEntity.ok(body);
String responseBody = prestashopClient.put(path, query, body);
return ResponseEntity
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(responseBody);
} }
// ---------- DELETE ---------- @PostMapping("/**")
@DeleteMapping("/**") public ResponseEntity<String> proxyPost(HttpServletRequest request,
public ResponseEntity<Void> proxyDelete(HttpServletRequest request) { @RequestBody String body) {
String path = extractPath(request); String path = extractPath(request);
prestashopClient.delete(path); String query = request.getQueryString();
return ResponseEntity.noContent().build();
String responseBody = prestashopClient.post(path, query, body);
return ResponseEntity
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(responseBody);
}
@DeleteMapping("/**")
public ResponseEntity<String> proxyDelete(HttpServletRequest request) {
String path = extractPath(request);
String query = request.getQueryString();
String responseBody = prestashopClient.delete(path, query);
return ResponseEntity
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(responseBody);
} }
} }

View File

@@ -5,18 +5,22 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*; import org.springframework.http.*;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import java.util.List;
@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 RestTemplate restTemplate = new RestTemplate(); private final RestTemplate restTemplate = new RestTemplate();
private final String baseUrl; private final String baseUrl;
private final String basicAuth; private final String basicAuth; // base64 SANS le "Basic "
public PrestashopClient( public PrestashopClient(
@Value("${prestashop.base-url}") String baseUrl, @Value("${prestashop.base-url}") String baseUrl,
@@ -26,38 +30,42 @@ public class PrestashopClient {
this.basicAuth = basicAuth; this.basicAuth = basicAuth;
} }
private String buildUrl(String path) { // =========================
return UriComponentsBuilder // GET : on force JSON + full
// =========================
public String get(String path, String ignoredQuery) {
UriComponentsBuilder builder = UriComponentsBuilder
.fromHttpUrl(baseUrl) .fromHttpUrl(baseUrl)
.path("/api") .path("/api")
.path(path) .path(path)
.queryParam("output_format", "JSON") .queryParam("output_format", "JSON")
.queryParam("display", "full") .queryParam("display", "full");
.build(true)
.toUriString(); String url = builder.build(true).toUriString();
}
log.info("[PrestaShop] GET {}", url);
private HttpHeaders buildHeaders() {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth); headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
headers.setContentType(MediaType.APPLICATION_XML); // Presta exige XML pour POST/PUT headers.setAccept(List.of(MediaType.APPLICATION_JSON));
headers.setAccept(java.util.List.of(MediaType.APPLICATION_JSON));
return headers;
}
// ========== GET ========== HttpEntity<Void> entity = new HttpEntity<>(headers);
public String get(String path) {
String url = buildUrl(path);
log.info("[PrestaShop] GET {}", url);
try { try {
ResponseEntity<String> response = restTemplate.exchange( ResponseEntity<String> response = restTemplate.exchange(
url, url,
HttpMethod.GET, HttpMethod.GET,
new HttpEntity<>(buildHeaders()), entity,
String.class String.class
); );
log.info("[PrestaShop] Réponse GET {} pour {}", response.getStatusCode(), url);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("PrestaShop returned non-2xx status: "
+ response.getStatusCode() + " for URL " + url);
}
return response.getBody(); return response.getBody();
} catch (RestClientException e) { } catch (RestClientException e) {
log.error("[PrestaShop] Erreur GET {}", url, e); log.error("[PrestaShop] Erreur GET {}", url, e);
@@ -65,58 +73,150 @@ public class PrestashopClient {
} }
} }
// ========== POST ========== // =========================
public String post(String path, String xmlBody) { // PUT : on respecte la query du front
String url = buildUrl(path); // =========================
log.info("[PrestaShop] POST {}", url); public String put(String path, String query, String body) {
UriComponentsBuilder builder = UriComponentsBuilder
.fromHttpUrl(baseUrl)
.path("/api")
.path(path);
try { if (query != null && !query.isBlank()) {
ResponseEntity<String> response = restTemplate.exchange( // on laisse Angular décider (ex: output_format=JSON)
url, builder.query(query);
HttpMethod.POST,
new HttpEntity<>(xmlBody, buildHeaders()),
String.class
);
return response.getBody();
} catch (RestClientException e) {
log.error("[PrestaShop] Erreur POST {}", url, e);
throw new RuntimeException("Erreur POST PrestaShop", e);
}
} }
// ========== PUT ========== String url = builder.build(true).toUriString();
public String put(String path, String xmlBody) {
String url = buildUrl(path);
log.info("[PrestaShop] PUT {}", url); log.info("[PrestaShop] PUT {}", url);
log.debug("[PrestaShop] PUT body = {}", body);
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<>(body, headers);
try { try {
ResponseEntity<String> response = restTemplate.exchange( ResponseEntity<String> response = restTemplate.exchange(
url, url,
HttpMethod.PUT, HttpMethod.PUT,
new HttpEntity<>(xmlBody, buildHeaders()), entity,
String.class String.class
); );
log.info("[PrestaShop] Réponse PUT {} pour {}", response.getStatusCode(), url);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("PrestaShop returned non-2xx status: "
+ response.getStatusCode() + " for URL " + url);
}
return response.getBody(); return response.getBody();
} catch (HttpStatusCodeException e) {
// Ici on log le body d'erreur de Presta !
log.error("[PrestaShop] Erreur PUT {} status={} body={}",
url, e.getStatusCode(), e.getResponseBodyAsString(), e);
throw new RuntimeException("Erreur PUT PrestaShop", e);
} catch (RestClientException e) { } catch (RestClientException e) {
log.error("[PrestaShop] Erreur PUT {}", url, e); log.error("[PrestaShop] Erreur PUT {}", url, e);
throw new RuntimeException("Erreur PUT PrestaShop", e); throw new RuntimeException("Erreur PUT PrestaShop", e);
} }
} }
// ========== DELETE ========== // =========================
public void delete(String path) { // POST : création
String url = buildUrl(path); // =========================
log.info("[PrestaShop] DELETE {}", url); public String post(String path, String query, String body) {
UriComponentsBuilder builder = UriComponentsBuilder
.fromHttpUrl(baseUrl)
.path("/api")
.path(path);
if (query != null && !query.isBlank()) {
builder.query(query);
}
String url = builder.build(true).toUriString();
log.info("[PrestaShop] POST {}", url);
log.debug("[PrestaShop] POST body = {}", body);
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<>(body, headers);
try { try {
restTemplate.exchange( ResponseEntity<String> response = restTemplate.exchange(
url,
HttpMethod.POST,
entity,
String.class
);
log.info("[PrestaShop] Réponse POST {} pour {}", response.getStatusCode(), url);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("PrestaShop returned non-2xx status: "
+ response.getStatusCode() + " for URL " + url);
}
return response.getBody();
} catch (HttpStatusCodeException e) {
log.error("[PrestaShop] Erreur POST {} status={} body={}",
url, e.getStatusCode(), e.getResponseBodyAsString(), e);
throw new RuntimeException("Erreur POST PrestaShop", e);
} catch (RestClientException e) {
log.error("[PrestaShop] Erreur POST {}", url, e);
throw new RuntimeException("Erreur POST PrestaShop", e);
}
}
// =========================
// DELETE : suppression
// =========================
public String delete(String path, String query) {
UriComponentsBuilder builder = UriComponentsBuilder
.fromHttpUrl(baseUrl)
.path("/api")
.path(path);
if (query != null && !query.isBlank()) {
builder.query(query);
}
String url = builder.build(true).toUriString();
log.info("[PrestaShop] DELETE {}", url);
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
HttpEntity<Void> entity = new HttpEntity<>(headers);
try {
ResponseEntity<String> response = restTemplate.exchange(
url, url,
HttpMethod.DELETE, HttpMethod.DELETE,
new HttpEntity<>(buildHeaders()), entity,
Void.class String.class
); );
log.info("[PrestaShop] Réponse DELETE {} pour {}", response.getStatusCode(), url);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("PrestaShop returned non-2xx status: "
+ response.getStatusCode() + " for URL " + url);
}
return response.getBody();
} catch (HttpStatusCodeException e) {
log.error("[PrestaShop] Erreur DELETE {} status={} body={}",
url, e.getStatusCode(), e.getResponseBodyAsString(), e);
throw new RuntimeException("Erreur DELETE PrestaShop", e);
} catch (RestClientException e) { } catch (RestClientException e) {
log.error("[PrestaShop] Erreur DELETE {}", url, e); log.error("[PrestaShop] Erreur DELETE {}", url, e);
throw new RuntimeException("Erreur DELETE PrestaShop", e); throw new RuntimeException("Erreur DELETE PrestaShop", e);