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
Get Updates on the Splunk Community!

Introducing the Splunk Community Dashboard Challenge!

Welcome to Splunk Community Dashboard Challenge! This is your chance to showcase your skills in creating ...

Wondering How to Build Resiliency in the Cloud?

IT leaders are choosing Splunk Cloud as an ideal cloud transformation platform to drive business resilience,  ...

Updated Data Management and AWS GDI Inventory in Splunk Observability

We’re making some changes to Data Management and Infrastructure Inventory for AWS. The Data Management page, ...