Getting Unirest Config exception when I use java with Unirest API to call the web service asynchronous way. It is working as expected in the sync method.
I am writing a Java code for Apache Spark to call REST API.
Future> future = ui.post("http://x.x.x.x:x/xwa/evalrules").body(Str).asStringAsync(
new Callback() {
public void failed(UnirestException e) {
System.out.println("JTX Failed Get message"+ e.getMessage());
}
public void completed(HttpResponse<String> resp) {
System.out.println(new Date() + " Consumer JTXX recvd response -> " + resp.getStatus() + "/" + resp.getBody());
//out_JSON=resp.body();
}
public void cancelled() {
System.out.println("The request has been cancelled JTX");
}
});
Expected: It is working as expected for first few calls. post that it is failing. I suspected the timeout so i have already disabled using approach.
Config c = Unirest.config().socketTimeout(0).connectTimeout(0).concurrency(10, 8);
UnirestInstance ui = new UnirestInstance(c);
Error Message:
kong.unirest.UnirestConfigException: Http Clients are already built in order to build a new config execute Unirest.config().reset() before changing settings.
This should be done rarely.
Any suggestions on how to resolve this will be highly appreciated. Thanks.
Muthu
Related
I'm currently trying to find a way to deal with unexpected HBase failures in my application. More specifically, what I'm trying to solve is a case where my application inserts data to HBase and then HBase fails and restarts.
In order to check how my application reacts to that scenario I wrote an application that uses HBase Async client by doing a tight loop and saving the results in HBase. When I start the application I can see rows are saved into the table, if during this time I intentionally fail my HBase server and restart it the client seems to reconnect but new insertions are not saved into the table
The code looks like this:
HConnection connection = HConnectionManager.createConnection();
HBaseClient hbaseClient = new HBaseClient(connection);
IntStream.range(0, 10000)
.forEach(new IntConsumer() {
#Override
public void accept(int value) {
try {
System.out.println("in value: " + value);
Thread.sleep(2000);
Get get = new Get(Bytes.toBytes("key"));
hbaseClient.get(TableName.valueOf("testTable"), get, new ResponseHandler<Result>() {
#Override
public void onSuccess(Result response) {
System.out.println("SUCCESS");
}
#Override
public void onFailure(IOException e) {
System.out.println("FAILURE");
}
});
urlsClient.save("valuekey", "w" + value, new FailureHandler<IOException>() {
#Override
public void onFailure(IOException failure) {
System.out.println("FAILURE");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
This is obviously just a simple test but what I'm trying to achieve is that the async client will successfully save new rows after I restarted my HBase server. What the asynchronous HBase clients prints to me if I actually print the stacktrace in the "onFailure" method is:
org.apache.hadoop.hbase.ipc.RpcClient$CallTimeoutException: Call id=303, waitTime=60096, rpcTimeout=60000
at org.apache.hadoop.hbase.ipc.AsyncRpcChannel.cleanupCalls(AsyncRpcChannel.java:612)
at org.apache.hadoop.hbase.ipc.AsyncRpcChannel$1.run(AsyncRpcChannel.java:119)
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:581)
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:655)
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:367)
at java.lang.Thread.run(Thread.java:745)
And so my questions are:
How should one deal with a situation like I mentioned using the specified async client?
If this async client is no longer relevant could someone suggest a different async client that can perform asynchronous puts? I tried the BufferedMutator but it does not seem to actually flush any contents but just fails with the following java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.hbase.zookeeper.MetaTableLocator (but this gets a little off topic so I wont expand anymore)
Thanks
It's been quite a long time since I asked this question but I ended up using the HBase high availability instead of finding a way to solve it with code
I'm trying to figure out how to integrate an external API and run every integration test against it. I've been reading and looking at:
https://github.com/dropwizard/dropwizard/blob/master/dropwizard-example/src/test/java/com/example/helloworld/IntegrationTest.java
https://github.com/dropwizard/dropwizard/blob/master/docs/source/manual/testing.rst
but it looks like these are examples of testing local endpoints and not external ones. I would like to be able to test my api calls with JUnit tests. Currently I'm having to start up and run my app to make sure they're working.
This is the direction I'm currently exploring:
private Client client;
#Before
public void setUp() throws Exception {
client = ClientBuilder.newClient();
}
#After
public void tearDown() throws Exception {
client.close();
}
#Test
public void testHitApi() throws Exception {
client.target("https://api.github.com/users/" + getUser() + "/repos");
}
Any help would be much appreciated, thanks!
You need to make the api call to hit the endpoint.
doing just :
client.target("https://api.github.com/users/" + getUser() + "/repos")
returns a WebTarget .
you should ideally do something like:
client
.target("https://api.github.com/users/" + getUser() + "/repos")
.request()
.get() ; // for a get call
google for exact post/put/delete calls .
If you mean to run your integration tests against an external api or a separate running instance of your api.
testEnvironment = new Environment("Test environment", Jackson.newObjectMapper(),
null, new MetricRegistry(), null);
ObjectMapper mapper = Jackson.newObjectMapper(new YAMLFactory());
IntegrationTestConfiguration integrationTestConfiguration = mapper.readValue(fixture("integration-testing-config.yml"),
IntegrationTestConfiguration.class);
Instantiate your client as so
exampleClient = new exampleClient(testEnvironment, clientConfiguration);
Hope this helps.
I am using spring-cloud-starter (ie.. spring boot with all the microservices features). When I create hystrix method in a component annotated using the javanica #HystrixCommand, follow the directions on the javanica github site (https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica) to make that method run async, regardless of whether I use their 'Future<>' or Reactive execution 'Observable<>', nothing runs/executes and I get
java.lang.ClassCastException: springbootdemo.EricComponent$1 cannot be cast to springbootdemo.Eric whenever I attempt to pull the result (in the case of Future<>) or get a callback (in case of Reactive Execution .. and println's dont trigger so it really didnt run).
public class Application { ...
}
#RestController
#RequestMapping(value = "/makebunchofcalls/{num}")
class EricController { ..
#RequestMapping(method={RequestMethod.POST})
ArrayList<Eric> doCalls(#PathVariable Integer num) throws IOException {
ArrayList<Eric> ale = new ArrayList<Eric>(num);
for (int i =0; i<num; i++) {
rx.Observable<Eric> oe = this.ericComponent.doRestTemplateCallAsync(i);
oe.subscribe(new Action1<Eric>() {
#Override
public void call(Eric e) { // AT RUNTIME, ClassCastException
ale.add(e);
}
});
}
return ale;
}
#Component
class EricComponent { ...
// async version =========== using reactive execution via rx library from netflix ==============
#HystrixCommand(fallbackMethod = "defaultRestTemplateCallAsync", commandKey = "dogeAsync")
public rx.Observable<Eric> doRestTemplateCallAsync(int callNum) {
return new ObservableResult<Eric>() {
#Override
public Eric invoke() { // NEVER CALLED
try {
ResponseEntity<String> result = restTemplate.getForEntity("http://doges/doges/24232/photos", String.class); // actually make a call
System.out.println("*************** call successfull: " + new Integer(callNum).toString() + " *************");
} catch (Exception ex) {
System.out.println("=============== call " + new Integer(callNum).toString() + " not successfull: " + ex.getMessage() + " =============");
}
return new Eric(new Integer(callNum).toString(), "ok");
}
};
}
public rx.Observable<Eric> defaultRestTemplateCallAsync(int callNum) {
return new ObservableResult<Eric>() {
#Override
public Eric invoke() {
System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum).toString() + "!!!!!!!!!!!!!");
return new Eric(new Integer(callNum).toString(), "bomb");
}
};
}
}
Why would I be getting back an EricComponent$1 instead of a Eric? btw, Eric is just a simple class with 2 strings... its ommitted.
I am figuring that I must have to explicitly execute, but that alludes me because: 1) Doing it with Future<> the queue() method is not available as the documentation claims and 2) doing it with Observable<> there really isn't a way to execute it that I get.
Do you have the #EnableHystrix annotation on you application class?
The subscribe method is asynchronous and you are trying to populate a list in a synchronous controller method so there may be a problem there. Can you change the subscribe to toBlockingObservable().forEach() and see if that helps?
Update #1
I was able to duplicate. Your default method should not return an Observable<Eric>, just an Eric.
public Eric defaultRestTemplateCallAsync(final int callNum) {
System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum) + "!!!!!!!!!!!!!");
return new Eric(new Integer(callNum).toString(), "bomb");
}
Update #2
See my code here https://github.com/spencergibb/communityanswers/tree/so26372319
Update #3
When I commented out the fallbackMethod attribute, it complained that it couldn't find a public version of EricComponent for AOP. I made EricComponent public static and it worked. A top level class in its own file would work to. My code, linked above, works (assuming the restTemplate call works) and returns n OK.
I am new to Atmosphere so I must be missing something simple. I made a sample and can get the #Broadcast to work but not BroadcasterFactory to work. I can trace the onMessage to be hit (via a listener) but I dont see onBroadcast happening unless the #Broadcast is specified. Also, unless I specify the #Broadcast, I dont see the message delivered to the client. My WebSocket code is very basic:
#Path("/chat")
#AtmosphereService(
interceptors = {AtmosphereResourceLifecycleInterceptor.class,
TrackMessageSizeInterceptor.class/*,
BroadcastOnPostAtmosphereInterceptor.class*/}//,
)
public class HelloWorldWS {
#GET
#Produces(MediaType.APPLICATION_JSON)
public SuspendResponse<String> connect(#Context AtmosphereResource res)
{
// eventually this will be done via subscription in the post area
BroadcasterFactory.getDefault().get().addAtmosphereResource(res);
return new SuspendResponse.SuspendResponseBuilder<String>()
//.broadcaster(BroadcasterFactory.getDefault().get())
.outputComments(true)
.addListener(new ResourceListener())
.build();
}
//#Broadcast(writeEntity = false)
#POST
public void broadcast(String message) {
final String msg = String.format("{'author':'fdsa','message':'%s'}", "Override proof");
// Send to all
BroadcasterFactory.getDefault().get().broadcast(msg);
// No Really, send to all
Collection<Broadcaster> broadcasters = BroadcasterFactory.getDefault().lookupAll();
for (Broadcaster b : broadcasters)
{
System.out.println("Broadcaster: " + b.toString() + "; Count: " + b.getAtmosphereResources().size());
for (AtmosphereResource r : b.getAtmosphereResources())
{
System.out.println("Notifying Resource: " + r.toString());
r.write(msg);
}
}
}
}
When I enable the #Broadcast/BroadcastOnPostAtmosphereInterceptor then the message is relayed to the client (my code in the "broadcast" function does nothing then). When I comment out the #Broadcast/BroadcastOnPostAtmosphereInterceptor then I would expect my Broadcast code to deliver the message.
With #Broadcast I show the following ResourceListener callbacks: onPreSuspend, onSuspend, onConnect, onMessage, onBroadcast (client gets it)
When #Broadcast is commented out I show the following ResourceListener callbacks: onPreSuspend, onSuspend, onConnect, onMessage (client never gets message)
What am I doing wrong?
I am using atmosphere 2.1.2 with Jersey 1.17
get rid of AtmosphereResourceLifecycleInterceptor is you use the SuspendResponse API as it may conflict.
I'm trying to use BlazeDS's AMFConnection class to connect to pyamf, but when I call AMFConnection.call(), I get HTTP status 400 (Bad Request - "The request body was unable to be successfully decoded."). I'm more or less following this example: (pyamf.org/wiki/ClientHowTo ... sorry, I'm a new user so I guess I can't use hyperlinks. append a "http://" to those if you want to follow them)
Here's my code:
package amfconnectiontest;
import flex.messaging.io.amf.client.AMFConnection;
import flex.messaging.io.amf.client.exceptions.*;
public class Main {
public static void main(String[] args) {
AMFConnection amfConnection = new AMFConnection();
String url = "http://demo.pyamf.org/gateway/recordset";
String service = "service.getLanguages";
try
{
amfConnection.connect(url);
}
catch (ClientStatusException cse)
{
System.out.println(cse);
return;
}
// Make a remoting call and retrieve the result.
try
{
Object result = amfConnection.call(service);
System.out.println("results: " + result.toString());
}
catch (ClientStatusException cse)
{
System.out.println(cse);
}
catch (ServerStatusException sse)
{
System.out.println(sse);
}
// Close the connection.
amfConnection.close();
}
}
Any ideas?
The ability to en/decode BlazeDS specific messages (implementing ISmallMessage) has landed on the PyAMF trunk (r2726 and up). See the related ticket - http://pyamf.org/ticket/581
This version or one very similar is likely to become 0.5. If you need to connect to a BlazeDS service I would suggest checking out the trunk.