args) {
+ ResponseMessage response = service.get(actionPath("history"), args);
+ return parseHistoryResponse(response);
+ }
+
+ /**
+ * Parses response message from history action path
+ *
+ * @param response
+ * @return result An array of Job
+ */
+ private Job[] parseHistoryResponse(final ResponseMessage response) {
AtomFeed feed;
try {
feed = AtomFeed.parseStream(response.getContent());
@@ -170,7 +192,7 @@ public String getActionEmailCc() {
*
* Generally, this command is a template search pipeline that is realized
* with values from the saved search. To reference saved search field
- * values, wrap them in "$". For example, use "$name$" to reference the
+ * values, wrap them in "$". For example, use "$name$" to reference the
* saved search name, or use "$search$" to reference the search query.
*
* @return The search command (or pipeline).
@@ -630,7 +652,7 @@ public String getActionSummaryIndexName() {
*
* Generally, this command is a template search pipeline that is realized
* with values from the saved search. To reference saved search field
- * values, wrap them in "$". For example, use "$name$" to reference the
+ * values, wrap them in "$". For example, use "$name$" to reference the
* saved search name, or use "$search$" to reference the search query.
*
* @return The search command (or pipeline).
@@ -906,7 +928,7 @@ public int getDispatchMaxCount() {
public int getDispatchMaxTime() {
return getInteger("dispatch.max_time");
}
-
+
/**
* Returns how frequently Splunk runs the MapReduce reduce phase
* on accumulated map values.
@@ -928,7 +950,7 @@ public int getDispatchReduceFrequency() {
public boolean getDispatchRtBackfill() {
return getDispatchRealTimeBackfill();
}
-
+
/**
* Indicates whether to back fill the real-time window for this search.
* This attribute only applies to real-time searches.
@@ -1235,7 +1257,7 @@ public void setActionEmailCc(String cc) {
*
* Generally, this command is a template search pipeline that is realized
* with values from the saved search. To reference saved search field
- * values, wrap them in "$". For example, use "$name$" to reference the
+ * values, wrap them in "$". For example, use "$name$" to reference the
* saved search name, or use "$search$" to reference the search query.
*
* @param command The search command (or pipeline).
@@ -1547,7 +1569,7 @@ public void setActionPopulateLookupTtl(String ttl) {
*
* Generally, this command is a template search pipeline that is realized
* with values from the saved search. To reference saved search field
- * values, wrap them in "$". For example, use "$name$" to reference the
+ * values, wrap them in "$". For example, use "$name$" to reference the
* saved search name, or use "$search$" to reference the search query.
*
* @param command The search command (or pipeline).
@@ -1614,7 +1636,7 @@ public void setActionRssTtl(String ttl) {
*
* Generally, this command is a template search pipeline that is realized
* with values from the saved search. To reference saved search field
- * values, wrap them in "$". For example, use "$name$" to reference the
+ * values, wrap them in "$". For example, use "$name$" to reference the
* saved search name, or use "$search$" to reference the search query.
*
* @param command The search command (or pipeline).
@@ -1702,7 +1724,7 @@ public void setActionSummaryIndexName(String name) {
*
* Generally, this command is a template search pipeline that is realized
* with values from the saved search. To reference saved search field
- * values, wrap them in "$". For example, use "$name$" to reference the
+ * values, wrap them in "$". For example, use "$name$" to reference the
* saved search name, or use "$search$" to reference the search query.
*
* @param command The search command (or pipeline).
@@ -1954,7 +1976,7 @@ public void setDisabled(boolean disabled) {
public void setDispatchBuckets(String buckets) {
setDispatchBuckets(Integer.parseInt(buckets));
}
-
+
/**
* Sets the maximum number of timeline buckets.
*
@@ -2161,7 +2183,7 @@ public void setRequestUiDispatchView(String view) {
public void setRestartOnSearchpeerAdd(boolean restart) {
setRestartOnSearchPeerAdd(restart);
}
-
+
/**
* Sets whether a real-time search managed by the scheduler is
* restarted when a search peer becomes available for this saved search.
diff --git a/splunk/src/main/java/com/splunk/Service.java b/splunk/src/main/java/com/splunk/Service.java
index cbe63b4a..d6d15b8f 100644
--- a/splunk/src/main/java/com/splunk/Service.java
+++ b/splunk/src/main/java/com/splunk/Service.java
@@ -66,6 +66,9 @@ public class Service extends BaseService {
/** The version of this Splunk instance, once logged in. */
public String version = null;
+ /** The type of this Splunk instance, once logged in. */
+ public String instanceType = null;
+
/** The default host name, which is used when a host name is not provided.*/
public static String DEFAULT_HOST = "localhost";
@@ -225,7 +228,7 @@ public InputStream export(String search, Map args) {
}
ResponseMessage response;
- if (versionIsAtLeast("9.0"))
+ if(enableV2SearchApi())
response = post(JobCollection.REST_PATH_V2 + "/export", args);
else {
response = post(JobCollection.REST_PATH + "/export", args);
@@ -1112,7 +1115,7 @@ public UserCollection getUsers(Args args) {
* @return The current {@code Service} instance.
*/
public Service login() {
- if (!this.cookieStore.isEmpty() && (this.username == null || this.password == null)) {
+ if (this.cookieStore.hasSplunkAuthCookie() && (this.username == null || this.password == null)) {
return this;
}
else if (this.username == null || this.password == null) {
@@ -1147,6 +1150,7 @@ public Service login(String username, String password) {
.getTextContent();
this.token = "Splunk " + sessionKey;
this.version = this.getInfo().getVersion();
+ this.instanceType = this.getInfo().getInstanceType();
if (versionCompare("4.3") >= 0)
this.passwordEndPoint = "storage/passwords";
@@ -1258,7 +1262,7 @@ public ResponseMessage parse(String query) {
public ResponseMessage parse(String query, Map args) {
args = Args.create(args).add("q", query);
- if (versionIsAtLeast("9.0"))
+ if(enableV2SearchApi())
return post("search/v2/parser", args);
else
return get("search/parser", args);
@@ -1312,7 +1316,7 @@ public Job search(String query, Map args) {
*/
@Override public ResponseMessage send(String path, RequestMessage request) {
// cookieStore is a protected member of HttpService
- if (token != null && cookieStore.isEmpty()) {
+ if (token != null && !cookieStore.hasSplunkAuthCookie() ) {
request.getHeader().put("Authorization", token);
}
return super.send(fullpath(path), request);
@@ -1350,6 +1354,15 @@ public void setBearerToken(String value) {
this.token = value.contains("Splunk") || value.contains("Bearer") ? value : "Bearer " + value;
}
+
+ public boolean enableV2SearchApi(){
+ if(this.instanceType.equalsIgnoreCase("cloud")) {
+ return versionIsAtLeast("9.0.2209");
+ }else{
+ return versionIsAtLeast("9.0.2");
+ }
+ }
+
/**
* Returns true if this Splunk instance's version is no earlier than
* the version specified in {@code version}.
diff --git a/splunk/src/main/java/com/splunk/ServiceInfo.java b/splunk/src/main/java/com/splunk/ServiceInfo.java
index 72f556bd..16ec8aaa 100644
--- a/splunk/src/main/java/com/splunk/ServiceInfo.java
+++ b/splunk/src/main/java/com/splunk/ServiceInfo.java
@@ -155,6 +155,8 @@ public String getVersion() {
return getString("version");
}
+ public String getInstanceType() {return getString("instance_type", "");}
+
/**
* Indicates whether this Splunk instance is running under a free license.
*
diff --git a/splunk/src/main/java/com/splunk/SimpleCookieStore.java b/splunk/src/main/java/com/splunk/SimpleCookieStore.java
index afc1219c..4fd60664 100644
--- a/splunk/src/main/java/com/splunk/SimpleCookieStore.java
+++ b/splunk/src/main/java/com/splunk/SimpleCookieStore.java
@@ -28,6 +28,8 @@
*/
class SimpleCookieStore {
+ public static final String SPLUNK_AUTH_COOKIE = "splunkd_";
+
private Map cookieJar = new HashMap();
/**
* Adds cookies from a "Set-Cookie" header to the cookie store.
@@ -69,6 +71,18 @@ public Boolean isEmpty() {
return cookieJar.isEmpty();
}
+ public boolean hasSplunkAuthCookie(){
+ if(cookieJar.isEmpty()){
+ return false;
+ }
+ for(String cookie : cookieJar.keySet()){
+ if(cookie.startsWith(SPLUNK_AUTH_COOKIE)){
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Removes all cookies from SimpleCookieStore
*/
diff --git a/splunk/src/test/java/com/splunk/CookieTest.java b/splunk/src/test/java/com/splunk/CookieTest.java
index f49b18d2..d11cda76 100644
--- a/splunk/src/test/java/com/splunk/CookieTest.java
+++ b/splunk/src/test/java/com/splunk/CookieTest.java
@@ -16,13 +16,11 @@
package com.splunk;
+import java.net.HttpCookie;
import java.util.HashMap;
import java.util.Map;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
public class CookieTest extends SDKTestCase {
@@ -124,6 +122,32 @@ public void testLoginWithMultipleCookies() {
s.getSettings().refresh();
}
+ @Test
+ public void testLoginWithOtherCookies() {
+ String otherCookies = "load=balancer;";
+ service.logout();
+ service.cookieStore.removeAll();
+ service.cookieStore.add(otherCookies);
+ service.login();
+ service.getApplications();
+ service.cookieStore.removeAll();
+ }
+
+ @Test
+ public void testUsingAuthTokenAndOtherCookie(){
+ String validToken = service.getToken();
+ Assert.assertTrue(validToken.startsWith("Splunk "));
+ String otherCookies = "load=balancer;";
+ Map args = new HashMap<>();
+ args.put("cookie", otherCookies);
+ args.put("host",service.getHost());
+ args.put("port", service.getPort());
+ Service s = new Service(args);
+ s.setToken(validToken);
+ s.getApplications();
+ Assert.assertEquals(otherCookies.trim(),s.cookieStore.getCookies().trim());
+ }
+
@Test
public void testLoginWithMultipleInvalidCookies() {
String validCookie = service.stringifyCookies();
diff --git a/splunk/src/test/java/com/splunk/IndexTest.java b/splunk/src/test/java/com/splunk/IndexTest.java
index a98dd56a..56d6670a 100644
--- a/splunk/src/test/java/com/splunk/IndexTest.java
+++ b/splunk/src/test/java/com/splunk/IndexTest.java
@@ -77,8 +77,8 @@ public void testAttachWithCookieHeader() throws IOException {
// Cookies not implemented before version 6.2
return;
}
- // Check that their are cookies at all
- Assert.assertTrue(service.hasCookies());
+ // Check that their are Splunk Auth cookies at all
+ Assert.assertTrue(service.hasSplunkAuthCookies());
// Make a service that only has that cookie
String validCookie = service.stringifyCookies();
diff --git a/splunk/src/test/java/com/splunk/PasswordTest.java b/splunk/src/test/java/com/splunk/PasswordTest.java
index 175c8c4c..3d32d393 100644
--- a/splunk/src/test/java/com/splunk/PasswordTest.java
+++ b/splunk/src/test/java/com/splunk/PasswordTest.java
@@ -19,6 +19,8 @@
import org.junit.Assert;
import org.junit.Test;
+import java.util.HashMap;
+
public class PasswordTest extends SDKTestCase {
@Test
public void testGettersOfDefaultPasswords() {
@@ -129,4 +131,46 @@ public void testPasswordsCompatibleGetByName() {
passwords.remove(username);
Assert.assertNull(passwords.get(username));
}
+ @Test
+ public void testPasswordsWithWildCards(){
+ HashMap args = new HashMap();
+ args = Command.defaultValues;
+ args.put("owner", "-");
+ args.put("app", "-");
+ args.put("username", "admin");
+ args.put("password", "changed!");
+ Service service = Service.connect(args);
+ PasswordCollection passwords = service.getPasswords();
+ Assert.assertEquals(passwords.size(),0);
+
+ String name = "no-owner";
+ String value = "sdk-test-password";
+ String realm = "sdk-test-realm";
+
+ Password password;
+ // Create a password
+ try{
+ password = passwords.create(name, value);
+ }catch(IllegalArgumentException e){
+ Assert.assertEquals("While creating StoragePasswords, namespace cannot have wildcards.", e.getMessage());
+ }
+ try{
+ password = passwords.create(name, value, realm);
+ }catch(IllegalArgumentException e){
+ Assert.assertEquals("While creating StoragePasswords, namespace cannot have wildcards.", e.getMessage());
+ }
+ // Remove a password
+ try{
+ password = passwords.remove(name);
+ }catch(IllegalArgumentException e){
+ Assert.assertEquals("app context must be specified when removing a password.", e.getMessage());
+ }
+ try{
+ password = passwords.remove(realm, name);
+ }catch(IllegalArgumentException e){
+ Assert.assertEquals("app context must be specified when removing a password.", e.getMessage());
+ }
+ passwords = service.getPasswords();
+ Assert.assertEquals(passwords.size(),0);
+ }
}
diff --git a/splunk/src/test/java/com/splunk/ReceiverTest.java b/splunk/src/test/java/com/splunk/ReceiverTest.java
index 99e4b0e4..e171b9d1 100644
--- a/splunk/src/test/java/com/splunk/ReceiverTest.java
+++ b/splunk/src/test/java/com/splunk/ReceiverTest.java
@@ -24,6 +24,8 @@
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
public class ReceiverTest extends SDKTestCase {
@@ -36,9 +38,28 @@ public void testReceiverWithoutCookie() {
@Test
public void testReceiverWithCookie() {
Assume.assumeTrue(service.versionIsAtLeast("6.2"));
- Assert.assertTrue(service.hasCookies());
+ Assert.assertTrue(service.hasSplunkAuthCookies());
testReceiver(service);
}
+
+ @Test
+ public void testReceiverWithoutSplunkCookie() {
+ String validToken = service.getToken();
+ Assert.assertTrue(validToken.startsWith("Splunk "));
+ String otherCookies = "load=balancer;";
+ Map args = new HashMap<>();
+ args.put("cookie", otherCookies);
+ args.put("host",service.getHost());
+ args.put("port", service.getPort());
+ Service s = new Service(args);
+ s.setToken(validToken);
+ s.version = s.getInfo().getVersion();
+ System.out.println(s.version);
+ Assume.assumeTrue(s.versionIsAtLeast("6.2"));
+ Assert.assertTrue(!s.cookieStore.isEmpty());
+ testReceiver(s);
+ }
+
// Make a few simple requests and make sure the results look ok.
public void testReceiver(Service passedService) {
Receiver receiver = passedService.getReceiver();
diff --git a/splunk/src/test/java/com/splunk/SavedSearchTest.java b/splunk/src/test/java/com/splunk/SavedSearchTest.java
index fcaf672b..dc45caa1 100644
--- a/splunk/src/test/java/com/splunk/SavedSearchTest.java
+++ b/splunk/src/test/java/com/splunk/SavedSearchTest.java
@@ -21,6 +21,8 @@
import org.junit.Before;
import org.junit.Test;
+import java.util.HashMap;
+
public class SavedSearchTest extends SDKTestCase {
SavedSearchCollection savedSearches;
String savedSearchName;
@@ -429,4 +431,34 @@ public boolean predicate() {
Assert.fail(e.toString());
}
}
+
+ @Test
+ public void testHistoryWithArgs(){
+ savedSearch.refresh();
+ Assert.assertEquals(0, savedSearch.history().length);
+ try {
+ Job job;
+ for(int i = 0 ; i < 31 ; i++){
+ job = savedSearch.dispatch();
+ while(!job.isReady()){
+ sleep(2);
+ }
+ }
+ //history without any argument, it will return max 30 jobs only.
+ Assert.assertEquals(30, savedSearch.history().length);
+
+ //history with argument 'count' set to '0' i.e it returns the whole history
+ HashMap args = new HashMap();
+ args.put("count", 0);
+ Assert.assertEquals(31, savedSearch.history(args).length);
+
+ //history with argument 'count' set to '10' i.e. it will return only 10 jobs from history
+ args.put("count", 10);
+ args.put("sort_dir", "desc");
+ Assert.assertEquals(10, savedSearch.history(args).length);
+
+ } catch (InterruptedException e) {
+ Assert.fail(e.toString());
+ }
+ }
}
diff --git a/splunk/src/test/java/com/splunk/ServiceTest.java b/splunk/src/test/java/com/splunk/ServiceTest.java
index 1bd80833..ce9aafdf 100644
--- a/splunk/src/test/java/com/splunk/ServiceTest.java
+++ b/splunk/src/test/java/com/splunk/ServiceTest.java
@@ -715,4 +715,24 @@ public void testPost() {
Assert.assertTrue(firstLineIsXmlDtd(response.getContent()));
}
+ /*
+ Test whether the V2 and V1 Search APIs are switched properly based on the Type of Splunk Instance and Version.
+ */
+ @Test
+ public void testEnableV2Api(){
+ if(service.instanceType.equalsIgnoreCase("cloud")) {
+ if(service.versionIsEarlierThan("9.0.2209")){
+ Assert.assertFalse(service.enableV2SearchApi());
+ }else{
+ Assert.assertTrue(service.enableV2SearchApi());
+ }
+ }else{
+ if(service.versionIsEarlierThan("9.0.2")){
+ Assert.assertFalse(service.enableV2SearchApi());
+ }else{
+ Assert.assertTrue(service.enableV2SearchApi());
+ }
+ }
+ }
+
}