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?
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;
}
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?