javasplunkjava-http-client

Java 11 HttpClient - POST issue


I am writing java HttpClient code, to query splunk API, and get search id (sid) as output. I was able to write this in curl and python, with no issues. But Java is proving to be difficult.

Curl: (Working. Got the sid as output)

curl -u user https://url:8089/services/search/jobs -d"search=|tstats count where index=main"

**output:**
<response>
  <sid>1352061658.136</sid>
</response>

Python: (Working. Got sid as output)

import json
import requests


baseurl = 'https://url:8089/services/search/jobs'
username = 'my_username'
password = 'my_password'

payload = {
   "search": "|tstats count where index=main",
   "count": 0,
   "output_mode": "json" 
}
headers={"Content-Type": "application/x-www-form-urlencoded"}


response = requests.post(url, auth=(userid,password), data=payload, headers=headers, verify=False)

print(response.status_code)
print(response.text)

Java: (Not working. No matter what request payload, we POST, getting list of all SPlunk jobs, instead of sid, like what we see in curl or python)

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class HttpClientPostJSON {

    private static final HttpClient httpClient = HttpClient.newBuilder()
            .authenticator(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(
                            "user",
                            "password".toCharArray());
                }

            })              
            .build();

    public static void main(String[] args) throws IOException, InterruptedException {

        // json formatted data
        String json = new StringBuilder()
                .append("{")
                .append("\"search\":\"|tstats count where index=main\"")                          
                .append("}").toString();

        // add json header
        HttpRequest request = HttpRequest.newBuilder()
                .POST(HttpRequest.BodyPublishers.ofString(json))
                .header("Content-Type", "application/x-www-form-urlencoded") 
                .uri(URI.create("https://url:8089/services/search/jobs"))          
                
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        // print status code
        System.out.println(response.statusCode());

        // print response body
        System.out.println(response.body());

    }

}

What is the issue with java code? is there a better way to pass payload? Why am i not gettting splunk search id (sid) as output. I see some 20MB+ output that is listing all the jobs in the splunk.


Solution

  • Your payload is JSON text, but the mime-type indicates it would consist of urlencoded key-value pairs. The python code results in a x-www-form-urlencoded body:

    search=%7Ctstats+count+where+index%3Dmain&count=0&output_mode=json
    

    If you assign this value to the json-String (rename it, please) in the main-method like

    String json = "search=%7Ctstats+count+where+index%3Dmain&count=0&output_mode=json";
    

    the payload matches the mime-type.