Spring-cloud-netflix: Sidecar - POST not forwarding request body

Created on 17 Feb 2017  路  28Comments  路  Source: spring-cloud/spring-cloud-netflix

I have a remote Python service exposing two endpoints (one GET and one POST). Sidecar is installed on the host and registering itself with Eureka so this service is available to others.

I also have a Java Spring boot client running Feign which looks up services using serviceId.

@FeignClient("PythonSidecar")
public interface Client {

    @RequestMapping(value = "/test", method = RequestMethod.POST, produces =MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    public String testPost(@RequestBody(required = true) String testString);
}

When I invoke the python based service (via sidecar) GET requests work as expected. However, POST requests do not; they hit the endpoint but the request body is missing the data.

We are running Spring Cloud CAMDEN SR4.

We were running Spring Cloud ANGEL SR4 and this was working correctly. The upgrade broke it.

Thanks

bug

Most helpful comment

@reidadam yes I did, I was busy last week with some other work, I will try to look at the sample soon

All 28 comments

Would it be possible to provide a sample that reproduces this?

@spencergibb Please, there is no reason to close this issue. Can we please have it re-opened.

@ryanjbaxter I have provided a sample that can reproduces this issue at: https://github.com/ImranAdan/PythonSidecar

Pick one, SO or this issue.

This issue. I have provided a sample application that should make it possible to reproduce it.

You don't own the SO issue to close/delete it.

I've removed the SO issue. Please continue on this forum with this issue.

Quick question, did you happen to try Brixton.SR7?

@reidadam I am not a Python expert so excuse me if I am making a dumb mistake here...
I ran pip install flask and then ran python app.py but I get

Traceback (most recent call last):
  File "app.py", line 1, in <module>
    from flask import Flask, render_template, request, url_for
ImportError: No module named flask

@ryanjbaxter that looks like either Flask didn't get properly installed (did the pip install flask command succeed?) or you have more than one instance of the python interpreter (for instance if you are running stuff in a virtual machine) and it got installed in the wrong one.

If the pip install command ran properly, you should be able to fire up the python interpreter from the terminal (just type python) and then run import flask without getting any errors.

It installed correctly from what I can see. Looks like it got installed to /usr/local/lib/python2.7/site-packages/flask, python is installed in /usr/local/Cellar/python/2.7.13/bin/python.

That is probably a python path issue. You seem to have installed python form homebrew, but OSX needs its own python for functioning normally. Sometimes system upgrades force default python interpreter to be the system one. If when you run from the terminal which python you get /usr/bin/python instead of usr/local/bin/python (or similar, something inside /usr/local then this is definitely your issue.

In any case, if Flask is installed properly you should have a flask command line tool which you can use to run your app like this (from the folder where app.py lives):
export FLASK_APP=app.py; flask run
This should use the same python interpreter that flask got installed with.

For the sake of completeness, it might also be a permissions issue with the python packages. This happens if you ever do sudo pip install ..., the installed modules get root ownership and cannot be loaded by regular users. If that is the case then try

sudo pip uninstall flask
pip install flask

to get it installed in an accessible way.

@jlopezpena thanks for the hints, I now have the app running!

Looks like setting the correct Content-Type header fixes the problem.

    @RequestMapping(value = "/testPost", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded")
    public String testPost(@RequestBody(required = true) String test);

@ryanjbaxter Thanks for this, I will add this to our services and see if that resolves that issue.

@ryanjbaxter I've tested this change in my own project. I can see the content-type header has changed from application/json to application/x-www-form-urlencoded but I still don't get any request body data

The only thing I changed in your git repo, is move from Camden.SR2 to Camden.SR5 and make the change above to the @RequestMapping annotation in PythonFeignClient.

This solution does work but unfortunately the sample app does not represent the problem exactly.

This solution works only when Feign client uses a url to point the Python service directly (port 8000 in this case). Its is not using the Spring Side Car to proxy the requests.

//works!
@FeignClient(url = "http://localhost:8000", name = "PythonSidecar" )
public interface PythonFeignClient {

    @RequestMapping(value = "/testPost", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded")
    public String testPost(@RequestBody(required = true) String test);

}

However, if you incorporate a Eureka Server and lookup the service by Id, then the problem occurs.

//does not work!
@FeignClient(name = "PythonSidecar" )
public interface PythonFeignClient {

        @RequestMapping(value = "/testPost", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded")
    public String testPost(@RequestBody(required = true) String test);

}

Let me know if you'd like me to post a complete set of projects to demonstrate this. Thx.

Yes a sample with all the projects that reproduce the problem would be welcome.

@ryanjbaxter Thanks, I have provided a sample with all the projects required to reproduce the issue. The sample can be found at: https://github.com/ImranAdan/SidecarIssue

Please let me know if there is anything which is not clear and we can work on resolving it

@ryanjbaxter Did you see @ImranAdan's sample project and did you manage to reproduce the error? Thanks.

@reidadam yes I did, I was busy last week with some other work, I will try to look at the sample soon

The difference is that the content-length header is not being sent when using the service id. Apparently Flask does not like that. I need to look into why we are removing the content-length header.

Applied to 1.2.x via bd3391ae55a3c63dbd19a1b7ef4f2bfd5765ea34

@reidadam if you move the TestHarness project in the sample to Camden.BUILD-SNAPSHOT or Dalston.BUILD-SNAPSHOT you should be able to pick up the fix @spencergibb made. It is working for me.

That works. Thanks for your help!

What are the timelines for 1.2.6.RELEASE release?

I am hoping this week. Glad it worked!

Was this page helpful?
0 / 5 - 0 ratings