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 e594280..4289475 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 @@ -10,39 +10,74 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @RestController -@RequestMapping("/api") // important : ton context-path est /gameovergne-api, donc ici on reste sur /api +@RequestMapping("/api/ps") // <-- IMPORTANT : préfixe unique pour tout le proxy Presta @RequiredArgsConstructor @Slf4j public class PrestashopProxyController { private final PrestashopClient prestashopClient; + /** + * Extrait le path Presta à partir de l'URL appelée côté front. + * + * Exemple : + * contextPath = /gameovergne-api + * requestURI = /gameovergne-api/api/ps/categories + * prefixToStrip = /gameovergne-api/api/ps + * => pathForwarded = /categories + */ + private String extractPrestaPath(HttpServletRequest request) { + String requestUri = request.getRequestURI(); + String prefix = request.getContextPath() + "/api/ps"; + if (!requestUri.startsWith(prefix)) { + // Sécurité, mais normalement ça ne doit jamais arriver + log.warn("extractPrestaPath: URI {} ne commence pas par prefix {}", requestUri, prefix); + return requestUri; + } + String path = requestUri.substring(prefix.length()); // garde le '/' de début + if (path.isEmpty()) { + path = "/"; // Cas extrême, normalement on ne l’utilise pas + } + return path; + } + // ---------- GET générique /api/ps/** ---------- - @GetMapping(path = "/ps/**", produces = MediaType.APPLICATION_JSON_VALUE) + @GetMapping(path = "/**", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity proxyGet(HttpServletRequest request) { - String requestUri = request.getRequestURI(); // ex: /gameovergne-api/api/ps/categories - String path = requestUri.substring(request.getContextPath().length() + "/api".length()); // -> /ps/categories - String rawQuery = request.getQueryString(); + String path = extractPrestaPath(request); // ex: /categories + String rawQuery = request.getQueryString(); // ex: display=[id,name,active]&output_format=JSON - return prestashopClient.getWithRawQuery(path, rawQuery); + log.info("[Proxy] GET {}", path); + + try { + return prestashopClient.getWithRawQuery(path, rawQuery); + } catch (Exception ex) { + log.error("[Proxy] GET error on {}?{} ", path, rawQuery, ex); + // On renvoie une 502 propre plutôt que laisser Spring balancer un stacktrace + return ResponseEntity + .status(502) + .contentType(MediaType.APPLICATION_JSON) + .body(""" + {"error":"Error while calling PrestaShop WebService"} + """); + } } // ---------- POST générique XML /api/ps/** (catégories, produits, etc.) ---------- @PostMapping( - path = "/ps/**", + path = "/**", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE ) public ResponseEntity proxyPost(HttpServletRequest request, @RequestBody String xmlBody) { - String requestUri = request.getRequestURI(); - String path = requestUri.substring(request.getContextPath().length() + "/api".length()); // ex: /ps/categories + String path = extractPrestaPath(request); // ex: /categories String rawQuery = request.getQueryString(); - log.info("XML envoyé à Presta:\n{}", xmlBody); + log.info("XML envoyé à Presta (POST {}):\n{}", path, xmlBody); return prestashopClient.postWithRawQuery(path, rawQuery, xmlBody); } @@ -50,38 +85,38 @@ public class PrestashopProxyController { // ---------- PUT générique XML /api/ps/** ---------- @PutMapping( - path = "/ps/**", + path = "/**", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE ) public ResponseEntity proxyPut(HttpServletRequest request, @RequestBody String xmlBody) { - String requestUri = request.getRequestURI(); - String path = requestUri.substring(request.getContextPath().length() + "/api".length()); + String path = extractPrestaPath(request); // ex: /products/446 String rawQuery = request.getQueryString(); - log.info("XML envoyé (proxy PUT):\n{}", xmlBody); + log.info("XML envoyé (proxy PUT {}):\n{}", path, xmlBody); return prestashopClient.putWithRawQuery(path, rawQuery, xmlBody); } // ---------- DELETE générique /api/ps/** ---------- - @DeleteMapping(path = "/ps/**", produces = MediaType.APPLICATION_XML_VALUE) + @DeleteMapping(path = "/**", produces = MediaType.APPLICATION_XML_VALUE) public ResponseEntity proxyDelete(HttpServletRequest request) { - String requestUri = request.getRequestURI(); - String path = requestUri.substring(request.getContextPath().length() + "/api".length()); + String path = extractPrestaPath(request); // ex: /categories/10 String rawQuery = request.getQueryString(); + log.info("[Proxy] DELETE {}", path); + return prestashopClient.deleteWithRawQuery(path, rawQuery); } // ---------- UPLOAD IMAGE PRODUIT /api/ps/images/products/{productId} ---------- @PostMapping( - path = "/ps/images/products/{productId}", + path = "/images/products/{productId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_XML_VALUE ) @@ -89,10 +124,12 @@ public class PrestashopProxyController { @PathVariable("productId") String productId, @RequestPart("image") MultipartFile imageFile) { - String rawQuery = request.getQueryString(); // si un jour tu veux passer des options + String rawQuery = request.getQueryString(); + log.info("[Proxy] Upload image produit {} (size={} bytes, ct={})", productId, imageFile.getSize(), imageFile.getContentType()); + // Là on ne passe PAS par extractPrestaPath : on a un endpoint dédié côté PrestashopClient return prestashopClient.uploadProductImage(productId, rawQuery, imageFile); } } \ No newline at end of file