0

I am using NiFi's InvokeHTTP processor to POST to a SalesForce endpoint, particularly to the Login endpoint:

https://test.salesforce.com/services/oauth2/token

I append the client_id, client_secret, username and password field to the URL:

https://test.salesforce.com/services/oauth2/token?grant_type=password&client_id=<client_id>&client_secret=<client_secret>&username=<username>&password=<password + key>

And in addition there's a JSON message / payload that passes through InvokeHTTP processor so I configure

Content-Type: application/json

And this works fine when I run it.

[Note: Those who don't know Apache NiFi but knows HttpClient in Java and/or SFDC can answer the question, my point is the REST API endpoint works for me when on NiFi, but not when I try to reach the REST API using custom Java code]

Now because I want to convert this mechanism to a custom code in ExecuteScript processor, I tried coding in Java using HttpClient library. But it seems there are multiple ways of doing this, based on this post in Baeldung. I tried item #4 first:

CloseableHttpClient client = HttpClients.createDefault();

String urlStr = "https://test.salesforce.com/services/oauth2/token?grant_type=password&client_id=<client_id>&client_secret=<client_secret>&username=<username>&password=<password + key>";
HttpPost httpPost = new HttpPost(urlStr);

String jsonPayload = "{\"qty\":100,\"name\":\"iPad 4\"}";
StringEntity entity = new StringEntity(jsonPayload);
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");

CloseableHttpResponse response = client.execute(httpPost);

System.out.println(response.getStatusLine().getStatusCode());

InputStream is = response.getEntity().getContent();
String responseStr = IOUtils.toString(is, "UTF-8");

System.out.println(responseStr);

client.close();

In which I get:

400
{"error":"invalid_grant","error_description":"authentication failure"}

I also tried item #2 pattern in the page, without the JSON payload, as the parameters would be my entity now:

CloseableHttpClient client = HttpClients.createDefault();

String urlStr = "https://test.salesforce.com/services/oauth2/token";

HttpPost httpPost = new HttpPost(urlStr);

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("grant_type", "password"));
params.add(new BasicNameValuePair("client_id", CLIENT_ID));
params.add(new BasicNameValuePair("client_secret", CLIENT_SECRET));
params.add(new BasicNameValuePair("username", USERNAME));
params.add(new BasicNameValuePair("password", PASSWORD));

httpPost.setEntity(new UrlEncodedFormEntity(params));

CloseableHttpResponse response = client.execute(httpPost);
System.out.println(response.getStatusLine().getStatusCode());

InputStream is = response.getEntity().getContent();
String responseStr = IOUtils.toString(is, "UTF-8");

System.out.println(responseStr);

client.close();

In which case, I also get the same response. Am I missing something in my Java code? How do I combine both patterns, with params and jsonPayload as entity?

oikonomiyaki
  • 7,691
  • 15
  • 62
  • 101

1 Answers1

0

Here is my experience with HTTPClient, for Bing search API

      URIBuilder builder = new URIBuilder("https://api.cognitive.microsoft.com/bing/v5.0/search");

        builder.setParameter("q", line);
        builder.setParameter("count", "10");
        builder.setParameter("offset", "0");
        builder.setParameter("mkt", "en-us");
        builder.setParameter("safesearch", "Moderate");

        URI uri = builder.build();
        HttpGet request = new HttpGet(uri);

        request.setHeader(api key);
        HttpClient httpclient = HttpClients.createDefault();
        HttpResponse response = httpclient.execute(request);
        HttpEntity entity = response.getEntity();

Later on, you need to read entity and manipulate it as you wish.

lonesome
  • 2,503
  • 6
  • 35
  • 61