Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect response codes for routing PUT/DELETE requests #3509

Open
predhme opened this issue Aug 27, 2024 · 1 comment
Open

Incorrect response codes for routing PUT/DELETE requests #3509

predhme opened this issue Aug 27, 2024 · 1 comment

Comments

@predhme
Copy link

predhme commented Aug 27, 2024

I am using the latest Spring Cloud Gateway MVC via Spring Boot

I am attempting to place a relatively naive Gateway behind an Nginx Ingress that will sit in between a bunch of Microservices. The idea is that I can perform things like, authentication, authorization, etc in the gateway while deferring to the microservices for the business logic. I have a working implementation for the most part with one major problem. For example, consider an Entity microservice:

@RestController
@RequestMapping("/entity")
public class EntityController {

    @GetMapping(value = "/{id}", consumes = MediaType.ALL_VALUE)
    @ResponseStatus(HttpStatus.OK)
    public Entity getEntity(@PathVariable("id") String id) {
        return entityService.get(id);
    }

    @PutMapping(value = "/{id}", consumes = MediaType.ALL_VALUE)
    @ResponseStatus(HttpStatus.OK)
    public Entity updateEntity(@PathVariable("id") String id) {
        return entityService.update(id);
    }

    @DeleteMapping(value = "/{id}", consumes = MediaType.ALL_VALUE)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public Entity deleteEntity(@PathVariable("id") String id) {
        return entityService.delete(id);
    }

}

In front of the Entity service I have a route

@Value("${services.entity.uri}")
private String entityApiUri;

@Bean
public RouterFunction<ServerResponse> entityRoute() {
    return route()
            .route(path("/entity/**"), http(entityApiUri))
            .before(
                 auth().andThen(
                 audit()).andThen(
                 stripPrefix()))
            .build();
}

The GET endpoints work when I call it with valid and invalid IDs. That is, I get a 200 or 404 respectively. However, PUT and DELETE return a 500 error. In fact, looks like I am getting a FileNotFoundException:

2024-08-27T18:04:17.936Z ERROR 1 --- [api-gateway] [nio-8080-exec-2] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/api-gateway] threw exception [Request processing failed: org.springframework.web.client.ResourceAccessException: I/O error on DELETE request for "http://entity-service:8080/entity-service/entity/1": http://entity-service:8080/entity-service/entity/1] with root cause
java.io.FileNotFoundException: http://entity-service:8080/entity-service/entity/1
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
	at org.springframework.http.client.SimpleClientHttpResponse.getBody(SimpleClientHttpResponse.java:89)
	at org.springframework.web.client.DefaultRestClient$DefaultConvertibleClientHttpResponse.getBody(DefaultRestClient.java:748)
	at org.springframework.cloud.gateway.server.mvc.handler.RestClientProxyExchange.doExchange(RestClientProxyExchange.java:50)
	at org.springframework.cloud.gateway.server.mvc.handler.RestClientProxyExchange.lambda$exchange$2(RestClientProxyExchange.java:42)
	at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:495)
	at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchange(DefaultRestClient.java:465)
	at org.springframework.cloud.gateway.server.mvc.handler.RestClientProxyExchange.exchange(RestClientProxyExchange.java:42)
	at org.springframework.cloud.gateway.server.mvc.handler.ProxyExchangeHandlerFunction.handle(ProxyExchangeHandlerFunction.java:120)
	at org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions$LookupProxyExchangeHandlerFunction.handle(HandlerFunctions.java:107)
	at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$ofRequestProcessor$3(HandlerFilterFunction.java:83)
	at org.springframework.web.servlet.function.HandlerFilterFunction.lambda$apply$2(HandlerFilterFunction.java:70)
	at org.springframework.web.servlet.function.support.HandlerFunctionAdapter.handle(HandlerFunctionAdapter.java:108)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:936)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:596)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
...

I would expect the PUT and DELETE methods to behave in the same fashion. That is, that they would return 404 errors.

@predhme
Copy link
Author

predhme commented Sep 12, 2024

I am fairly confident that this issue is caused by: spring-projects/spring-framework#33020

That is slated to be fixed in 6.2.0 of spring. Once the Cloud packages pick up that new version, this issue should be resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant