Splunk Dev

Java client using REST API getting 400 error

jantona
Engager

I looked at all the CURL and Python examples of using the REST API. I am able to successfully use the CURL command to get a sessionKey. But when I try to emulate this behavior in Java code, I keep getting error 400 "Login Failed".

Here is my Java code that sets up the HTTP Header

public String postPull(String value) {
        String r = null;
        Set<Integer> valid = new HashSet<>();
        valid.add(200);
        valid.add(201);

        TrustStrategy trustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) {
                return true;
            }
        };

        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).setConnectionRequestTimeout(30*1000).setSocketTimeout(30*1000).build();
        CloseableHttpClient httpClient = null;
        try {
            httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setSSLSocketFactory(new SSLConnectionSocketFactory(
                    new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(),
                    hostnameVerifier)).build();

            HttpPost postRequest = new HttpPost(url);
            postRequest.addHeader("Content-Type", contentType);
            postRequest.addHeader("Accept", accept);
            if (this.authorize) {
                String basicAuth = "Splunk " + this.session;
                postRequest.addHeader("Authorization", basicAuth);
            } else {
                String userCredentials = this.user + ":" + this.token;
                String basicAuth = "Basic " + new String(new Base64().encode(userCredentials.getBytes()));
                postRequest.addHeader("Authorization", basicAuth);
            }

            postRequest.setEntity(new StringEntity(value));
            HttpResponse response = httpClient.execute(postRequest);
            if (!valid.contains(response.getStatusLine().getStatusCode())) {
                throw new RuntimeException(String.format("Failed request = %s, error code = %d : %s", url, response.getStatusLine().getStatusCode(), IOUtils.toString(response.getEntity().getContent(),"UTF-8")));
            }
            r = getStringFromInputStream(response.getEntity().getContent());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                httpClient.close();
            } catch ( Exception ieie) {};
        }
        return r;
    }

and the body that I pass is formatted this way:

public String connect() throws Exception {
        String r = null;
        try {
            HttpInsecureConnector connector = null;
            logger.info("insecure url " + this.surl + "/services/auth/login?output_mode=json");
            connector = new HttpInsecureConnector(this.surl + "/services/auth/login?output_mode=json", 
                        HEADER_CONTENT_TYPE, HEADER_ACCEPT, System.getProperty("splunk.user.name"), this.token);
            StringBuilder mockJson = new StringBuilder();
            mockJson = mockJson.append("{");
                mockJson = mockJson.append("\"username\" : \"" + System.getProperty("splunk.user.name") + "\",");
                mockJson = mockJson.append("\"password\" : \"" + this.token  + "\"");
            mockJson = mockJson.append("}");
            logger.info(mockJson.toString());
//          String pp = "username=" + System.getProperty("splunk.user.name") + "&" + this.token;
            r = connector.postPull(mockJson.toString());
//          r = connector.pull();

        } catch ( Exception e) {
            logger.error(this.surl);
            logger.error(e.getMessage());
            throw e;
        }
        return r;
    }

and this is the output I receive:

12:01:34.502 [main] INFO  metric.Main - Splunk2Wave ETL container starting
12:01:34.505 [main] INFO  metrics.connector.SplunkConnector - insecure url https://xxxxxx-wsl1.internal.salesforce.com:8089/services/auth/login?output_mode=json
12:01:35.286 [main] ERROR metrics.connector.SplunkConnector - https://xxxxx-wsl1.internal.salesforce.com:8089
12:01:35.286 [main] ERROR metrics.connector.SplunkConnector - java.lang.RuntimeException: Failed request = https://pteyer-wsl1.internal.salesforce.com:8089/services/auth/login?output_mode=json, error code = 400 : {"messages":[{"type":"WARN","text":"Login failed"}]}
12:01:35.287 [main] ERROR metric.Main - error java.lang.RuntimeException: Failed request = https://xxxxxxx-wsl1.internal.salesforce.com:8089/services/auth/login?output_mode=json, error code = 400 : {"messages":[{"type":"WARN","text":"Login failed"}]}

Any ideas?

Tags (4)
0 Karma

jantona
Engager

I eventually just settled on making it work with CURL embedded into Java:

public String curlConnect() throws Exception {
        String r = null;
        try {
            List<String> theCommand = new ArrayList<String>();
            theCommand.add("curl");
            theCommand.add("-sk");
            theCommand.add(this.surl + "/services/auth/login?output_mode=json");
            logger.debug(this.surl+ "/services/auth/login?output_mode=json");
            logger.debug("-d username=" + this.user + " password=XXXXXX");
            theCommand.add("-d");
            theCommand.add("username=" + this.user);
            theCommand.add("-d");
            theCommand.add("password=" + this.token);

            ProcessBuilder pb = new ProcessBuilder(theCommand);

            pb.directory(new File(System.getProperty("input.file.path")));
            pb.redirectErrorStream(true);
            Process p = pb.start();
            InputStream is = p.getInputStream();

            r = IOUtils.toString(is);
            r = r.substring(r.indexOf("{\"sessionKey\":\""), r.length());
            JSONObject jsonResponse = new JSONObject(r);
            this.sessionKey = jsonResponse.getString("sessionKey");
            r = this.sessionKey;
            logger.debug(r);

        } catch ( Exception e ) {
            logger.error(this.surl);
            logger.error(e.getMessage());
            throw e;
        }
        return r;
    }

    public String query(String splunkQuery) throws Exception {
        String r = null;
        try {
            List<String> theCommand = new ArrayList<String>();
            theCommand.add("curl");
            theCommand.add("-sku");
            theCommand.add(this.user+":"+this.token);
            //theCommand.add("-H");
            //theCommand.add("\"Authorization: Splunk " + this.sessionKey + "\"");
            theCommand.add(this.surl + "/services/search/jobs?output_mode=json");
            logger.debug(this.surl+ "/services/search/jobs?output_mode=json");
            theCommand.add("-d");
            theCommand.add("search=" + URLEncoder.encode(splunkQuery, "UTF-8"));
            logger.info("search=" + URLEncoder.encode(splunkQuery, "UTF-8"));
            //theCommand.add("-d");
            //theCommand.add("output_mode=json");

            ProcessBuilder pb = new ProcessBuilder(theCommand);

            pb.directory(new File(System.getProperty("input.file.path")));
            pb.redirectErrorStream(true);
            Process p = pb.start();
            InputStream is = p.getInputStream();

            String theResult = IOUtils.toString(is);
            logger.info(theResult);

            theResult = theResult.substring(theResult.indexOf("{\"sid\":\""), theResult.length());
            JSONObject jsonResponse = new JSONObject(theResult);
            r = jsonResponse.getString("sid");

            while ( !resultsReady(r)) {
                logger.info("waiting 30 seconds for async report to finish running sid " + r);
                java.util.concurrent.TimeUnit.SECONDS.sleep(30);
            }
        } catch ( Exception e) {
            logger.error(this.surl);
            logger.error(e.getMessage());
            throw e;
        }
        return r;
    }
0 Karma

marcellodesales
Path Finder

Having the same problem... I can get a curl working to query the REST API... but I get a 400 in Java... Is it related to encoding the request?

0 Karma
Got questions? Get answers!

Join the Splunk Community Slack to learn, troubleshoot, and make connections with fellow Splunk practitioners in real time!

Meet up IRL or virtually!

Join Splunk User Groups to connect and learn in-person by region or remotely by topic or industry.

Get Updates on the Splunk Community!

Agent Mode Engaged! Enchaining Agentic Operations with Splunk AI Assistant 2.0

    Are you ready to transform how your team handles complex data requests? We invite you to our upcoming ...

Announcing Modern Navigation: A New Era of Splunk User Experience

We are excited to introduce the Modern Navigation feature in the Splunk Platform, available to both cloud and ...

Modernize your Splunk Apps – Introducing Python 3.13 in Splunk

We are excited to announce that the upcoming releases of Splunk Enterprise 10.2.x and Splunk Cloud Platform ...