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!

ICYMI - Check out the latest releases of Splunk Edge Processor

Splunk is pleased to announce the latest enhancements to Splunk Edge Processor.  HEC Receiver authorization ...

Introducing the 2024 SplunkTrust!

Hello, Splunk Community! We are beyond thrilled to announce our newest group of SplunkTrust members!  The ...

Introducing the 2024 Splunk MVPs!

We are excited to announce the 2024 cohort of the Splunk MVP program. Splunk MVPs are passionate members of ...