diff --git a/api/src/main/java/fr/gameovergne/api/controller/prestashop/PrestashopProxyController.java b/api/src/main/java/fr/gameovergne/api/controller/prestashop/PrestashopProxyController.java index b7d68f9..859321c 100644 --- a/api/src/main/java/fr/gameovergne/api/controller/prestashop/PrestashopProxyController.java +++ b/api/src/main/java/fr/gameovergne/api/controller/prestashop/PrestashopProxyController.java @@ -16,38 +16,65 @@ public class PrestashopProxyController { this.prestashopClient = prestashopClient; } + // Utilitaire pour extraire /products, /products/446, etc. 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("/**") public ResponseEntity proxyGet(HttpServletRequest 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 proxyPost(HttpServletRequest request, @RequestBody String xmlBody) { - String path = extractPath(request); - String body = prestashopClient.post(path, xmlBody); - return ResponseEntity.ok(body); - } - - // ---------- PUT ---------- @PutMapping("/**") - public ResponseEntity proxyPut(HttpServletRequest request, @RequestBody String xmlBody) { + public ResponseEntity proxyPut(HttpServletRequest request, + @RequestBody String body) { String path = extractPath(request); - String body = prestashopClient.put(path, xmlBody); - return ResponseEntity.ok(body); + String query = request.getQueryString(); + + String responseBody = prestashopClient.put(path, query, body); + + return ResponseEntity + .ok() + .contentType(MediaType.APPLICATION_JSON) + .body(responseBody); } - // ---------- DELETE ---------- - @DeleteMapping("/**") - public ResponseEntity proxyDelete(HttpServletRequest request) { + @PostMapping("/**") + public ResponseEntity proxyPost(HttpServletRequest request, + @RequestBody String body) { String path = extractPath(request); - prestashopClient.delete(path); - return ResponseEntity.noContent().build(); + String query = request.getQueryString(); + + String responseBody = prestashopClient.post(path, query, body); + + return ResponseEntity + .ok() + .contentType(MediaType.APPLICATION_JSON) + .body(responseBody); + } + + @DeleteMapping("/**") + public ResponseEntity 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); } } \ No newline at end of file diff --git a/api/src/main/java/fr/gameovergne/api/service/prestashop/PrestashopClient.java b/api/src/main/java/fr/gameovergne/api/service/prestashop/PrestashopClient.java index b357024..9b1d1af 100644 --- a/api/src/main/java/fr/gameovergne/api/service/prestashop/PrestashopClient.java +++ b/api/src/main/java/fr/gameovergne/api/service/prestashop/PrestashopClient.java @@ -5,18 +5,22 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; +import java.util.List; + @Service public class PrestashopClient { private static final Logger log = LoggerFactory.getLogger(PrestashopClient.class); private final RestTemplate restTemplate = new RestTemplate(); + private final String baseUrl; - private final String basicAuth; + private final String basicAuth; // base64 SANS le "Basic " public PrestashopClient( @Value("${prestashop.base-url}") String baseUrl, @@ -26,38 +30,42 @@ public class PrestashopClient { 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) .path("/api") .path(path) .queryParam("output_format", "JSON") - .queryParam("display", "full") - .build(true) - .toUriString(); - } + .queryParam("display", "full"); + + String url = builder.build(true).toUriString(); + + log.info("[PrestaShop] GET {}", url); - private HttpHeaders buildHeaders() { HttpHeaders headers = new HttpHeaders(); headers.set(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth); - headers.setContentType(MediaType.APPLICATION_XML); // Presta exige XML pour POST/PUT - headers.setAccept(java.util.List.of(MediaType.APPLICATION_JSON)); - return headers; - } + headers.setAccept(List.of(MediaType.APPLICATION_JSON)); - // ========== GET ========== - public String get(String path) { - String url = buildUrl(path); - log.info("[PrestaShop] GET {}", url); + HttpEntity entity = new HttpEntity<>(headers); try { ResponseEntity response = restTemplate.exchange( url, HttpMethod.GET, - new HttpEntity<>(buildHeaders()), + entity, 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(); } catch (RestClientException e) { log.error("[PrestaShop] Erreur GET {}", url, e); @@ -65,58 +73,150 @@ public class PrestashopClient { } } - // ========== POST ========== - public String post(String path, String xmlBody) { - String url = buildUrl(path); - log.info("[PrestaShop] POST {}", url); + // ========================= + // PUT : on respecte la query du front + // ========================= + public String put(String path, String query, String body) { + UriComponentsBuilder builder = UriComponentsBuilder + .fromHttpUrl(baseUrl) + .path("/api") + .path(path); - try { - ResponseEntity response = restTemplate.exchange( - url, - 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); + if (query != null && !query.isBlank()) { + // on laisse Angular décider (ex: output_format=JSON) + builder.query(query); } - } - // ========== PUT ========== - public String put(String path, String xmlBody) { - String url = buildUrl(path); + String url = builder.build(true).toUriString(); 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 entity = new HttpEntity<>(body, headers); try { ResponseEntity response = restTemplate.exchange( url, HttpMethod.PUT, - new HttpEntity<>(xmlBody, buildHeaders()), + entity, 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(); + } 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) { log.error("[PrestaShop] Erreur PUT {}", url, e); throw new RuntimeException("Erreur PUT PrestaShop", e); } } - // ========== DELETE ========== - public void delete(String path) { - String url = buildUrl(path); - log.info("[PrestaShop] DELETE {}", url); + // ========================= + // POST : création + // ========================= + 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 entity = new HttpEntity<>(body, headers); try { - restTemplate.exchange( + ResponseEntity 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 entity = new HttpEntity<>(headers); + + try { + ResponseEntity response = restTemplate.exchange( url, HttpMethod.DELETE, - new HttpEntity<>(buildHeaders()), - Void.class + entity, + 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) { log.error("[PrestaShop] Erreur DELETE {}", url, e); throw new RuntimeException("Erreur DELETE PrestaShop", e);