diff --git a/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/FileUploadProxyController.java b/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/FileUploadProxyController.java new file mode 100644 index 0000000..e8b9a0c --- /dev/null +++ b/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/FileUploadProxyController.java @@ -0,0 +1,85 @@ +package com.continiousdisappointment.apigw.config; + +import org.springframework.core.env.Environment; +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import lombok.RequiredArgsConstructor; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.Arrays; + +@RestController +@RequiredArgsConstructor +public class FileUploadProxyController { + + private final Environment environment; + private final RestTemplate restTemplate; + + @PostMapping("/genai/**") + public ResponseEntity proxyMultipartRequest( + HttpServletRequest request, + @RequestHeader HttpHeaders headers) { + + try { + // Extract the remaining path after /genai + String requestPath = request.getRequestURI(); + String targetPath = requestPath; // Keep the full path including /genai + + // Build target URL + String genaiServiceUrl = getGenAiServiceUrl(); + String targetUrl = genaiServiceUrl + targetPath; + + // Prepare headers for forwarding (exclude host and content-length) + HttpHeaders forwardHeaders = new HttpHeaders(); + headers.forEach((name, values) -> { + String lowerName = name.toLowerCase(); + if (!lowerName.equals("host") && !lowerName.equals("content-length")) { + forwardHeaders.put(name, values); + } + }); + + // Check if this is a multipart request + if (request instanceof MultipartHttpServletRequest multipartRequest) { + // Handle multipart request + MultiValueMap body = new LinkedMultiValueMap<>(); + + // Add all multipart files + multipartRequest.getFileMap().forEach((name, file) -> { + body.add(name, file.getResource()); + }); + + // Add all form parameters + multipartRequest.getParameterMap().forEach((name, values) -> { + for (String value : values) { + body.add(name, value); + } + }); + + forwardHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); + + HttpEntity> entity = new HttpEntity<>(body, forwardHeaders); + return restTemplate.postForEntity(targetUrl, entity, Object.class); + } else { + // Handle non-multipart request + HttpEntity entity = new HttpEntity<>(forwardHeaders); + return restTemplate.postForEntity(targetUrl, entity, Object.class); + } + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Proxy error: " + e.getMessage()); + } + } + + private String getGenAiServiceUrl() { + if (Arrays.asList(environment.getActiveProfiles()).contains("dev")) { + return "http://localhost:8000"; + } + return "http://genai-service:8000"; + } +} \ No newline at end of file diff --git a/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/MultipartConfig.java b/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/MultipartConfig.java new file mode 100644 index 0000000..c675860 --- /dev/null +++ b/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/MultipartConfig.java @@ -0,0 +1,16 @@ +package com.continiousdisappointment.apigw.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.multipart.support.StandardServletMultipartResolver; + +@Configuration +public class MultipartConfig { + + @Bean + public StandardServletMultipartResolver multipartResolver() { + StandardServletMultipartResolver resolver = new StandardServletMultipartResolver(); + resolver.setResolveLazily(true); + return resolver; + } +} \ No newline at end of file diff --git a/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/RestTemplateConfig.java b/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/RestTemplateConfig.java new file mode 100644 index 0000000..8ec5886 --- /dev/null +++ b/server/api-gw/src/main/java/com/continiousdisappointment/apigw/config/RestTemplateConfig.java @@ -0,0 +1,14 @@ +package com.continiousdisappointment.apigw.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +} \ No newline at end of file diff --git a/server/api-gw/src/main/resources/application-dev.yml b/server/api-gw/src/main/resources/application-dev.yml index a26058b..5fdb207 100644 --- a/server/api-gw/src/main/resources/application-dev.yml +++ b/server/api-gw/src/main/resources/application-dev.yml @@ -5,18 +5,13 @@ spring: gateway: mvc: routes: - - id: genai - uri: http://localhost:8000 - predicates: - - Path=/genai/** - - id: chat + - id: user uri: http://localhost:8081 predicates: - Path=/user/** - - id: user + - id: chat uri: http://localhost:8082 predicates: - Path=/chat/** - server: port: 8080 diff --git a/server/api-gw/src/main/resources/application.yaml b/server/api-gw/src/main/resources/application.yaml index 13680e2..34daba3 100644 --- a/server/api-gw/src/main/resources/application.yaml +++ b/server/api-gw/src/main/resources/application.yaml @@ -7,10 +7,6 @@ spring: gateway: mvc: routes: - - id: genai - uri: http://genai-service:8000 - predicates: - - Path=/genai/** - id: user uri: http://user-service:8081 predicates: