Cannot call Bitcoin RPC from Jersey HttpClient - java

im using dropwizard. From a resource i try to use bitcoin rpc via Jersey HttpClient.
using curl works like a charm:
$ curl --user user:password -X POST -d '{"jsonrpc": "1.0", "id":"curltest", "method": "getinfo", "params":
[] }' -H 'content-type: text/plain;' http://domain.name:18332/
But somehow using Jersey HTTP client from a resource doesnt work:
//init in run methode
final Client client = new JerseyClientBuilder(e).using(c.getJerseyClientConfiguration()).build(getName());
HTTPBasicAuthFilter httpBasicAuth = new HTTPBasicAuthFilter("user", "password");
client.addFilter(httpBasicAuth);
//From the resource
WebResource webRes = client.resource("http://domain.name:18332/");
webRes.header("content-type", "text/plain");
RPC_REQUEST rpc = new RPC_REQUEST("1.0", "curltest", "getinfo", new ArrayList<String>());
String response = webRes.post(String.class, JSONParserHelper.parseJSONToString(rpc));
JSONParserHelper.parseJSONToString(rpc) returns following string:
{"jsonrpc":"1.0","id":"curltest","method":"getinfo","params":[]}
Following error is caused in row "webRes.post":
! com.sun.jersey.api.client.UniformInterfaceException: Client response status: 500
EDIT: Using a wrong pw causes a 401. I guess the connection should be correct and the issue is somewhere else.
EDIT: Used -d instead of --data-binary
EDIT: As soon as Im home Ill dump the whole request from jersey http client.
Thank you

Bitcoin RPC does not support chunked encoding requests.
Since there was a bug in dropbox jersey libs till 0.8 you cannot disable it.
Since 0.8 you can disable it in the configuration file.
I had to migrate from 0.7 to 0.8 and add this in my configuration file.
httpClient:
...
chunkedEncodingEnabled: false
By the way a good migration overview: https://groups.google.com/forum/#!topic/dropwizard-dev/VInOW_ebiAc

Related

HttpResponseException: Bad Request occurs while implementing call inbound using vonage SDK

I am trying to implement call functionality using nexmo api in my spring MVC project, but I keep on getting the below exception
com.vonage.client.VonageResponseParseException: Unable to parse response.
at com.vonage.client.AbstractMethod.execute(AbstractMethod.java:105) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.voice.CallsEndpoint.post(CallsEndpoint.java:57) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.voice.VoiceClient.createCall(VoiceClient.java:61) ~[client-6.1.0.jar:6.1.0]
.............................
Caused by: org.apache.http.client.HttpResponseException: Bad Request
at org.apache.http.impl.client.AbstractResponseHandler.handleResponse(AbstractResponseHandler.java:69) ~[httpclient-4.5.1.jar:4.5.1]
at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:65) ~[httpclient-4.5.1.jar:4.5.1]
at com.vonage.client.voice.CreateCallMethod.parseResponse(CreateCallMethod.java:57) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.voice.CreateCallMethod.parseResponse(CreateCallMethod.java:32) ~[client-6.1.0.jar:6.1.0]
at com.vonage.client.AbstractMethod.execute(AbstractMethod.java:102) ~[client-6.1.0.jar:6.1.0]
... 51 more
Below is my code logic
VonageClient client = VonageClient.builder().applicationId(APPLICATION_ID).privateKeyContents(PRIVATE_KEY).build();
Ncco ncco = new Ncco(TalkAction.builder("message").build());
Call call = new Call(TO_NUMBER, FROM_NUMBER, ncco);
CallEvent result = client.getVoiceClient().createCall(call);
Although inbound calls work using curl command below
curl -X POST https://api.nexmo.com/v1/calls\
-H "Authorization: Bearer "$JWT\
-H "Content-Type: application/json"\
-d '{"to":[{"type": "phone","number": "TO_NUMBER"}],
"from": {"type": "phone","number": "FROM_NUMBER"},
"ncco": [
{
"action": "talk",
"text": "This is a text to speech call from Vonage"
}
]}'
The code provided here appears to work fine on the 5.6.0 version of the nexmo client - I would make sure you're all the way up to date.
That error is suggesting that the content being passed to the nexmo API is bad so it's probably worth turning on some logging if this continues to be a problem after upgrading here's an example of how to turn on logging. this will allow you to see exactly what it's passing along and perhaps find out what the issue is.

How to send HTTP request from Java

