How to issue a POST request with a JSON body in a HystrixCommand object's run block?

1090 views
Skip to first unread message

Hongyi Li

unread,
Jul 28, 2014, 1:04:41 PM7/28/14
to hystr...@googlegroups.com
Hi guys,

I've been stuck on how to issue a post request with a json entity body in a HystrixCommand object's run block. I was able to make get & post requests without an entity body easily, but when i tried to include an entity body, i just kept getting errors.

In my run() block,
RestClient client = (RestClient) ClientFactory.getNamedClient(RSSConstants.MIDDLETIER_REST_CLIENT);
HttpClientRequest request = HttpClientRequest.newBuilder()
                       
.setVerb(this.restAction)
                       
.setUri(new URI("/"
                               
+ RSSConstants.MIDDLETIER_WEB_RESOURCE_ROOT_PATH
                               
+ this.resourcePath)
                       
)
                       
.setHeaders(headers)
                       
.setEntity(<JSON String>)
                       
.build();

HttpClientResponse response = client.executeWithLoadBalancer(request);
return IOUtils.toString(response.getRawEntity(), Charsets.UTF_8);

Where the <JSON String> is in the above code, I have tried to use simple strings, JSONObject (org.json), StringEntity, etc, but they all gave various errors such as no message body writer for this mime type, classcastexception for jboss etc.

Can someone help me with how to issue a request with a request body using Hystrix? I've been trying to debug this for a whole week and I would really really appreciate any help.

Thanks!!












Ben Christensen

unread,
Jul 28, 2014, 3:08:14 PM7/28/14
to hystr...@googlegroups.com
It sounds like your issue is that your code is expecting certain ThreadLocal state, but the run() method is executed on a different thread without that ThreadLocal state.

You will need to implement a ConcurrencyStrategy (https://github.com/Netflix/Hystrix/wiki/Plugins#concurrency-strategy) to copy state from the JBoss thread to the Hystrix thread if you're doing anything that relies on ThreadLocal (generally not a pleasant programming model).

Hongyi Li

unread,
Jul 28, 2014, 3:39:35 PM7/28/14
to Ben Christensen, hystr...@googlegroups.com

Thanks for the speedy reply Ben!

I don't think my code did anything with threads. I simply modified the sample recipes-rss app from netflixOSS to try to issue a post request that has a request body eg json (the example only had query params but no body). Is there a simple way to do that, say using httpclientrequest.newbuilder.setentity(xyz) to do that?

Thanks!

On Jul 28, 2014 12:08 PM, "Ben Christensen" <benjchr...@gmail.com> wrote:
It sounds like your issue is that your code is expecting certain ThreadLocal state, but the run() method is executed on a different thread without that ThreadLocal state.

You will need to implement a ConcurrencyStrategy (https://github.com/Netflix/Hystrix/wiki/Plugins#concurrency-strategy) to copy state from the JBoss thread to the Hystrix thread if you're doing anything that relies on ThreadLocal (generally not a pleasant programming model).

--
You received this message because you are subscribed to a topic in the Google Groups "HystrixOSS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/hystrixoss/k-bmcSLAoTs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to hystrixoss+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ben Christensen

unread,
Jul 28, 2014, 3:42:37 PM7/28/14
to Hongyi Li, Ben Christensen, hystr...@googlegroups.com
You may not be using threads, but JBoss and Hystrix certainly do.

Please provide code examples that involve Hystrix and actual stack traces. As for “httpclientrequest.newbuild.setentity” … I have no idea, I never use that library so can’t comment.

-- 
Ben Christensen - Netflix Edge Engineering
+1.310.782.5511  @benjchristensen
You received this message because you are subscribed to the Google Groups "HystrixOSS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hystrixoss+...@googlegroups.com.
Message has been deleted

Hongyi Li

unread,
Jul 28, 2014, 5:46:45 PM7/28/14
to hystr...@googlegroups.com, harryl...@gmail.com, benjchr...@gmail.com
Hi Ben,

The relevant code for my HystrixCommand class is here: http://pastebin.com/xxYSDkLA

When I run this using StringEntity (quoted) or JSONObject (similar), i get the following stacktrace complaining that the relevant MessageBodyWriter was not found:

ERROR 14:41:38,452 Error executing HystrixCommand
java
.lang.RuntimeException: Exception
    at com
.netflix.recipes.rss.hystrix.UserActionsCommand.run(UserActionsCommand.java:143)
    at com
.netflix.recipes.rss.hystrix.UserActionsCommand.run(UserActionsCommand.java:50)
    at com
.netflix.hystrix.HystrixCommand.executeCommand(HystrixCommand.java:764)
    at com
.netflix.hystrix.HystrixCommand.access$1400(HystrixCommand.java:81)
    at com
.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:706)
    at com
.netflix.hystrix.strategy.concurrency.HystrixContextCallable.call(HystrixContextCallable.java:45)
    at java
.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java
.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java
.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java
.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java
.lang.Thread.run(Thread.java:695)
Caused by: com.netflix.client.ClientException: Unable to execute RestClient request for URI:http://harry.li-ltm:9191/middletier/users
    at com
.netflix.client.AbstractLoadBalancerAwareClient.generateNIWSException(AbstractLoadBalancerAwareClient.java:256)
    at com
.netflix.client.AbstractLoadBalancerAwareClient.executeOnSingleServer(AbstractLoadBalancerAwareClient.java:203)
    at com
.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:402)
    at com