i'm creating java module to parse JSON file.
To receive file i need to send HTTP request. When I use curl my request looks like this:
curl -X GET "https://***" -H "accept: application/json" -H "apikey: ***"
How can I send the equivalent HTTP request from Java
Java has a lot of options to work with HTTP.
Option 1
Since Java 9, there is a built-in HTTP client. So You can use it to create a request without any third-party libraries.
A simple example is something like this:
HttpRequest request2 = HttpRequest.newBuilder()
.uri(new URI("some url"))
.header("someHeader", "value1")
.header("anotherHeader", "value2")
.GET()
.build();
For more examples see here
Option 2
Use third party libraries, there are many: OkHttpClient, More "old-school" Apache Http Client (HttpComponents
Option 3
If you're using spring, you might consider using Spring's WebClient. There are also wrappers in spring like RestTemplate that can come handy, but it really depends on what would you like to work with.
Many clients are coming with http connection pools that should be properly set up.
In addition, in your example, I see that you work with https - all these clients support it but it should be properly set up.
If you are using Spring then try WebClient - it is a bit harder to understand in the begging (at least harder than RestTemplate) but it pays of since RestTemplate will be discontinued.
You can find an example here
https://www.baeldung.com/spring-webclient-resttemplate
#GetMapping(value = "/tweets-non-blocking",
produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Tweet> getTweetsNonBlocking() {
log.info("Starting NON-BLOCKING Controller!");
Flux<Tweet> tweetFlux = WebClient.create()
.get()
.uri(getSlowServiceUri())
.retrieve()
.bodyToFlux(Tweet.class);
tweetFlux.subscribe(tweet -> log.info(tweet.toString()));
log.info("Exiting NON-BLOCKING Controller!");
return tweetFlux;
}
Just be aware that this is non-blocking (e.g. asynchronous) solution so you won't get the response right away, but you subscribe to the request and then process the response when it is available. There are also blocking options in WebClient
Java has its own classes that allow you to send HTTP request. See class HttpURLConnection. However, I recommend using 3d party libraries that significantly simplify this task. Good libraries would be Apache Http client or OK Http client. I also can offer you to use another Open source library that has an HTTP client as well. It is called MgntUtils library and it is written by me. In this case your code would look something like this:
HttpClient workingClient = new HttpClient();
workingClient.setRequestProperty("accept", "application/json;charset=UTF-8");
workingClient.setRequestProperty("apikey", "***");
workingClient.setConnectionUrl("https://***");
ByteBuffer buffer =
workingClient.sendHttpRequestForBinaryResponse(HttpMethod.GET);
//or of your API returns contents of file as a string
String jsonStr = workingClient.sendHttpRequest(HttpMethod.GET);
After that, your ByteBuffer buffer or String jsonStr will hold the content of your JSON file. And now you can do whatever you need with it. Here is Javadoc for HttpClient class. The MgntUtils library can be obtained as maven artifacts here or on Github (including source code and Javadoc)

Using Vert.x Web Client to send GET requests properly with headers

I have an internal endpoint that I am trying to send GET requests to with Vert.x Web Client with Java. So far, I am unable to successfully get any data back.
If I cURL the endpoint, it works just fine (these are internal endpoints). The service I am trying to send GET requests to requires a few headers , and data as well:
curl -H "Accept:application/json" -H "Content-Type:application/json" -H "alpha:192.168.10.20" -d '{"mutate":"*"}' http://my-endpoint.com/api/get-items
But if I try to use this in one of my router endpoints in Vert.x, I get an error:
WebClient webClient = WebClient.create(vertx);
webClient.get("http://my-endpoint.com/api/get-items")
.putHeader("Accept", "application/json")
.putHeader("Content-Type", "application/json")
.putHeader("alpha", "192.168.10.20")
.sendJsonObject(new JsonObject().put("mutate", "*"), ar -> {
if (ar.succeeded()) {
System.out.println("##### WEBCLIENT #####");
System.out.println(ar);
} else {
System.out.println("CAUSE: " + ar.cause().getMessage());
}
});
The error message I get from the else statement is:
CAUSE: Connection refused: localhost/127.0.0.1:80
What am I doing wrong? I've been using this for reference: Vert.x Web Client
===========================================
SOLUTION
===========================================
I had to change
webClient.get("http://my-endpoint.com/api/get-items")
to
webClient.post(80, "my-endpoint.com", "/api/get-items")
Also had to add .as(BodyCodec.jsonArray()) underneath the above line because the result I was getting was a Json Array.
You need to change
webClient.get("http://my-endpoint.com/api/get-items")
to
webClient.get(80, "my-endpoint.com", "/api/get-items")

Watson Natural Language Understanding Java 401-not authorized

I'm trying to connect my Java application to the Watson NLU service. For a start, I tried to follow the tutorial from Bluemix. I created a service on Bluemix and imported the watson Java SDK. Using this tutorial code, I keep receiving 401 - not authorized responses. (Of course i changed username and password for the service).
I guess there's something missing, but i can't figure out what.
NaturalLanguageUnderstanding service = new NaturalLanguageUnderstanding(
NaturalLanguageUnderstanding.VERSION_DATE_2017_02_27,
"{username}",
"{password}"
);
String text = "IBM is an American multinational technology " +
"company headquartered in Armonk, New York, " +
"United States, with operations in over 170 countries.";
EntitiesOptions entitiesOptions = new EntitiesOptions.Builder()
.emotion(true)
.sentiment(true)
.limit(2)
.build();
KeywordsOptions keywordsOptions = new KeywordsOptions.Builder()
.emotion(true)
.sentiment(true)
.limit(2)
.build();
Features features = new Features.Builder()
.entities(entitiesOptions)
.keywords(keywordsOptions)
.build();
AnalyzeOptions parameters = new AnalyzeOptions.Builder()
.text(text)
.features(features)
.build();
AnalysisResults response = service
.analyze(parameters)
.execute();
System.out.println(response);
i had the same problems in node.js and solved it by adding the correct url of the api gateway to the NaturalLanguageUnderstanding service = new NaturalLanguageUnderstanding() object.
please keep in mind, that this depends on your region ..
regards
Leo
A 401 Unauthorized would suggest that there's an issue with the credentials that you're using to access the service. To rule this out, take a start by using the cURL tutorial from that same page:
curl -X POST \
-H "Content-Type: application/json" \
-u "{username}":"{password}" \
-d #parameters.json "https://gateway.watsonplatform.net/natural-language-understanding/api/v1/analyze?version=2017-02-27"
If, with that same username and password, you still receive a 401 Unauthorized error, then there's likely an issue with that username/password combination. Delete the tile in Bluemix and create a new one to get a new username/password, and give that a try.
If that does work fine, then there's an issue with how the username/password is being inserted into the code. Verify that you've replaced {username} and {password}, the final version should not have any curly brackets in it.

CURL in JAVA - Could not resolve host : POST

I have been successfully able to perform CURL commands from the CMD in my Windows PC by installing curl for Windows. Similarly, I have been able to get them working in my JAVA application by using ProcessBuilder and Process to create Operating System process. In particular, I need to execute the REST API end point commands used in KissFlow given here: https://support.kissflow.com/support/solutions/articles/179582-understanding-the-rest-api-end-points
Question: I have been able to able to execute the commands with the GET method like so.
ProcessBuilder pb = new ProcessBuilder("curl","-H","api_key:<XXXX>","-X","GET","http://<XXXX>.appspot.com/api/1/Employee/list/p1/50
However, when using the commands with POST like
ProcessBuilder pb = new ProcessBuilder("curl","-H","api_key:<XXXX>","-X ","POST","--data-urlencode","First Name=XXXX","http://<XXXX>.appspot.com/api/1/Employee/submit");, I get an error:
curl: (6) Could not resolve host: POST
with the input stream of the process returning
<html><title>Error 400 (Bad Request)!!1</title></html>
This in fact works perfectly when executed from CMD.
I have tried suggestions of all related questions here. Any help is appreciated. Thanks.
EDIT: Any alternate method from CURL to do the same will be acceptable as well.
According #GyroGearless's idea, try to use the sample code below to retrieve responses from URLs through methods GET and POST using Apache's HttpClient class. I think that with HttpClient you'll have much more "power" than with CURL.
You'll need commons-httpclient.jar and its dependencies: commons-codec and commons-logging. You'll find these jars at http://commons.apache.org/downloads/
(...)
String url = "http://<XXXX>.appspot.com/api/1/Employee/list/p1/50";
HttpClient client = new HttpClient();
GetMethod get = new GetMethod(url);
client.executeMethod(get);
System.out.println(new String(get.getResponseBody()));
get.releaseConnection();
url = "http://<XXXX>.appspot.com/api/1/Employee/submit";
PostMethod post = new PostMethod(url);
post.addParameter("id", "10");
client.executeMethod(post);
System.out.println(new String(post.getResponseBody()));
post.releaseConnection();
(...)
As you can see, in the PostMethod part we're sending parameters within request. Maybe you don't need this....
You can also use Visual studio, we also created a post method where we reject requests in kissflow. Just letting you know that you can also do that in visual studio.

Categories

Resources