.netflix.recipes.rss.hystrix.UserActionsCommand.run(UserActionsCommand.java:139)
   
... 10 more
Caused by: com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java class org.apache.http.entity.StringEntity, and Java type class org.apache.http.entity.StringEntity, and MIME media type text/html was not found
    at com
.sun.jersey.api.client.RequestWriter$RequestEntityWriterImpl.<init>(RequestWriter.java:199)
    at com
.sun.jersey.api.client.RequestWriter.getRequestEntityWriter(RequestWriter.java:248)
    at com
.sun.jersey.client.apache4.ApacheHttpClient4Handler.getHttpEntity(ApacheHttpClient4Handler.java:241)
    at com
.sun.jersey.client.apache4.ApacheHttpClient4Handler.getUriHttpRequest(ApacheHttpClient4Handler.java:197)
    at com
.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:153)
    at com
.sun.jersey.api.client.Client.handle(Client.java:648)
    at com
.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
    at com
.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com
.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:568)
    at com
.netflix.niws.client.http.RestClient.execute(RestClient.java:501)
    at com
.netflix.niws.client.http.RestClient.execute(RestClient.java:418)
    at com
.netflix.niws.client.http.RestClient.execute(RestClient.java:78)
    at com
.netflix.client.AbstractLoadBalancerAwareClient.executeOnSingleServer(AbstractLoadBalancerAwareClient.java:192)
   
... 12 more


 

However, when instead of using StringEntity or JSONObject (org.json) as in the above code, I use java String in HttpClient.builder().setEntity("{hey: 'yo'}") method, the edge-tier (that sent the request) is fine but it is the middle-tier's turn to give errors, like this:
 WARN 11:58:58,168 EXCEPTION, please implement com.netflix.recipes.rss.netty.NettyHandlerContainer.exceptionCaught() for proper handling.
java
.lang.ClassCastException: org.jboss.netty.handler.codec.http.HttpChunk$1 cannot be cast to org.jboss.netty.handler.codec.http.HttpRequest
    at com
.netflix.recipes.rss.netty.NettyHandlerContainer.messageReceived(NettyHandlerContainer.java:96)
    at org
.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
    at org
.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459)
    at org
.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536)
    at org
.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:435)
    at org
.jboss.netty.handler.execution.ChannelUpstreamEventRunnable.doRun(ChannelUpstreamEventRunnable.java:43)
    at org
.jboss.netty.handler.execution.ChannelEventRunnable.run(ChannelEventRunnable.java:67)
    at java
.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java
.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java
.lang.Thread.run(Thread.java:695)

My middle-tier's method that got called is a simple jersey method: http://pastebin.com/2E1VJEPU


So can you tell me a simple way where I can make a Http request using HystrixCommand? I really don't have to follow the above code's structure at all. All I need to do is to send a json or text string via a POST request, but i'm unable to do so.

Thanks a lot! :)

Ben Christensen

unread,
Jul 30, 2014, 4:44:01 PM7/30/14
to hystr...@googlegroups.com, Hongyi Li, harryl...@gmail.com
I have no idea what those Jersey errors are about. Here are various simpler examples of HystrixCommand implementations: https://github.com/benjchristensen/ReactiveLab/tree/master/reactive-lab-edge/src/main/java/io/reactivex/lab/edge/clients


-- 
Ben Christensen
+1.310.782.5511  @benjchristensen

Hongyi Li

unread,
Jul 30, 2014, 6:29:16 PM7/30/14
to Ben Christensen, hystr...@googlegroups.com

This is exactly what I was looking for!! Thanks!! I wish I knew of this repo earlier, could've saved me days and days haha.

qi.z...@gmail.com

unread,
Sep 27, 2017, 11:31:57 PM9/27/17
to HystrixOSS
Hi Li,
     The url could not open. Could u please give me some advise to solve the problem that send Json by httprequest?

在 2014年7月31日星期四 UTC+8上午6:29:16,Hongyi Li写道:
Reply all
Reply to author
Forward
0 new messages