diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..d008e42b
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,42 @@
+on:
+ release:
+ types: [published]
+
+permissions:
+ contents: write
+
+name: Release
+
+jobs:
+ build:
+ name: Java SDK Release
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+ server-username: MAVEN_USERNAME
+ server-password: MAVEN_PASSWORD
+ server-id: splunk-artifactory
+ - name: build
+ run: mvn package --file pom.xml -DskipTests=true
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v1
+ with:
+ files: ./splunk/target/*.jar
+ draft: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Deploy to Artifactory
+ run: mvn --batch-mode deploy -DskipTests=true
+ env:
+ MAVEN_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
+
+ - name: Upload Artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: java_sdk_docs
+ path: splunk/target/apidocs
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..84ca35c8
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,66 @@
+name: Java SDK Test
+
+on:
+ [push, pull_request]
+
+jobs:
+ test:
+ strategy:
+ fail-fast: false
+ matrix:
+ os:
+ - ubuntu-latest
+ java-version:
+ - 1.8
+ splunk-version:
+ - "8.2"
+ - "latest"
+ runs-on: ${{ matrix.os }}
+
+ services:
+ splunk:
+ image: splunk/splunk:${{matrix.splunk-version}}
+ env:
+ SPLUNK_START_ARGS: --accept-license
+ SPLUNK_PASSWORD: changed!
+ TEST_TCP_PORT: 10667
+ TEST_UDP_PORT: 10668
+ SPLUNK_HOME: "/opt/splunk"
+ SPLUNK_APPS_URL: https://github.com/splunk/sdk-app-collection/releases/download/v1.1.0/sdkappcollection.tgz
+ ports:
+ - 8000:8000
+ - 8089:8089
+ - 8088:8088
+ - 10667:10667
+ - 10668:10668/udp
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+
+ - name: Cache local Maven repository
+ uses: actions/cache@v2
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: ${{ runner.os }}-maven-
+
+ - name: Create .splunkrc file
+ run: |
+ cd ~
+ echo host=localhost >> .splunkrc
+ echo port=8089 >> .splunkrc
+ echo username=admin >> .splunkrc
+ echo password=changed! >> .splunkrc
+ echo scheme=https >> .splunkrc
+ echo version=${{ matrix.splunk }} >> .splunkrc
+
+ - name: Test using maven
+ run: mvn test -fae
+ env:
+ SPLUNK_HOME: "/opt/splunk"
+ TEST_TCP_PORT: 10667
+ TEST_UDP_PORT: 10668
diff --git a/.gitignore b/.gitignore
index 2177187f..0f808f1f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,12 +8,15 @@
build
dist
out
+target/
# Test & Coverage
TEST-com.splunk.*.xml
# IntelliJ
.idea/workspace.xml
+.idea/misc.xml
+.idea/
# Unknown
*.swp
diff --git a/.idea/ant.xml b/.idea/ant.xml
deleted file mode 100644
index 313b0c0c..00000000
--- a/.idea/ant.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
index 3572571a..e7bedf33 100644
--- a/.idea/copyright/profiles_settings.xml
+++ b/.idea/copyright/profiles_settings.xml
@@ -1,5 +1,3 @@
-
-
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index f50841ca..00000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- http://www.w3.org/1999/xhtml
-
-
-
-
-
-
diff --git a/.idea/splunk-sdk-java.iml b/.idea/splunk-sdk-java.iml
new file mode 100644
index 00000000..d6ebd480
--- /dev/null
+++ b/.idea/splunk-sdk-java.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6589b22a..8aad9ae9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,178 @@
-# Splunk SDK for Java Changelog
+# Splunk Enterprise SDK for Java Changelog
+
+## Version 1.9.5
+
+### New Features and APIs
+* Added static method _addClusterMasterURIsToHosts_ in HttpService class to update list of Valid Hosts with Cluster Master Hosts (GitHub PR [#215](https://github.com/splunk/splunk-sdk-java/pull/215))
+* Added instance method _getClusterMasters_ in Service class to get list of cluster master hosts
+
+## Version 1.9.4
+
+### Minor Changes
+* Added check for localhost IPv6 address, for IPv6 compatible apps (GitHub PR [#210](https://github.com/splunk/splunk-sdk-java/pull/210))
+* Updating SSL_SOCKET_FACTORY instance on changing _validateCertificates_ flag. (GitHub PR [#206](https://github.com/splunk/splunk-sdk-java/pull/210))
+
+## Version 1.9.3
+
+### Minor Changes
+* Re-fetch logic for instancetype and version fields if not set within Service instance to avoid NPE (GitHub PR [#202](https://github.com/splunk/splunk-sdk-java/pull/202))
+* Check for local IP as alternative to _localhost_ within HostnameVerifier, addressing issue with certain local workflows
+
+## Version 1.9.2
+
+### New Features and APIs
+* Added feature that allows to update ACL properties of an entity (GitHub PR [#196](https://github.com/splunk/splunk-sdk-java/pull/196))
+
+### Minor Changes
+* Added null check for child to handle error when no value is passed for a parameter in modular-inputs (Ref issue [#198](https://github.com/splunk/splunk-sdk-java/issues/198) & GitHub PR [#199](https://github.com/splunk/splunk-sdk-java/pull/199))
+
+## Version 1.9.1
+
+### New Features and APIs
+* SDK Support for third-party (Load Balancer) "sticky sessions"(cookie persistence) (Github PR [#192](https://github.com/splunk/splunk-sdk-java/pull/192))
+* Added Args option for Saved Search history method (GitHub Issue [#126](https://github.com/splunk/splunk-sdk-java/issues/126) & PR [#188](https://github.com/splunk/splunk-sdk-java/pull/188) )
+
+### Minor Changes
+* Special handling related to the semantic versioning of specific Search APIs functional in Splunk Enterprise 9.0.2 and (Splunk Cloud 9.0.2209). These SDK changes will enable seamless transition between the APIs based on the version of the Splunk Enterprise/Cloud (Github PR [#193](https://github.com/splunk/splunk-sdk-java/pull/193))
+* Updated checks to fetch Storage Passwords with wildcards in namespace. (GitHub PR [#187](https://github.com/splunk/splunk-sdk-java/pull/187))
+
+## Version 1.9.0
+
+### New Features and APIs
+* SDK Support for splunkd search API changes, for Splunk 9.0+. (Github PR [#189](https://github.com/splunk/splunk-sdk-java/pull/189))
+
+### Minor Changes
+* Automated docs generation using GitHub actions. (Github PR [#184](https://github.com/splunk/splunk-sdk-java/pull/184))
+
+## Version 1.8.0
+
+### New Features and APIs
+* Added a support to add custom headers in Service class. (Github PR [#176](https://github.com/splunk/splunk-sdk-java/pull/176)).
+* SSL Certificate validation (default implementation) added. (Github PR [#175](https://github.com/splunk/splunk-sdk-java/pull/175)).
+ * Boolean flag is introduced to skip/validate certificate. Use _HttpService.setValidateCertificates()_ to enable/disable certificate validation.
+ * Breaking change: Certificate validation is now enforced by default, for local or non-production use cases use _HttpService.setValidateCertificates(false)_.
+* Apps/app-install replaced with **apps/local**. (Github PR [#168](https://github.com/splunk/splunk-sdk-java/pull/168))
+* Breaking change: HttpService.useTLS flag removed, please use _HttpService.setSslSecurityProtocol()_ to set a specific SSL/TLS implementation or else TLS v1.2 is used by default for Java 1.8.
+
+### Minor Changes
+
+* External Entities restricted in XML factory. (Github PR [#180](https://github.com/splunk/splunk-sdk-java/pull/180)).
+ * Prevent expansion of external entities in Document Builder factory.
+* Headers modified in Socket creation. (Github PR [#179](https://github.com/splunk/splunk-sdk-java/pull/179)).
+ * Http Request uses raw request headers by including escape characters which seems vulnerable. It was replaced with PrintWriter methods to avoid escape characters.
+ * Host parameter used in Socket is omitted to prevent exposing it to external users.
+* README.md file modified with all login methods along with Splunk Search creation example. (Github PR [#177](https://github.com/splunk/splunk-sdk-java/pull/177)).
+* Deploy plugin is removed from Splunk module pom to avoid redundancy. (Github PR [#172](https://github.com/splunk/splunk-sdk-java/pull/172)).
+* Setter methods for Session and Bearer token added along with test case. (Github PR [#171](https://github.com/splunk/splunk-sdk-java/pull/171))
+ * **Use:** service.setSplunkToken() for session tokens and service.setBearerToken() for long-lived tokens.
+* Modular input folder name renamed based on newer splunk folder name validation. (Github PR [#168](https://github.com/splunk/splunk-sdk-java/pull/168))
+* SDK app collection URL has been updated to v1.1.0 in docker compose file. (Github PR [#168](https://github.com/splunk/splunk-sdk-java/pull/168))
+ * Test files in sdk app collections are modified based on python v3 syntax.
+* Added Saved Search test case based on title. (Github PR [#166](https://github.com/splunk/splunk-sdk-java/pull/166))
+
+## Version 1.7.1
+
+### Minor Changes
+* Dependency breaking changes are resolved.
+
+## Version 1.7.0
+
+### New Features and APIs
+* Added Credits.md file along with licences. (Github PR [#162](https://github.com/splunk/splunk-sdk-java/pull/162)).
+* Improved TLS implementation as default behavior and turned on hostname verification for all hosts. (Github PR [#158](https://github.com/splunk/splunk-sdk-java/pull/158)).
+
+### Minor changes
+* Replaced Travis CI with Github actions (Github PR [#161](https://github.com/splunk/splunk-sdk-java/pull/161)).
+* Fixed Javadoc generation while project packaging. (Github PR [#159](https://github.com/splunk/splunk-sdk-java/pull/159)).
+* Fixed breaking change of **Index.getMaxHotBuckets()** method behavior to return as String instead of int.
+* SDK build is migrated from ant build tool to maven build tool (Github PR [#157](https://github.com/splunk/splunk-sdk-java/pull/157)).
+ * Dependencies directory for ant build is removed and maven dependencies are added using pom.xml.
+ * Dependencies are upgraded to its LTS version.
+ * Project structure is re-organized with respect to Maven.
+
+## Version 1.6.5
+
+### Bug Fixes
+
+* Fixed bug for push back buffer is full when exporting data in XML (GitHub PR [#125](https://github.com/splunk/splunk-sdk-java/pull/125)).
+
+## Version 1.6.4
+
+### Bug Fixes
+
+* Fixed bug in modinput Windows shims that caused Splunk Enterprise to fail to restart (GitHub PR [#120](https://github.com/splunk/splunk-sdk-java/pull/120)).
+* Fixed bug with data model endpoint on Splunk Enterprise 7+ (GitHub PR [#117](https://github.com/splunk/splunk-sdk-java/pull/117)).
+* Fixed bug with invalid `Index.submit()` forming an invalid REST API path for namespaced services ([#118](https://github.com/splunk/splunk-sdk-java/pull/118)).
+* Fixed bug with `Value.toDate(string value)` not being thread safe (GitHub PR [#109](https://github.com/splunk/splunk-sdk-java/pull/109)).
+
+## Version 1.6.3
+
+### New features and APIs
+
+* Added the `updated` property on all `Resource` objects (GitHub PR [#104](https://github.com/splunk/splunk-sdk-java/pull/104)).
+
+## Version 1.6.2
+
+### Bug Fixes
+
+* Update modular input shims to ensure Java processes are killed (GitHub issue [#92](https://github.com/splunk/splunk-sdk-java/issues/92)).
+
+## Version 1.6.1
+
+### Bug Fixes
+
+* Fix authentication issues when the Splunk `Set-Cookie` header is not the first one.
+
+## Version 1.6.0
+
+### New features and APIs
+
+* Added support for retrieving `Password` entities scoped by realm and username.
+* Added getter methods for embed `SavedSearch` properties.
+* Added support for custom `HttpURLConnection` connection timeouts on `HttpService`.
+* Performance improvement to `SavedSearch.dispatch()`.
+* Added getter methods to the `Job` class for retrieving `long` values (`getEventCountLong`, `getResultCountLong`, `getScanCountLong`).
+* Added `setFieldList()` to the `JobExportArgs` class.
+* Added support for the `manualRebuilds` `DataModel` setting.
+
+### Bug Fixes
+
+* Fixed `SavedSearch.Dispatch()` throwing a `NullPointerException` in some load-balanced search head clustering environments.
+* Fixed non-limit `PivotFilter` constructing the wrong JSON blob.
+
+### Minor changes
+
+* Added support for Travis CI.
+
+## Version 1.5.0
+
+### New features and APIs
+
+* Added support for cookie-based authentication, for Splunk 6.2+.
+
+### Bug Fixes
+
+* Fixed failure parsing XML responses. Pull Request #76.
+* Fixed bug where `Job` is never ready leading to infinite loops.
+
+### Minor changes
+
+* The SDK is now properly compiled with the `Command` class used in examples.
+
+## Version 1.4.0
+
+### New features and APIs
+
+* Added support for Java 8, when manually configuring the `Service` class to use TLSv1.2, TLSv1.1, or TLSv1 defined in the `SSLSecurityProtocol` enum. The default is still SSLv3.
+* Allow setting a custom `SSLSocketFactory` on the `HTTPService` and `Service` classes.
+
+### New examples
+
+* `ssl_protocols`: tries to connect to Splunk over HTTPS using different SSL/TLS protocols, then using a custom SSL and TLS `SSLSocketFactory`.
+
+### Minor changes
+
+* The SDK is now compiled with the `Command` class used in examples.
## Version 1.3.2
@@ -46,11 +220,11 @@
### New features and APIs
-* The Splunk SDK for Java is fully compatible with Splunk Enterprise 6.0 as of this release.
+* The Splunk Enterprise SDK for Java is fully compatible with Splunk Enterprise 6.0 as of this release.
### Bug fixes
-* **JobCollection.create()** previously invalidated the collection and refreshed it to see whether the job had
+* **JobCollection.create()** previously invalidated the collection and refreshed it to see whether the job had
appeared. This was problematic for Splunk Enterprise instances running many jobs at once. The method has been changed
to only interact with the endpoint specific to the newly created job.
* Namespaces that contain special characters such as '@' in their owner or app are now handled correctly.
@@ -64,18 +238,18 @@
### Known issues
-* Certain combinations of requests and restarts of splunkd can cause splunkd to hang on OS X v10.8 Mountain Lion and
- OS X v10.9 Mavericks running Splunk 6.0.0. This issue is not present when running Splunk Enterprise on earlier
+* Certain combinations of requests and restarts of splunkd can cause splunkd to hang on OS X v10.8 Mountain Lion and
+ OS X v10.9 Mavericks running Splunk 6.0.0. This issue is not present when running Splunk Enterprise on earlier
versions of OS X. This will be fixed in a future release.
-* The modular input support in the Splunk SDK for Java is not compatible with Windows Server 2003 or Windows Server
+* The modular input support in the Splunk Enterprise SDK for Java is not compatible with Windows Server 2003 or Windows Server
2003 R2.
## Version 1.2
### New features and APIs
-* Added support for building modular input scripts in Java using the Splunk SDK for Java.
+* Added support for building modular input scripts in Java using the Splunk Enterprise SDK for Java.
### Bug fixes
@@ -87,29 +261,29 @@
### Breaking changes
-* The default setting for all search jobs is now `segmentation=none` unless
+* The default setting for all search jobs is now `segmentation=none` unless
you explicitly set it otherwise. This setting returns results as a raw-text
string rather than a string in XML format.
-
-* The `ResultReaderCsv` class no longer supports streams from the `Service.export` method.
- Instead, use the `ResultReaderXml` class with XML output, or use the `ResultReaderJson`
+
+* The `ResultReaderCsv` class no longer supports streams from the `Service.export` method.
+ Instead, use the `ResultReaderXml` class with XML output, or use the `ResultReaderJson`
class with JSON output.
-
+
### New features and APIs
-* New classes have been added, `MultiResultsReaderXml` and `MultiResultsReaderJson`,
+* New classes have been added, `MultiResultsReaderXml` and `MultiResultsReaderJson`,
to read search results streams with multiple result sets from `Service.Export` methods.
-
+
* The `ResultsReader` classes now support `Iterable` and `Iterator` interfaces.
-* The `Event.getSegmentedRaw` method has been added to return raw data from events, preserving
- segmentation information.
-
+* The `Event.getSegmentedRaw` method has been added to return raw data from events, preserving
+ segmentation information.
+
### Bug fixes
-* The `ServiceInfo` class now uses the `services/*` endpoint rather than the
- default namespace (`servicesNS/*`) for HTTP requests. This change is a workaround to
- avoid a bug in Splunk that returns HTTP code 403 when the `server/info` endpoint
+* The `ServiceInfo` class now uses the `services/*` endpoint rather than the
+ default namespace (`servicesNS/*`) for HTTP requests. This change is a workaround to
+ avoid a bug in Splunk that returns HTTP code 403 when the `server/info` endpoint
is accessed using certain namespaces.
* The `ResultsReaderXml` class can now read search results streams from the
@@ -119,7 +293,7 @@
### New features and APIs
-* Specialized *args* classes have been added to make it easier to pass
+* Specialized *args* classes have been added to make it easier to pass
entity-specific arguments:
- `CollectionArgs`
- `IndexCollectionArgs`
@@ -131,8 +305,8 @@
- `JobSummaryArgs`
- `SavedSearchCollectionArgs`
- `SavedSearchDispatchArgs`
-
- These new *args* classes are used with the following methods:
+
+ These new *args* classes are used with the following methods:
- `Service` constructor
- `Service.getSavedSearches` method
- `Service.getJobs` method
@@ -150,35 +324,35 @@
with older code that expects a `HashMap`. However this new
`Event` object is read-only.
-* Modular input functionality has been implemented (requiring Splunk 5.0+)
+* Modular input functionality has been implemented (requiring Splunk 5.0+)
and the following classes have been added:
- `ModularInputKind`
- `ModularInputKindArgument`
-
+
The `InputCollection` class also now handles arbitrary input kinds represented
by modular inputs. You can call `InputCollection.getInputKinds` to get the set
of `InputKinds` on the connected Splunk instance.
* The `ReceiverBehavior` interface has been added to work with output streams.
-* The `IndexCollection` class has been added as a specialized collection class
+* The `IndexCollection` class has been added as a specialized collection class
for indexes.
* The `JobCollection` class has been added as a specialized collection class for
jobs.
-* You can now programatically remove indexes using the `IndexCollection.remove`
+* You can now programatically remove indexes using the `IndexCollection.remove`
method (requires Splunk 5.0+).
-* You can now send data to an input using the `TcpInputs.attach`,
+* You can now send data to an input using the `TcpInputs.attach`,
`TcpInputs.submit`, and `UdpInput.submit` convenience methods.
* You can now restrict inputs to a specified host using the `setRestrictToHost`
- method on `TcpInput`, `TcpSplunkInput`, and `UdpInput` (this method requires
+ method on `TcpInput`, `TcpSplunkInput`, and `UdpInput` (this method requires
Splunk 5.0+).
-* The `DistributedConfiguration.enable` and `DistributedConfiguration.disable`
- convenience methods have been added, allowing you to immediately enable or
+* The `DistributedConfiguration.enable` and `DistributedConfiguration.disable`
+ convenience methods have been added, allowing you to immediately enable or
disable the configuration.
* The following methods have been added to the `Index` class:
@@ -191,50 +365,50 @@
### Breaking changes
-* The JAR files have changed so that everything is now included in the
- **splunk.jar** file. The **splunk-external.jar** and **splunk-sdk.jar** files
+* The JAR files have changed so that everything is now included in the
+ **splunk.jar** file. The **splunk-external.jar** and **splunk-sdk.jar** files
have been removed.
-* Arguments are now submitted to Splunk in a consistent order, which improves
+* Arguments are now submitted to Splunk in a consistent order, which improves
behavior in certain cases.
-
+
* The `InputKind` enum is now a class. The `InputKind` class has static members
- identical to the enum values, but you can no longer use a `switch` statement
- over the values. Instead, use a series of `if-else` blocks. This change was
+ identical to the enum values, but you can no longer use a `switch` statement
+ over the values. Instead, use a series of `if-else` blocks. This change was
necessary to support arbitrary modular input kinds.
* All text is now consistently UTF-8 encoded. Previously, the platform-native
- encoding was used in certain cases. For example:
- - HTTP requests are sent in UTF-8. In particular the values of *args*
+ encoding was used in certain cases. For example:
+ - HTTP requests are sent in UTF-8. In particular the values of *args*
classes are always encoded in UTF-8.
- Results and events from jobs are read as UTF-8.
-* The `Index.setAssureUTF8` method fails for Splunk 5.0+ because this field has
+* The `Index.setAssureUTF8` method fails for Splunk 5.0+ because this field has
become a global setting rather than a per-index setting.
* The `Index.clean` method now throws `SplunkException.INTERRUPTED` when
- interrupted. Additionally, the `maxSeconds` parameter is obeyed more
+ interrupted. Additionally, the `maxSeconds` parameter is obeyed more
accurately.
-* The `WindowsRegistryInput.getType` and `WindowsRegistryInput.setType` method
+* The `WindowsRegistryInput.getType` and `WindowsRegistryInput.setType` method
type has changed to `String[]` instead of `String`.
-* The `DistributedPeer.getBuild` method now returns an `int` instead of a
+* The `DistributedPeer.getBuild` method now returns an `int` instead of a
`String` to be consistent with the `ServiceInfo.getBuild` method.
* The `setRestrictToHost` method on `TcpInput`, `TcpSplunkInput`, and `UdpInput`
throws an exception for Splunk 4.x. Previously, this method failed silently.
-* The `StormService` class has been removed, but will be restored in a
+* The `StormService` class has been removed, but will be restored in a
subsequent release.
-* The methods in the `ResultsReader` class now throw `IOException` instead of a
+* The methods in the `ResultsReader` class now throw `IOException` instead of a
plain `Exception`, so callers no longer need to handle a plain `Exception`.
* The `SplunkException` class now provides error messages when printed.
-* The test suite has been completely cleaned up, resulting in better coverage
- and faster performance, mostly by eliminating unnecessary restarts. The test
+* The test suite has been completely cleaned up, resulting in better coverage
+ and faster performance, mostly by eliminating unnecessary restarts. The test
suite strictly requires tests to handle restart requests.
* The `get`, `remove`, and `contains` methods for entity collections now throw
@@ -244,7 +418,7 @@
* The `HashMap` and `Event` objects returned by `ResultsReader.getNextEvent` are
now read-only.
-* The `SavedSearch.getDispatchMaxTime` method previously returned a `String`,
+* The `SavedSearch.getDispatchMaxTime` method previously returned a `String`,
but now returns an `int`.
* The `LicensePool.getSlavesUsageBytes` method now returns a map from each slave
@@ -256,7 +430,7 @@
has been removed, because `outputArgs` had no effect.
* The `SavedSearch.setArgsWildcard` method has been removed. To set a wildcard
- parameter, specify it as a key-value pair in a map and pass it to the
+ parameter, specify it as a key-value pair in a map and pass it to the
`SavedSearch.dispatch(java.util.Map args)` method.
* The `SavedSearch.setActionWildcard` method has been removed. Use the specific
@@ -272,42 +446,42 @@
* The `Entity.toUpdate` field is no longer public.
-* The `Service.search(query)` and `Service.search(query, args)` methods now
- return a search job instead of blocking and returning results.
-
+* The `Service.search(query)` and `Service.search(query, args)` methods now
+ return a search job instead of blocking and returning results.
+
* The `Service.search(query, inputArgs, outputArgs)` overload has been removed.
-* The `OutputServer.setsslRootCAPPath` method has been renamed to
+* The `OutputServer.setsslRootCAPPath` method has been renamed to
`setSslRootCAPPath`.
* The `SavedSearch.getDispatchReduceFreq` method, which returned a `String`, has
been replaced with `getDispatchReduceFrequency`, which returns an `int`.
-* The `setRestrictToHost` method has been removed from the `TcpInput` and
+* The `setRestrictToHost` method has been removed from the `TcpInput` and
`UdpInput` classes.
-* The `Settings.setMgmtHostPort` method has been renamed to `setMgmtPort` and
+* The `Settings.setMgmtHostPort` method has been renamed to `setMgmtPort` and
this method now returns an `int`.
### Bug fixes
* The `Service.versionCompare` method has been fixed to work as expected.
-* The `OutputDefault.update` method has been fixed so that when a "name"
- parameter is not specified, the method no longer fails.
+* The `OutputDefault.update` method has been fixed so that when a "name"
+ parameter is not specified, the method no longer fails.
### Deprecated features
The following list contains the main features that have been deprecated (trivial
-changes are not included):
+changes are not included):
-* The public fields in the `ServiceArgs` class have been deprecated in favor of
+* The public fields in the `ServiceArgs` class have been deprecated in favor of
the new setter methods to maintain consistency with the new *args* subclasses.
-* The `Application.isManageable` and `Application.setManageable` methods have
+* The `Application.isManageable` and `Application.setManageable` methods have
been deprecated in Splunk 5.0 and later.
-* The `DistributedConfiguration.getServerTimeout` method has been deprecated in
+* The `DistributedConfiguration.getServerTimeout` method has been deprecated in
Splunk 5.0 and later.
@@ -395,7 +569,7 @@ changes are not included):
* Added a namespacing feature as optional arguments (`app`, `owner`, `sharing`)
to the collection's `create` and `get` methods. For more information about
namespaces, see
- ["Overview of the Splunk SDK for Java"](http://dev.splunk.com/view/java-sdk/SP-CAAAECN)
+ ["Overview of the Splunk Enterprise SDK for Java"](http://dev.splunk.com/view/java-sdk/SP-CAAAECN)
on the Developer Portal.
The following example shows how to use the optional namespace to restrict
@@ -501,4 +675,4 @@ changes are not included):
## Version 0.1.0 (preview)
-Initial Splunk SDK for Java release.
+Initial Splunk Enterprise SDK for Java release.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..26b75753
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,35 @@
+# Contributing Guidelines
+
+## How to contribute
+
+If you would like to contribute to this project, see [Contributions to Splunk](https://www.splunk.com/en_us/form/contributions.html) for more information.
+
+## Issues and bug reports
+
+If you're seeing some unexpected behavior with this project, please create an [issue](https://github.com/splunk/splunk-sdk-java/issues) on GitHub with the following information:
+
+1. Version of this project you're using (ex: 1.4.0)
+2. Platform version (ex: Windows Server 2012)
+3. Framework version (ex: Java 8)
+4. Splunk Enterprise version (ex: 8.0)
+5. Other relevant information (ex: local/remote environment, Splunk network configuration, standalone or distributed deployment, are load balancers used)
+
+Alternatively, if you have a Splunk question please ask on [Splunk Answers](https://community.splunk.com/t5/Splunk-Development/ct-p/developer-tools).
+
+## Pull requests
+
+We love to see pull requests!
+
+To create a pull request:
+
+1. Fill out the [Individual Contributor Agreement](https://www.splunk.com/en_us/form/contributions.html).
+2. Fork the [repository](https://github.com/splunk/splunk-sdk-java).
+3. Make changes to the **develop** branch, preferably with tests.
+4. Create a [pull request](https://github.com/splunk/splunk-sdk-java/pulls) against the **develop** branch.
+
+## Contact us
+
+If you have a paid Splunk Enterprise or Splunk Cloud license, you can contact [Support](https://www.splunk.com/en_us/support-and-services.html) with questions.
+
+You can reach the Splunk Developer Platform team at _devinfo@splunk.com_.
+
diff --git a/CREDITS.md b/CREDITS.md
new file mode 100644
index 00000000..9afabf92
--- /dev/null
+++ b/CREDITS.md
@@ -0,0 +1,12 @@
+# Third-party software credits
+
+Some of the components included in the Splunk Enterprise SDK for Java are licensed under free or open source licenses. We wish to thank the contributors to those projects.
+
+| Contributor | Description | License |
+|:----------- |:----------- |:------- |
+| [opencsv](https://sourceforge.net/p/opencsv/source/ci/master/tree/) | For reading and writing CSV in Java | [Apache](https://github.com/splunk/splunk-sdk-java/blob/master/licenses/LICENSE-OPENCSV) |
+| [commons-cli](https://github.com/apache/commons-cli) | A package of Java utility classes for the classes that are in java.lang's hierarchy | [Apache](https://github.com/splunk/splunk-sdk-java/blob/master/licenses/LICENSE-COMMONS) |
+| [gson](https://github.com/google/gson) | Convert Java Objects into their JSON representation | [Apache](https://github.com/splunk/splunk-sdk-java/blob/master/licenses/LICENSE-GSON) |
+| [junit](https://github.com/junit-team/junit4) | Unit testing framework for Java | [Eclipse](https://github.com/splunk/splunk-sdk-java/blob/master/licenses/LICENSE-JUNIT) |
+| [jacoco](https://github.com/jacoco/jacoco) | JaCoCo runtime agent to your tests and allows basic report creation. | [Eclipse](https://github.com/splunk/splunk-sdk-java/blob/master/licenses/LICENSE-JACOCO) |
+| [netbeans-api](https://github.com/apache/netbeans) | OpenIDE Utilities | [Apache](https://github.com/splunk/splunk-sdk-java/blob/master/licenses/LICENSE-NETBEANS) |
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..123c4cb1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,48 @@
+# text reset
+NO_COLOR=\033[0m
+# green
+OK_COLOR=\033[32;01m
+# red
+ERROR_COLOR=\033[31;01m
+# cyan
+WARN_COLOR=\033[36;01m
+# yellow
+ATTN_COLOR=\033[33;01m
+
+ROOT_DIR := $(shell git rev-parse --show-toplevel)
+
+VERSION := `git describe --tags --dirty 2>/dev/null`
+COMMITHASH := `git rev-parse --short HEAD 2>/dev/null`
+DATE := `date "+%FT%T%z"`
+
+.PHONY: all
+all: init test
+
+init:
+ @echo "$(ATTN_COLOR)==> init $(NO_COLOR)"
+
+.PHONY: test
+test:
+ @echo "$(ATTN_COLOR)==> test $(NO_COLOR)"
+# @ant test
+ @mvn test
+
+.PHONY: test_specific
+test_specific:
+ @echo "$(ATTN_COLOR)==> test_specific $(NO_COLOR)"
+ @sh ./scripts/test_specific.sh
+
+.PHONY: up
+up:
+ @echo "$(ATTN_COLOR)==> up $(NO_COLOR)"
+ @docker-compose up -d
+
+.PHONY: wait_up
+wait_up:
+ @echo "$(ATTN_COLOR)==> wait_up $(NO_COLOR)"
+ @for i in `seq 0 180`; do if docker exec -it splunk /sbin/checkstate.sh &> /dev/null; then break; fi; printf "\rWaiting for Splunk for %s seconds..." $$i; sleep 1; done
+
+.PHONY: down
+down:
+ @echo "$(ATTN_COLOR)==> down $(NO_COLOR)"
+ @docker-compose stop
diff --git a/README.md b/README.md
index e1a8b2e4..8c63c07f 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,35 @@
+[](https://github.com/splunk/splunk-sdk-java/actions/workflows/test.yml)
# The Splunk Software Development Kit for Java
-#### Version 1.3.2
+#### Version 1.9.5
-The Splunk Software Development Kit (SDK) for Java contains library code and
+The Splunk Software Development Kit (SDK) for Java contains library code and
examples designed to enable developers to build applications using Splunk.
Splunk is a search engine and analytic environment that uses a distributed
-map-reduce architecture to efficiently index, search and process large
+map-reduce architecture to efficiently index, search and process large
time-varying data sets.
The Splunk product is popular with system administrators for aggregation and
-monitoring of IT machine data, security, compliance and a wide variety of
+monitoring of IT machine data, security, compliance and a wide variety of
other scenarios that share a requirement to efficiently index, search, analyze
and generate real-time notifications from large volumes of time series data.
-The Splunk developer platform enables developers to take advantage of the
+The Splunk developer platform enables developers to take advantage of the
same technology used by the Splunk product to build exciting new applications
that are enabled by Splunk's unique capabilities.
## Getting started with the Splunk SDK for Java
-The Splunk SDK for Java contains library code and examples that show how to
-programmatically interact with Splunk for a variety of scenarios including
-searching, saved searches, data inputs, and many more, along with building
-complete applications.
+The Splunk SDK for Java contains library code and examples that show how to
+programmatically interact with Splunk for a variety of scenarios including
+searching, saved searches, data inputs, and many more, along with building
+complete applications.
The information in this Readme provides steps to get going quickly, but for more
-in-depth information be sure to visit the
-[Splunk Developer Portal](http://dev.splunk.com/view/java-sdk/SP-CAAAECN).
+in-depth information be sure to visit the
+[Splunk Developer Portal](http://dev.splunk.com/view/java-sdk/SP-CAAAECN).
### Requirements
@@ -36,10 +37,10 @@ Here's what you need to get going with the Splunk SDK for Java.
#### Splunk
-If you haven't already installed Splunk, download it
-[here](http://www.splunk.com/download). For more about installing and running
-Splunk and system requirements, see
-[Installing & Running Splunk](http://dev.splunk.com/view/SP-CAAADRV).
+If you haven't already installed Splunk, download it
+[here](http://www.splunk.com/download). For more about installing and running
+Splunk and system requirements, see
+[Installing & Running Splunk](http://dev.splunk.com/view/SP-CAAADRV). The Splunk SDK for Java has been tested with Splunk Enterprise 9.0 and 8.2.
#### Splunk SDK for Java
@@ -47,66 +48,234 @@ Splunk and system requirements, see
If you want to contribute to the SDK, clone the repository from [GitHub](https://github.com/splunk/splunk-sdk-java).
+#### Java using Maven
-#### Java and Ant
+You can use [Apache Maven](http://maven.apache.org/) to build your Splunk SDK for Java projects. With a few updates to your project's `pom.xml` file, it will retrieve all necessary dependencies and seamlessly build your project.
-You'll need Java SE version 6 or higher, which you can download from the
-[Oracle web site](http://www.oracle.com/technetwork/java/javase/downloads/index.html).
+To add the Splunk SDK for Java `.JAR` file as a dependency:
-You'll also need Ant, which you can install from the
-[Apache website](http://ant.apache.org/bindownload.cgi).
+1. Add the repository to your project's `pom.xml` file:
-If you are using Windows, you'll need to make sure the following system
-variables are created and set:
+```xml
+
+ ...
+
+ splunk-artifactory
+ Splunk Releases
+ http://splunk.jfrog.io/splunk/ext-releases-local
+
+
+```
-* **ANT_HOME** should be set to the location where Ant is installed.
+2. Add the dependency to the `pom.xml` file:
-* **JAVA_HOME** should be set to the directory where the JDK is installed.
+```xml
+
+ ...
+
+ com.splunk
+ splunk
+ 1.9.5
+
+
+```
-* **PATH** should include the path to the **%ANT_HOME%\bin** directory.
+Be sure to update the version number to match the version of the Splunk SDK for Java that you are using.
-For full installation instructions, you can find more information here:
-
-* [Java Platform Installation](http://www.oracle.com/technetwork/java/javase/index-137561.html)
-
-* [Installing Apache Ant](http://ant.apache.org/manual/install.html)
+> Note: You can make similar changes to use [Gradle](http://www.gradle.org/) as well.
### Building the SDK and documentation
-To build the SDK, open a command prompt in the **/splunk-sdk-java**
-directory and enter:
+To build the SDK, open a command prompt in the **/splunk-sdk-java**
+directory and enter:
- ant
+ mvn
or
- ant dist
+ mvn package
This command builds all of the .class and .jar files. If you just want to build
the .class files, enter:
- ant build
+ mvn compile
To remove all build artifacts from the repository, enter:
- ant clean
-
-To build the documentation for the SDK, enter:
-
- ant javadoc
-
-### Examples and unit tests
-
-The Splunk SDK for Java includes several examples and unit tests that are run at
-the command line.
+ mvn clean
+
+To build the documentation for the SDK, it is being automatically generated with mvn package, otherwise enter:
+
+ cd splunk
+ mvn javadoc:javadoc
+
+### Usage
+#### Login using username and password
+```java
+import com.splunk.Service;
+import com.splunk.ServiceArgs;
+
+/**
+ * Login using username and password
+ */
+public class SplunkLogin {
+
+ static Service service = null;
+ public static void main(String args[]) {
+ ServiceArgs loginArgs = new ServiceArgs();
+ loginArgs.setPort(8089);
+ loginArgs.setHost("localhost");
+ loginArgs.setScheme("https");
+ loginArgs.setUsername("USERNAME"); // Use your username
+ loginArgs.setPassword("PASSWORD"); // Use your password
+
+ // Initialize the SDK client
+ service = Service.connect(loginArgs);
+ }
+}
+```
+
+#### Login using Session Token
+```java
+import com.splunk.Service;
+import com.splunk.ServiceArgs;
+
+/**
+ * Login using Session token
+ */
+public class SplunkLogin {
+
+ static Service service = null;
+ /**
+ * Session Token.
+ * Actual token length would be longer than this token length.
+ */
+ static String token = "1k_Ostpl6NBe4iVQ5d6I3Ohla_U5";
+
+ public static void main(String args[]) {
+ ServiceArgs loginArgs = new ServiceArgs();
+ loginArgs.setPort(8089);
+ loginArgs.setHost("localhost");
+ loginArgs.setScheme("https");
+ loginArgs.setToken(String.format("Splunk %s", token));
+
+ // Initialize the SDK client
+ service = Service.connect(loginArgs);
+ }
+}
+```
+* Login using username and password will create Session token internally.
+* Login using Credentials (username & password) OR directly using Session token are similar.
+* In above two approaches, there is one limitation that expiration time of Session token cannot be extended. User has to re-login every time when token expires.
+* To overcome this limitation, **Authentication** token is used instead of Session token.
+* In **Authentication** token, user has a provision to set token expiration time. Splunk allows user to set relative/absolute time for token expiration.
+* In other words, **Authentication** token is configurable whereas Session token cannot be configured.
+
+#### Login using Authentication Token (RECOMMENDED)
+```java
+import com.splunk.Service;
+import com.splunk.ServiceArgs;
+
+/**
+ * Login using Authentication token
+ */
+public class SplunkLogin {
+
+ static Service service = null;
+ /**
+ * Authentication Token.
+ * Actual token length would be longer than this token length.
+ */
+ static String token = "1k_Ostpl6NBe4iVQ5d6I3Ohla_U5";
+
+ public static void main(String args[]) {
+ ServiceArgs loginArgs = new ServiceArgs();
+ loginArgs.setPort(8089);
+ loginArgs.setHost("localhost");
+ loginArgs.setScheme("https");
+ loginArgs.setToken(String.format("Bearer %s", token));
+
+ // Initialize the SDK client
+ service = Service.connect(loginArgs);
+ }
+}
+```
+
+#### Example of running a simple search by first creating the search job
+```java
+import com.splunk.Job;
+import com.splunk.ResultsReader;
+import com.splunk.ResultsReaderXml;
+import com.splunk.Service;
+import com.splunk.ServiceArgs;
+
+/**
+ * Logged in using Authentication token.
+ * Assuming that authentication token is already created from Splunk web.
+ * Create Job using search creation.
+ * Read results and print _raw fields
+ */
+public class SearchExample {
+
+ static Service service = null;
+
+ /**
+ * Authentication Token.
+ * Actual token length would be longer than this token length.
+ */
+ static String token = "1k_Ostpl6NBe4iVQ5d6I3Ohla_U5";
+
+ public static void main(String args[]) {
+
+ ServiceArgs loginArgs = new ServiceArgs();
+ loginArgs.setPort(8089);
+ loginArgs.setHost("localhost");
+ loginArgs.setScheme("https");
+ loginArgs.setToken(String.format("Bearer %s", token));
+
+ // Initialize the SDK client
+ service = Service.connect(loginArgs);
+
+ // Run a simple search by first creating the search job
+ Job job = service.getJobs().create("search index=_internal | head 10");
+
+ // Waiting for search results to be ready
+ while (!job.isReady()) {
+ try {
+ Thread.sleep(500); // 500 ms
+ } catch (Exception e) {
+ // Handle exception here.
+ }
+ }
+
+ // Read results
+ try {
+ ResultsReader reader = new ResultsReaderXml(job.getEvents());
+
+ // Iterate over events and print _raw field
+ reader.forEach(event -> System.out.println(event.get("_raw")));
+
+ } catch (Exception e) {
+ // Handle exception here.
+ }
+ }
+}
+```
+
+For more information on authentication using tokens, please visit [Splunk Docs](https://docs.splunk.com/Documentation/Splunk/latest/Security/Setupauthenticationwithtokens).
+
+### Unit tests
+
+The Splunk SDK for Java includes several unit tests that are run at
+the command line.
#### Set up the .splunkrc file
To connect to Splunk, many of the SDK examples and unit tests take command-line
arguments that specify values for the host, port, and login credentials for
Splunk. For convenience during development, you can store these arguments as
-key-value pairs in a text file named **.splunkrc**. Then, the SDK examples and
-unit tests use the values from the **.splunkrc** file when you don't specify
+key-value pairs in a text file named **.splunkrc**. Then, the SDK examples and
+unit tests use the values from the **.splunkrc** file when you don't specify
them.
To use this convenience file, create a text file with the following format:
@@ -126,148 +295,91 @@ To use this convenience file, create a text file with the following format:
Save the file as **.splunkrc** in the current user's home directory.
-* For example, on Mac OS X, save the file as:
+* For example, on Mac OS X, save the file as:
~/.splunkrc
-* On Windows, save the file as:
+* On Windows, save the file as:
C:\Users\currentusername\.splunkrc
You might get errors in Windows when you try to name the file because
".splunkrc" looks like a nameless file with an extension. You can use
- the command line to create this file—go to the
- **C:\Users\currentusername** directory and enter the following command:
+ the command line to create this file—go to the
+ **C:\Users\currentusername** directory and enter the following command:
Notepad.exe .splunkrc
Click **Yes**, then continue creating the file.
-**Note**: Storing login credentials in the **.splunkrc** file is only for
-convenience during development. This file isn't part of the Splunk platform and
-shouldn't be used for storing user credentials for production. And, if you're
-at all concerned about the security of your credentials, just enter them at
-the command line rather than saving them in this file.
-
-
-#### Run examples
-
-After you build the SDK, examples are put in the **/splunk-sdk-
-java/dist/examples** directory. To run the examples, run the Java interpreter
-at the command line using the `-jar` flag to specify the target example jar
-file, and include any arguments that are required by the example. To get help
-for an example, use the `--help` argument with an example.
-
-For example, to see the command-line arguments for the Search example, open a
-command prompt in the **/splunk-sdk-java** directory and enter:
-
- java -jar dist/examples/search.jar --help
-
-To run the Search example, open a command prompt in the **/splunk-sdk-java**
-directory and enter:
-
- java -jar dist/examples/search.jar "search * | head 10" --output_mode=csv
-
-There is also a helper script called run in the root of the repository that
-simplifies running the SDK examples. For example, on Mac OS X you could
-simply enter:
-
- ./run search "search * | head 10" --output_mode=csv
-
-All the the example jars are completely self contained. They can be used
-completely independently of the SDK's repository.
+**Note**: Storing login credentials in the **.splunkrc** file is only for
+convenience during development. This file isn't part of the Splunk platform and
+shouldn't be used for storing user credentials for production. And, if you're
+at all concerned about the security of your credentials, just enter them at
+the command line rather than saving them in this file.
#### Run unit tests
-To run the SDK unit tests, open a command prompt in the **/splunk-sdk-java**
-directory and enter:
+To run the SDK unit tests, open a command prompt in the **/splunk-sdk-java**
+directory and enter:
- ant test
+ mvn test
-To run the units from anywhere in the repository, enter:
-
- ant test -find
-
-You can also run specific test classes by passing the class to the -Dtestcase=
+You can also run specific test classes by passing the class to the -Dtest=
option, e.g.,
- ant test -Dtestcase=AtomFeedTest
+ mvn test -Dtest=AtomFeedTest
-The ant configuration can also produce a single HTML report of all the tests run
-using the target testreport (which also understands the -Dtestcase= option), e.g.
+The maven configuration can also produce an HTML report of all the tests automatically when **mvn package / mvn test** are executed.
+Alternate way to generate report is using below command under splunk directory:
- ant testreport
+ mvn jacoco:report
-The report will be written in build/reports/tests/index.html.
+The report will be written in **/splunk-sdk-java/splunk/target/site/surefire-report.html**.
-It's also possible to run the units within Java IDEs such as IntelliJ and
-Eclipse. For example, to open the Splunk SDK for Java project in Eclipse:
+It's also possible to run the units within Java IDEs such as IntelliJ and
+Eclipse. For example, to open the Splunk SDK for Java project in Eclipse:
- 1. Click **File**, **Import**.
- 2. Click **General**, **Existing Projects into Workspace**, then click
- **Next**.
- 3. In **Select root directory**, type the path to the Splunk SDK for Java root
- directory (or click **Browse** to locate it), then click **Finish**.
+1. Click **File**, **Import**.
+2. Click **General**, **Existing Projects into Workspace**, then click
+ **Next**.
+3. In **Select root directory**, type the path to the Splunk SDK for Java root
+ directory (or click **Browse** to locate it), then click **Finish**.
#### Measure code coverage
-To measure the code coverage of the test suite, open a
-command prompt in the **/splunk-sdk-java** directory and enter:
-
- ant coverage
-
-To run code coverage from anywhere in the repository, enter:
+Measurement of code coverage is generated along with mvn package / mvn test:
- ant coverage -find
+ mvn jacoco:report
-To view the coverage report, open
-**/splunk-sdk-java/build/reports/coverage/index.html** in your web browser.
+To view the coverage report, open
+**/splunk-sdk-java/splunk/target/test-report/index.html** in your web browser.
## Repository
/argsGenerator
-
This directory is created by the build and contains intermediate build
+
This directory is created by the build and contains intermediate build
ouputs
-
/build
-
This directory is created by the build and contains intermediate build
+
/splunk/target
+
This directory is created by the build and contains intermediate build
ouputs
-
/dist
-
This directory is created by the build and contains final build
-outputs
-
-
-
-
/examples
-
Examples demonstrating various SDK features
-
-
-
-
/lib
-
Third-party libraries used by examples and unit tests
-
-
-
-
/splunk
+
/splunk/src/main
Source for com.splunk
-
/tests
+
/splunk/src/test
Source for unit tests
-
-
/util
-
Utilities shared by examples and units
-
### Changelog
@@ -279,12 +391,12 @@ of changes for each version of the SDK. You can also find it online at
### Branches
The **master** branch always represents a stable and released version of the SDK.
-You can read more about our branching model on our Wiki at
+You can read more about our branching model on our Wiki at
[https://github.com/splunk/splunk-sdk-java/wiki/Branching-Model](https://github.com/splunk/splunk-sdk-java/wiki/Branching-Model).
## Documentation and resources
-If you need to know more:
+If you need to know more:
* For all things developer with Splunk, your main resource is the [Splunk Developer Portal](http://dev.splunk.com).
@@ -344,24 +456,24 @@ If you would like to contribute to the SDK, go here for more information:
### Support
-1. You will be granted support if you or your company are already covered
- under an existing maintenance/support agreement. Send an email to
- _support@splunk.com_ and include "Splunk SDK for Java" in the subject line.
+1. You will be granted support if you or your company are already covered
+ under an existing maintenance/support agreement. Send an email to
+ _support@splunk.com_ and include "Splunk SDK for Java" in the subject line.
-2. If you are not covered under an existing maintenance/support agreement, you
+2. If you are not covered under an existing maintenance/support agreement, you
can find help through the broader community at:
Splunk Answers (use
- the sdk, java, python, and javascript tags to
+ the sdk, java, python, and javascript tags to
identify your questions)
-3. Splunk will NOT provide support for SDKs if the core library (the
+3. Splunk will NOT provide support for SDKs if the core library (the
code in the splunk directory) has been modified. If you modify an SDK
- and want support, you can find help through the broader community and Splunk
- answers (see above). We would also like to know why you modified the core
+ and want support, you can find help through the broader community and Splunk
+ answers (see above). We would also like to know why you modified the core
library—please send feedback to _devinfo@splunk.com_.
4. File any issues on [GitHub](https://github.com/splunk/splunk-sdk-java/issues).
diff --git a/build.xml b/build.xml
deleted file mode 100644
index b56565f5..00000000
--- a/build.xml
+++ /dev/null
@@ -1,413 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deploy b/deploy
index 0b8880ec..ab8acd24 100755
--- a/deploy
+++ b/deploy
@@ -2,7 +2,7 @@
declare -r scriptDirectory="$(dirname $(readlink -e $0))"
declare -r scriptName="$(basename $0)"
-declare -r version="1.3.2"
+declare -r version="1.9.5"
if [[ $# -ne 1 ]]; then
echo 1>&2 "Usage: ${scriptName} {local|staging||production}"
diff --git a/deploy.md b/deploy.md
index bc37dc08..aed545f5 100644
--- a/deploy.md
+++ b/deploy.md
@@ -1,6 +1,6 @@
##NAME
-deploy - Transmit splunk-sdk-java artifacts to the local, staging or production
+deploy - Transmit splunk-sdk-java artifacts to the local, staging or production
maven artifact repository
##SYNOPSIS
@@ -9,30 +9,30 @@ deploy \
##DESCRIPTION
-Deploy transmits **dist/splunk-1.3.2.jar**, **dist/splunk-1.3.2-javadoc.jar**, and
-**dist/splunk-1.3.2-sources.jar** to the **local**, **staging**, or **production**
+Deploy transmits **target/splunk-1.9.5.jar**, **target/splunk-1.9.5-javadoc.jar**, and
+**target/splunk-1.9.5-sources.jar** to the **local**, **staging**, or **production**
maven repository. Repository names are mapped to locations as follows.
| repository-name | location |
|-----------------|----------------------------------------------------------------|
| local | file:///${HOME}/.m2/repository/ |
| staging | http://stg-artifactory:8081/artifactory/devplat-staging/ | |
-| production | http://splunk.artifactoryonline.com/splunk/ext-releases-local/ |
+| production | https://splunk.jfrog.io/artifactory/ext-releases-local/ |
After deployment you should find this tree structure at the location of your repository
- com/splunk/splunk/1.3.2/
- ├── splunk-1.3.2-javadoc.jar
- ├── splunk-1.3.2-javadoc.jar.md5
- ├── splunk-1.3.2-javadoc.jar.sha1
- ├── splunk-1.3.2-sources.jar
- ├── splunk-1.3.2-sources.jar.md5
- ├── splunk-1.3.2-sources.jar.sha1
- ├── splunk-1.3.2.jar
- ├── splunk-1.3.2.jar.md5
- ├── splunk-1.3.2.jar.sha1
- ├── splunk-1.3.2.pom
- ├── splunk-1.3.2.pom.md5
- └── splunk-1.3.2.pom.sha1
+ com/splunk/splunk/1.9.5/
+ ├── splunk-1.9.5-javadoc.jar
+ ├── splunk-1.9.5-javadoc.jar.md5
+ ├── splunk-1.9.5-javadoc.jar.sha1
+ ├── splunk-1.9.5-sources.jar
+ ├── splunk-1.9.5-sources.jar.md5
+ ├── splunk-1.9.5-sources.jar.sha1
+ ├── splunk-1.9.5.jar
+ ├── splunk-1.9.5.jar.md5
+ ├── splunk-1.9.5.jar.sha1
+ ├── splunk-1.9.5.pom
+ ├── splunk-1.9.5.pom.md5
+ └── splunk-1.9.5.pom.sha1
Verify this structure prior to release.
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..4584c6d3
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,23 @@
+version: '3.6'
+
+services:
+ splunk:
+ image: "splunk/splunk:latest"
+ container_name: splunk
+ environment:
+ - SPLUNK_START_ARGS=--accept-license
+ - SPLUNK_HEC_TOKEN=11111111-1111-1111-1111-1111111111113
+ - SPLUNK_PASSWORD=changed!
+ - SPLUNK_APPS_URL=https://github.com/splunk/sdk-app-collection/releases/download/v1.1.0/sdkappcollection.tgz
+ - JAVA_VERSION=openjdk:8
+ ports:
+ - 8000:8000
+ - 8088:8088
+ - 8089:8089
+ - 10667:10667
+ - 10668:10668/udp
+ healthcheck:
+ test: ['CMD', 'curl', '-f', 'http://localhost:8000']
+ interval: 5s
+ timeout: 5s
+ retries: 20
diff --git a/examples/pom.xml b/examples/pom.xml
new file mode 100644
index 00000000..18bbb711
--- /dev/null
+++ b/examples/pom.xml
@@ -0,0 +1,120 @@
+
+
+ 4.0.0
+
+ examples
+
+ splunk-sdk-java
+ com.splunk
+ 1.0.1
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.0.0-M1
+
+ true
+
+
+
+
+
+
+
+ com.splunk
+ splunk
+ 1.9.5
+ provided
+
+
+ org.netbeans.api
+ org-openide-util-lookup
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-util
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-filesystems
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-awt
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-dialogs
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-nodes
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-explorer
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-execution
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-modules
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-windows
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-text
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-options
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-loaders
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-io
+ RELEASE124
+
+
+ org.netbeans.api
+ org-openide-actions
+ RELEASE124
+
+
+
+
diff --git a/examples/com/splunk/examples/endpoint_instantiation/Program.java b/examples/src/main/java/com/splunk/examples/endpoint_instantiation/Program.java
similarity index 100%
rename from examples/com/splunk/examples/endpoint_instantiation/Program.java
rename to examples/src/main/java/com/splunk/examples/endpoint_instantiation/Program.java
diff --git a/examples/com/splunk/examples/explorer/AppNode.java b/examples/src/main/java/com/splunk/examples/explorer/AppNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/AppNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/AppNode.java
diff --git a/examples/com/splunk/examples/explorer/ConfCollectionKids.java b/examples/src/main/java/com/splunk/examples/explorer/ConfCollectionKids.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/ConfCollectionKids.java
rename to examples/src/main/java/com/splunk/examples/explorer/ConfCollectionKids.java
diff --git a/examples/com/splunk/examples/explorer/ConfCollectionNode.java b/examples/src/main/java/com/splunk/examples/explorer/ConfCollectionNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/ConfCollectionNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/ConfCollectionNode.java
diff --git a/examples/com/splunk/examples/explorer/DatePropertyEditor.java b/examples/src/main/java/com/splunk/examples/explorer/DatePropertyEditor.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/DatePropertyEditor.java
rename to examples/src/main/java/com/splunk/examples/explorer/DatePropertyEditor.java
diff --git a/examples/com/splunk/examples/explorer/DeploymentClientNode.java b/examples/src/main/java/com/splunk/examples/explorer/DeploymentClientNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/DeploymentClientNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/DeploymentClientNode.java
diff --git a/examples/com/splunk/examples/explorer/DeploymentServerClassNode.java b/examples/src/main/java/com/splunk/examples/explorer/DeploymentServerClassNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/DeploymentServerClassNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/DeploymentServerClassNode.java
diff --git a/examples/com/splunk/examples/explorer/DeploymentServerNode.java b/examples/src/main/java/com/splunk/examples/explorer/DeploymentServerNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/DeploymentServerNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/DeploymentServerNode.java
diff --git a/examples/com/splunk/examples/explorer/DeploymentTenantNode.java b/examples/src/main/java/com/splunk/examples/explorer/DeploymentTenantNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/DeploymentTenantNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/DeploymentTenantNode.java
diff --git a/examples/com/splunk/examples/explorer/DistributedConfigurationNode.java b/examples/src/main/java/com/splunk/examples/explorer/DistributedConfigurationNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/DistributedConfigurationNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/DistributedConfigurationNode.java
diff --git a/examples/com/splunk/examples/explorer/DistributedPeerNode.java b/examples/src/main/java/com/splunk/examples/explorer/DistributedPeerNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/DistributedPeerNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/DistributedPeerNode.java
diff --git a/examples/com/splunk/examples/explorer/EntityCollectionNode.java b/examples/src/main/java/com/splunk/examples/explorer/EntityCollectionNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/EntityCollectionNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/EntityCollectionNode.java
diff --git a/examples/com/splunk/examples/explorer/EntityComparator.java b/examples/src/main/java/com/splunk/examples/explorer/EntityComparator.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/EntityComparator.java
rename to examples/src/main/java/com/splunk/examples/explorer/EntityComparator.java
diff --git a/examples/com/splunk/examples/explorer/EntityKids.java b/examples/src/main/java/com/splunk/examples/explorer/EntityKids.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/EntityKids.java
rename to examples/src/main/java/com/splunk/examples/explorer/EntityKids.java
diff --git a/examples/com/splunk/examples/explorer/EntityMetadataNode.java b/examples/src/main/java/com/splunk/examples/explorer/EntityMetadataNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/EntityMetadataNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/EntityMetadataNode.java
diff --git a/examples/com/splunk/examples/explorer/EntityNode.java b/examples/src/main/java/com/splunk/examples/explorer/EntityNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/EntityNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/EntityNode.java
diff --git a/examples/com/splunk/examples/explorer/EventTypeNode.java b/examples/src/main/java/com/splunk/examples/explorer/EventTypeNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/EventTypeNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/EventTypeNode.java
diff --git a/examples/com/splunk/examples/explorer/Explorer.java b/examples/src/main/java/com/splunk/examples/explorer/Explorer.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/Explorer.java
rename to examples/src/main/java/com/splunk/examples/explorer/Explorer.java
diff --git a/examples/com/splunk/examples/explorer/ExplorerNode.java b/examples/src/main/java/com/splunk/examples/explorer/ExplorerNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/ExplorerNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/ExplorerNode.java
diff --git a/examples/com/splunk/examples/explorer/GroupNode.java b/examples/src/main/java/com/splunk/examples/explorer/GroupNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/GroupNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/GroupNode.java
diff --git a/examples/com/splunk/examples/explorer/IndexNode.java b/examples/src/main/java/com/splunk/examples/explorer/IndexNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/IndexNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/IndexNode.java
diff --git a/examples/com/splunk/examples/explorer/InputKindPropertyEditor.java b/examples/src/main/java/com/splunk/examples/explorer/InputKindPropertyEditor.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/InputKindPropertyEditor.java
rename to examples/src/main/java/com/splunk/examples/explorer/InputKindPropertyEditor.java
diff --git a/examples/com/splunk/examples/explorer/InputNode.java b/examples/src/main/java/com/splunk/examples/explorer/InputNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/InputNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/InputNode.java
diff --git a/examples/com/splunk/examples/explorer/JobNode.java b/examples/src/main/java/com/splunk/examples/explorer/JobNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/JobNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/JobNode.java
diff --git a/examples/com/splunk/examples/explorer/LicenseGroupNode.java b/examples/src/main/java/com/splunk/examples/explorer/LicenseGroupNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/LicenseGroupNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/LicenseGroupNode.java
diff --git a/examples/com/splunk/examples/explorer/LicenseNode.java b/examples/src/main/java/com/splunk/examples/explorer/LicenseNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/LicenseNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/LicenseNode.java
diff --git a/examples/com/splunk/examples/explorer/LicensePoolNode.java b/examples/src/main/java/com/splunk/examples/explorer/LicensePoolNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/LicensePoolNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/LicensePoolNode.java
diff --git a/examples/com/splunk/examples/explorer/LicenseSlaveNode.java b/examples/src/main/java/com/splunk/examples/explorer/LicenseSlaveNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/LicenseSlaveNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/LicenseSlaveNode.java
diff --git a/examples/com/splunk/examples/explorer/LicenseStackNode.java b/examples/src/main/java/com/splunk/examples/explorer/LicenseStackNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/LicenseStackNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/LicenseStackNode.java
diff --git a/examples/com/splunk/examples/explorer/LoggerNode.java b/examples/src/main/java/com/splunk/examples/explorer/LoggerNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/LoggerNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/LoggerNode.java
diff --git a/examples/com/splunk/examples/explorer/MapPropertyEditor.java b/examples/src/main/java/com/splunk/examples/explorer/MapPropertyEditor.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/MapPropertyEditor.java
rename to examples/src/main/java/com/splunk/examples/explorer/MapPropertyEditor.java
diff --git a/examples/com/splunk/examples/explorer/MessageNode.java b/examples/src/main/java/com/splunk/examples/explorer/MessageNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/MessageNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/MessageNode.java
diff --git a/examples/com/splunk/examples/explorer/NamespaceKids.java b/examples/src/main/java/com/splunk/examples/explorer/NamespaceKids.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/NamespaceKids.java
rename to examples/src/main/java/com/splunk/examples/explorer/NamespaceKids.java
diff --git a/examples/com/splunk/examples/explorer/NamespacesKids.java b/examples/src/main/java/com/splunk/examples/explorer/NamespacesKids.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/NamespacesKids.java
rename to examples/src/main/java/com/splunk/examples/explorer/NamespacesKids.java
diff --git a/examples/com/splunk/examples/explorer/NamespacesNode.java b/examples/src/main/java/com/splunk/examples/explorer/NamespacesNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/NamespacesNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/NamespacesNode.java
diff --git a/examples/com/splunk/examples/explorer/OutputDefaultNode.java b/examples/src/main/java/com/splunk/examples/explorer/OutputDefaultNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/OutputDefaultNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/OutputDefaultNode.java
diff --git a/examples/com/splunk/examples/explorer/OutputGroupNode.java b/examples/src/main/java/com/splunk/examples/explorer/OutputGroupNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/OutputGroupNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/OutputGroupNode.java
diff --git a/examples/com/splunk/examples/explorer/OutputServerNode.java b/examples/src/main/java/com/splunk/examples/explorer/OutputServerNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/OutputServerNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/OutputServerNode.java
diff --git a/examples/com/splunk/examples/explorer/OutputSyslogNode.java b/examples/src/main/java/com/splunk/examples/explorer/OutputSyslogNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/OutputSyslogNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/OutputSyslogNode.java
diff --git a/examples/com/splunk/examples/explorer/PasswordNode.java b/examples/src/main/java/com/splunk/examples/explorer/PasswordNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/PasswordNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/PasswordNode.java
diff --git a/examples/com/splunk/examples/explorer/Program.java b/examples/src/main/java/com/splunk/examples/explorer/Program.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/Program.java
rename to examples/src/main/java/com/splunk/examples/explorer/Program.java
diff --git a/examples/com/splunk/examples/explorer/PropertyInfo.java b/examples/src/main/java/com/splunk/examples/explorer/PropertyInfo.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/PropertyInfo.java
rename to examples/src/main/java/com/splunk/examples/explorer/PropertyInfo.java
diff --git a/examples/com/splunk/examples/explorer/PropertyList.java b/examples/src/main/java/com/splunk/examples/explorer/PropertyList.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/PropertyList.java
rename to examples/src/main/java/com/splunk/examples/explorer/PropertyList.java
diff --git a/examples/com/splunk/examples/explorer/ResourceNode.java b/examples/src/main/java/com/splunk/examples/explorer/ResourceNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/ResourceNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/ResourceNode.java
diff --git a/examples/com/splunk/examples/explorer/RoleNode.java b/examples/src/main/java/com/splunk/examples/explorer/RoleNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/RoleNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/RoleNode.java
diff --git a/examples/com/splunk/examples/explorer/SavedSearchNode.java b/examples/src/main/java/com/splunk/examples/explorer/SavedSearchNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/SavedSearchNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/SavedSearchNode.java
diff --git a/examples/com/splunk/examples/explorer/ServiceKids.java b/examples/src/main/java/com/splunk/examples/explorer/ServiceKids.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/ServiceKids.java
rename to examples/src/main/java/com/splunk/examples/explorer/ServiceKids.java
diff --git a/examples/com/splunk/examples/explorer/ServiceNode.java b/examples/src/main/java/com/splunk/examples/explorer/ServiceNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/ServiceNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/ServiceNode.java
diff --git a/examples/com/splunk/examples/explorer/SettingsNode.java b/examples/src/main/java/com/splunk/examples/explorer/SettingsNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/SettingsNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/SettingsNode.java
diff --git a/examples/com/splunk/examples/explorer/StanzaNode.java b/examples/src/main/java/com/splunk/examples/explorer/StanzaNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/StanzaNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/StanzaNode.java
diff --git a/examples/com/splunk/examples/explorer/StringArrayPropertyEditor.java b/examples/src/main/java/com/splunk/examples/explorer/StringArrayPropertyEditor.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/StringArrayPropertyEditor.java
rename to examples/src/main/java/com/splunk/examples/explorer/StringArrayPropertyEditor.java
diff --git a/examples/com/splunk/examples/explorer/UserNode.java b/examples/src/main/java/com/splunk/examples/explorer/UserNode.java
similarity index 100%
rename from examples/com/splunk/examples/explorer/UserNode.java
rename to examples/src/main/java/com/splunk/examples/explorer/UserNode.java
diff --git a/examples/com/splunk/examples/export/Program.java b/examples/src/main/java/com/splunk/examples/export/Program.java
similarity index 100%
rename from examples/com/splunk/examples/export/Program.java
rename to examples/src/main/java/com/splunk/examples/export/Program.java
diff --git a/examples/com/splunk/examples/fluent_pivot/Program.java b/examples/src/main/java/com/splunk/examples/fluent_pivot/Program.java
similarity index 100%
rename from examples/com/splunk/examples/fluent_pivot/Program.java
rename to examples/src/main/java/com/splunk/examples/fluent_pivot/Program.java
diff --git a/examples/com/splunk/examples/genevents/Program.java b/examples/src/main/java/com/splunk/examples/genevents/Program.java
similarity index 100%
rename from examples/com/splunk/examples/genevents/Program.java
rename to examples/src/main/java/com/splunk/examples/genevents/Program.java
diff --git a/examples/com/splunk/examples/get_job/Program.java b/examples/src/main/java/com/splunk/examples/get_job/Program.java
similarity index 100%
rename from examples/com/splunk/examples/get_job/Program.java
rename to examples/src/main/java/com/splunk/examples/get_job/Program.java
diff --git a/examples/com/splunk/examples/index/Program.java b/examples/src/main/java/com/splunk/examples/index/Program.java
similarity index 100%
rename from examples/com/splunk/examples/index/Program.java
rename to examples/src/main/java/com/splunk/examples/index/Program.java
diff --git a/examples/com/splunk/examples/info/Program.java b/examples/src/main/java/com/splunk/examples/info/Program.java
similarity index 100%
rename from examples/com/splunk/examples/info/Program.java
rename to examples/src/main/java/com/splunk/examples/info/Program.java
diff --git a/examples/com/splunk/examples/input/Program.java b/examples/src/main/java/com/splunk/examples/input/Program.java
similarity index 100%
rename from examples/com/splunk/examples/input/Program.java
rename to examples/src/main/java/com/splunk/examples/input/Program.java
diff --git a/examples/com/splunk/examples/pivot/Program.java b/examples/src/main/java/com/splunk/examples/pivot/Program.java
similarity index 100%
rename from examples/com/splunk/examples/pivot/Program.java
rename to examples/src/main/java/com/splunk/examples/pivot/Program.java
diff --git a/examples/com/splunk/examples/random_numbers/Program.java b/examples/src/main/java/com/splunk/examples/random_numbers/Program.java
similarity index 100%
rename from examples/com/splunk/examples/random_numbers/Program.java
rename to examples/src/main/java/com/splunk/examples/random_numbers/Program.java
diff --git a/examples/com/splunk/examples/random_numbers/random_numbers/README/inputs.conf.spec b/examples/src/main/java/com/splunk/examples/random_numbers/random_numbers/README/inputs.conf.spec
similarity index 100%
rename from examples/com/splunk/examples/random_numbers/random_numbers/README/inputs.conf.spec
rename to examples/src/main/java/com/splunk/examples/random_numbers/random_numbers/README/inputs.conf.spec
diff --git a/examples/com/splunk/examples/random_numbers/random_numbers/default/app.conf b/examples/src/main/java/com/splunk/examples/random_numbers/random_numbers/default/app.conf
similarity index 100%
rename from examples/com/splunk/examples/random_numbers/random_numbers/default/app.conf
rename to examples/src/main/java/com/splunk/examples/random_numbers/random_numbers/default/app.conf
diff --git a/examples/com/splunk/examples/search/Program.java b/examples/src/main/java/com/splunk/examples/search/Program.java
similarity index 100%
rename from examples/com/splunk/examples/search/Program.java
rename to examples/src/main/java/com/splunk/examples/search/Program.java
diff --git a/examples/com/splunk/examples/search_blocking/Program.java b/examples/src/main/java/com/splunk/examples/search_blocking/Program.java
similarity index 100%
rename from examples/com/splunk/examples/search_blocking/Program.java
rename to examples/src/main/java/com/splunk/examples/search_blocking/Program.java
diff --git a/examples/com/splunk/examples/search_oneshot/Program.java b/examples/src/main/java/com/splunk/examples/search_oneshot/Program.java
similarity index 100%
rename from examples/com/splunk/examples/search_oneshot/Program.java
rename to examples/src/main/java/com/splunk/examples/search_oneshot/Program.java
diff --git a/examples/com/splunk/examples/search_realtime/Program.java b/examples/src/main/java/com/splunk/examples/search_realtime/Program.java
similarity index 100%
rename from examples/com/splunk/examples/search_realtime/Program.java
rename to examples/src/main/java/com/splunk/examples/search_realtime/Program.java
diff --git a/examples/com/splunk/examples/search_saved/Program.java b/examples/src/main/java/com/splunk/examples/search_saved/Program.java
similarity index 100%
rename from examples/com/splunk/examples/search_saved/Program.java
rename to examples/src/main/java/com/splunk/examples/search_saved/Program.java
diff --git a/examples/com/splunk/examples/search_simple/Program.java b/examples/src/main/java/com/splunk/examples/search_simple/Program.java
similarity index 100%
rename from examples/com/splunk/examples/search_simple/Program.java
rename to examples/src/main/java/com/splunk/examples/search_simple/Program.java
diff --git a/examples/com/splunk/examples/spurl/Program.java b/examples/src/main/java/com/splunk/examples/spurl/Program.java
similarity index 100%
rename from examples/com/splunk/examples/spurl/Program.java
rename to examples/src/main/java/com/splunk/examples/spurl/Program.java
diff --git a/examples/src/main/java/com/splunk/examples/ssl_protocols/Program.java b/examples/src/main/java/com/splunk/examples/ssl_protocols/Program.java
new file mode 100644
index 00000000..a6352054
--- /dev/null
+++ b/examples/src/main/java/com/splunk/examples/ssl_protocols/Program.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2015 Splunk, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"): you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This example will demonstrate how to use a specific SSL/TLS
+ * protocol to connect to Splunk.
+ * Additionally, there's a small code sample showing how to
+ * use a custom SSLSocketFactory to connect to Splunk.
+ */
+
+package com.splunk.examples.ssl_protocols;
+
+import com.splunk.Command;
+import com.splunk.SSLSecurityProtocol;
+import com.splunk.Service;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+
+
+public class Program {
+
+ public static Integer getJavaVersion() {
+ String ver = System.getProperty("java.version");
+ return Integer.parseInt(ver.substring(2, 3));
+ }
+
+ public static void main(String[] args) {
+ Command command = Command.splunk("info").parse(args);
+
+ int version = getJavaVersion();
+ System.out.println("Your Java version is: " + version);
+
+ // At this point, the default protocol is SSLv3.
+ // Possible values are TLSv1.2, TLSv1.1, TLSv1 & SSLv3
+ // These are defined by the SSLSecurityProtocol enum
+ // Java 8 disables SSLv3 by default
+ System.out.println("Now trying to connect to Splunk using SSLv3");
+ try {
+ Service.setSslSecurityProtocol(SSLSecurityProtocol.SSLv3);
+ Service serviceSSLv3 = Service.connect(command.opts);
+ serviceSSLv3.login();
+ System.out.println("\t Success!");
+ } catch (RuntimeException e) {
+ System.out.println("\t Failure! ");
+ }
+
+ // TLSv1 is available by default in every modern version of Java
+ System.out.println("Now trying to connect to Splunk using TLSv1");
+ try {
+ Service.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1);
+ Service serviceTLSv1 = Service.connect(command.opts);
+ serviceTLSv1.login();
+ System.out.println("\t Success!");
+ } catch (RuntimeException e) {
+ System.out.println("\t Failure! ");
+ }
+
+
+ // TLSv1.1 is available by default in Java 7 and up
+ System.out.println("Now trying to connect to Splunk using TLSv1.1");
+ try {
+ Service.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_1);
+ Service serviceTLSv1_1 = Service.connect(command.opts);
+ serviceTLSv1_1.login();
+ System.out.println("\t Success!");
+ } catch (RuntimeException e) {
+ System.out.println("\t Failure! ");
+ }
+
+ // TLSv1.2 is available by default in Java 7 and up
+ System.out.println("Now trying to connect to Splunk using TLSv1.2");
+ try {
+ Service.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);
+ Service serviceTLSv1_2 = Service.connect(command.opts);
+ serviceTLSv1_2.login();
+ System.out.println("\t Success!");
+ } catch (RuntimeException e) {
+ System.out.println("\t Failure! ");
+ }
+
+ // You can also specify your own SSLSocketFactory, in this case any version of SSL
+ System.out.println("Now trying to connect to Splunk using a custom SSL only SSLSocketFactory");
+ try {
+ // Create an SSLSocketFactory configured to use SSL only
+ SSLContext sslContext = SSLContext.getInstance("SSL");
+ TrustManager[] byPassTrustManagers = new TrustManager[]{
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {
+ }
+ }
+ };
+ sslContext.init(null, byPassTrustManagers, new SecureRandom());
+ SSLSocketFactory SSLOnlySSLFactory = sslContext.getSocketFactory();
+ Service.setSSLSocketFactory(SSLOnlySSLFactory);
+
+ Service serviceCustomSSLFactory = Service.connect(command.opts);
+ serviceCustomSSLFactory.login();
+ System.out.println("\t Success!");
+ } catch (Exception e) {
+ System.out.println("\t Failure!");
+ }
+
+ // You can also specify your own SSLSocketFactory, in this case any version of TLS
+ System.out.println("Now trying to connect to Splunk using a custom TLS only SSLSocketFactory");
+ try {
+ // Create an SSLSocketFactory configured to use TLS only
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ TrustManager[] byPassTrustManagers = new TrustManager[]{
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {
+ }
+ }
+ };
+ sslContext.init(null, byPassTrustManagers, new SecureRandom());
+ SSLSocketFactory TLSOnlySSLFactory = sslContext.getSocketFactory();
+ Service.setSSLSocketFactory(TLSOnlySSLFactory);
+
+ Service serviceCustomSSLFactory = Service.connect(command.opts);
+ serviceCustomSSLFactory.login();
+ System.out.println("\t Success!");
+ } catch (Exception e) {
+ System.out.println("\t Failure!");
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/com/splunk/examples/tail/Program.java b/examples/src/main/java/com/splunk/examples/tail/Program.java
similarity index 100%
rename from examples/com/splunk/examples/tail/Program.java
rename to examples/src/main/java/com/splunk/examples/tail/Program.java
diff --git a/examples/com/splunk/examples/testupdate/Program.java b/examples/src/main/java/com/splunk/examples/testupdate/Program.java
similarity index 100%
rename from examples/com/splunk/examples/testupdate/Program.java
rename to examples/src/main/java/com/splunk/examples/testupdate/Program.java
diff --git a/launchers/README.md b/launchers/README.md
index 39ee6336..a13675d6 100644
--- a/launchers/README.md
+++ b/launchers/README.md
@@ -1,6 +1,6 @@
-# Modular input launchers for the Splunk SDK for Java
+# Modular input launchers for the Splunk Enterprise SDK for Java
-Splunk cannot launch Java programs as modular inputs directly. Instead, we need to provide a few small programs to launch a JVM and run a program. Since modular inputs written in Java need to work across all Splunk variants, including the universal forwarder, the launchers cannot rely on Python or anything else in the underlying system. Instead, we provide a set of C programs compiled for each of Linux, MacOS X, and Windows.
+Splunk Enterprise cannot launch Java programs as modular inputs directly. Instead, we need to provide a few small programs to launch a JVM and run a program. Since modular inputs written in Java need to work across all Splunk variants, including the universal forwarder, the launchers cannot rely on Python or anything else in the underlying system. Instead, we provide a set of C programs compiled for each of Linux, MacOS X, and Windows.
The programs assume the following layout in an app: a jars/ directory containing a launchable jar containing the modular input, and a configuration file with a .ini suffix of the same base name that contains options for what JVM to launch and what options to pass to it. Then platform specific bin directories contain the launcher programs, named the base name of the target jar. For for a jar named myinput.jar, the layout would be
diff --git a/launchers/shim-darwin.sh b/launchers/shim-darwin.sh
index 17d5743d..145f1e46 100755
--- a/launchers/shim-darwin.sh
+++ b/launchers/shim-darwin.sh
@@ -4,6 +4,10 @@
# input is contained in, and the jar is assumed to be in
# jars/${INPUTNAME}.jar in the app.
#
+# If ${PLATFORM}/bin/customized.java.path exists, this script will
+# use java cmd defined in this file to start jvm, else default java
+# will be used.
+#
# Extra arguments to the JVM (i.e., -Xms512M) can be put in
# a file jars/${INPUTNAME}.vmopts and will be interpolated
# into the command to run the JVM.
@@ -20,6 +24,13 @@ done
BASENAME=$(basename "$SCRIPT" .sh)
JAR_DIR=`pwd -P`/../../jars
+CUSTOMIZED_JAVA_PATH_FILE=`pwd -P`/customized.java.path
+
+if [ -f $CUSTOMIZED_JAVA_PATH_FILE ]; then
+ JAVA_CMD=`cat $CUSTOMIZED_JAVA_PATH_FILE`
+else
+ JAVA_CMD="java"
+fi
if [ -f $JAR_DIR/$BASENAME.vmopts ]; then
VMOPTS=`cat $JAR_DIR/$BASENAME.vmopts`
@@ -27,4 +38,5 @@ else
VMOPTS=""
fi
-exec java $VMOPTS -jar $JAR_DIR/$BASENAME.jar $@
+exec $JAVA_CMD $VMOPTS -jar $JAR_DIR/$BASENAME.jar $@
+
diff --git a/launchers/shim-linux.sh b/launchers/shim-linux.sh
index fdfa0a5a..e0676451 100755
--- a/launchers/shim-linux.sh
+++ b/launchers/shim-linux.sh
@@ -4,12 +4,23 @@
# input is contained in, and the jar is assumed to be in
# jars/${INPUTNAME}.jar in the app.
#
+# If ${PLATFORM}/bin/customized.java.path exists, this script will
+# use java cmd defined in this file to start jvm, else default java
+# will be used.
+#
# Extra arguments to the JVM (i.e., -Xms512M) can be put in
# a file jars/${INPUTNAME}.vmopts and will be interpolated
# into the command to run the JVM.
SCRIPT=$(readlink -f "$0")
BASENAME=$(basename "$SCRIPT" .sh)
JAR_DIR=$(dirname "$SCRIPT")/../../jars
+CUSTOMIZED_JAVA_PATH_FILE=$(dirname "$SCRIPT")/customized.java.path
+
+if [ -f $CUSTOMIZED_JAVA_PATH_FILE ]; then
+ JAVA_CMD=`cat $CUSTOMIZED_JAVA_PATH_FILE`
+else
+ JAVA_CMD="java"
+fi
if [ -f $JAR_DIR/$BASENAME.vmopts ]; then
VMOPTS=`cat $JAR_DIR/$BASENAME.vmopts`
@@ -17,4 +28,4 @@ else
VMOPTS=""
fi
-exec java $VMOPTS -jar $JAR_DIR/$BASENAME.jar $@
+exec $JAVA_CMD $VMOPTS -jar $JAR_DIR/$BASENAME.jar $@
\ No newline at end of file
diff --git a/launchers/shim-windows_x86.exe b/launchers/shim-windows_x86.exe
index aac2da47..3ec87105 100755
Binary files a/launchers/shim-windows_x86.exe and b/launchers/shim-windows_x86.exe differ
diff --git a/launchers/shim-windows_x86_64.exe b/launchers/shim-windows_x86_64.exe
index 77ec8f3b..ffb1f4fc 100755
Binary files a/launchers/shim-windows_x86_64.exe and b/launchers/shim-windows_x86_64.exe differ
diff --git a/launchers/shim/shim/shim.cpp b/launchers/shim/shim/shim.cpp
index ef0d1c49..cbbf0778 100755
--- a/launchers/shim/shim/shim.cpp
+++ b/launchers/shim/shim/shim.cpp
@@ -25,9 +25,9 @@ int _tmain(int argc, _TCHAR* argv[])
HANDLE processHandles[2] = {NULL, NULL};
HANDLE &splunkdHandle = processHandles[0];
HANDLE &jvmHandle = processHandles[1];
- PTSTR jarPath = NULL, jvmOptions = NULL, jvmCommandLine = NULL;
- DWORD waitOutcome, exitCode;
-
+ HANDLE ghJob = NULL;
+ PTSTR customizedJavaCmd = NULL, jarPath = NULL, jvmOptions = NULL, jvmCommandLine = NULL;
+ DWORD waitOutcome;
DWORD returnCode = 0;
STARTUPINFO si;
@@ -39,7 +39,7 @@ int _tmain(int argc, _TCHAR* argv[])
SetConsoleCtrlHandler((PHANDLER_ROUTINE)killJvm, TRUE);
splunkdHandle = getSplunkdHandle();
-
+
if (NULL == splunkdHandle) {
// Couldn't get a handle to splunkd.
printErrorMessage(GetLastError());
@@ -48,11 +48,32 @@ int _tmain(int argc, _TCHAR* argv[])
goto CLEAN_UP_AND_EXIT;
}
+ // create a job
+ ghJob = CreateJobObject(NULL, NULL);
+ if(ghJob == NULL) {
+ printErrorMessage(GetLastError());
+
+ returnCode = 1;
+ goto CLEAN_UP_AND_EXIT;
+ }else {
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
+
+ // Configure all child processes associated with the job to terminate when the main process terminated
+ jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+ if(0 == SetInformationJobObject(ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) {
+ printErrorMessage(GetLastError());
+
+ returnCode = 1;
+ goto CLEAN_UP_AND_EXIT;
+ }
+ }
+
+ customizedJavaCmd = getCustomizedJavaCmd();
jarPath = getPathToJar();
jvmOptions = readJvmOptions(jarPath);
- jvmCommandLine = assembleJvmCommand(jarPath, jvmOptions, argc, argv);
+ jvmCommandLine = assembleJvmCommand(customizedJavaCmd, jarPath, jvmOptions, argc, argv);
- if (!CreateProcess(NULL, jvmCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
+ if (!CreateProcess(NULL, jvmCommandLine, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) {
// Process creation failed.
printErrorMessage(GetLastError(), jvmCommandLine);
@@ -60,6 +81,14 @@ int _tmain(int argc, _TCHAR* argv[])
goto CLEAN_UP_AND_EXIT;
}
+ // bind java process to this job
+ if(0 == AssignProcessToJobObject(ghJob, pi.hProcess)) {
+ printErrorMessage(GetLastError());
+
+ returnCode = 1;
+ goto CLEAN_UP_AND_EXIT;
+ }
+
CloseHandle(pi.hThread); // CreateProcess gives us a handle to the initial thread of the new process, which we don't need.
jvmHandle = pi.hProcess;
jvmPid = pi.dwProcessId;
@@ -89,9 +118,11 @@ int _tmain(int argc, _TCHAR* argv[])
if (NULL != jvmCommandLine) LocalFree(jvmCommandLine);
if (NULL != jvmOptions) LocalFree(jvmOptions);
if (NULL != jarPath) LocalFree(jarPath);
+ if (NULL != customizedJavaCmd) LocalFree(customizedJavaCmd);
if (NULL != splunkdHandle) CloseHandle(splunkdHandle);
if (NULL != jvmHandle) CloseHandle(jvmHandle);
+ if (NULL != ghJob) CloseHandle(ghJob);
return returnCode;
}
@@ -113,7 +144,7 @@ void printErrorMessage(DWORD errorCode, ...) {
va_list args = NULL;
va_start(args, errorCode);
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer, 0, &args);
fwprintf(stderr, TEXT("ERROR %s\r\n"), buffer);
@@ -123,7 +154,7 @@ void printErrorMessage(DWORD errorCode, ...) {
PTSTR readJvmOptions(PTSTR jarPath) {
- DWORD jarPathLen = _tcslen(jarPath);
+ size_t jarPathLen = _tcslen(jarPath);
// vmoptsPath is the same as jarPath, but ending with .vmopts instead of .jar. We allocate
// 3 additional TCHARs for the additional length of .vmopts, and 1 more TCHAR for a NULL
// terminator, so jarPathLen+4.
@@ -140,7 +171,7 @@ PTSTR readJvmOptions(PTSTR jarPath) {
_tcscpy_s(suffixPtr, 8, TEXT(".vmopts"));
- HANDLE vmoptsHandle = CreateFile(vmoptsPath, GENERIC_READ, FILE_SHARE_READ,
+ HANDLE vmoptsHandle = CreateFile(vmoptsPath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == vmoptsHandle) {
@@ -167,6 +198,8 @@ PTSTR readJvmOptions(PTSTR jarPath) {
}
buffer[nRead] = NULL; // Ensure options are null terminated.
+ if (NULL != vmoptsHandle) CloseHandle(vmoptsHandle);
+
#ifdef _UNICODE
// Calculate how much space is needed.
DWORD nWchars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer, nRead, NULL, 0);
@@ -182,7 +215,7 @@ PTSTR readJvmOptions(PTSTR jarPath) {
}
-PTSTR assembleJvmCommand(PTSTR jarPath, PTSTR jvmOptions, int argc, _TCHAR* argv[]) {
+PTSTR assembleJvmCommand(PTSTR customizedJavaCmd, PTSTR jarPath, PTSTR jvmOptions, int argc, _TCHAR* argv[]) {
PTSTR buffer, index;
size_t len;
int i;
@@ -192,16 +225,20 @@ PTSTR assembleJvmCommand(PTSTR jarPath, PTSTR jvmOptions, int argc, _TCHAR* argv
len += _tcslen(argv[i]) + 1; // The +1 accounts for a space to separate the arguments
}
- // 13 = number of characters for java and -jar sections; +1 at the end is for the null terminator.
- buffer = (PTSTR)malloc((13 + _tcslen(jarPath) + _tcslen(jvmOptions) + len + 1) * sizeof(TCHAR));
+ // 9 + max(command) = number of characters for java cmd and -jar sections; +1 at the end is for the null terminator.
+ buffer = (PTSTR)malloc((9 + max(_tcslen(customizedJavaCmd), 4) + _tcslen(jarPath) + _tcslen(jvmOptions) + len + 1) * sizeof(TCHAR));
index = buffer;
#define APPEND_TCS(literal) { \
_tcscpy_s(index, _tcslen(literal)+1, literal); \
index += _tcslen(literal); \
}
-
- APPEND_TCS(TEXT("java "));
+ if (NULL != customizedJavaCmd && 0 != _tcslen(customizedJavaCmd)) {
+ APPEND_TCS(customizedJavaCmd);
+ APPEND_TCS(TEXT(" "));
+ } else {
+ APPEND_TCS(TEXT("java "));
+ }
APPEND_TCS(jvmOptions);
APPEND_TCS(TEXT(" -jar \""));
APPEND_TCS(jarPath);
@@ -247,7 +284,7 @@ HANDLE getSplunkdHandle() {
}
free(pidBuffer);
-
+
return OpenProcess(SYNCHRONIZE, FALSE, splunkdPid);
}
@@ -259,13 +296,13 @@ PTSTR getPathToJar() {
PCTSTR jarSuffix = TEXT(".jar");
const DWORD jarSuffixLen = 5;
const size_t N = 1024;
- DWORD baseNameLen;
+ size_t baseNameLen;
thisPath = (PTSTR)malloc(N*sizeof(TCHAR));
if (N == GetModuleFileName(NULL, thisPath, N) && ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
return NULL;
}
-
+
// The following code removes the last two path segments before the executable name in the buffer,
// puts a \jars\ on the path, then shifts the base name of the executable over and adds .jar to it.
// Graphically, with 0 representing null terminators, the steps are:
@@ -274,7 +311,7 @@ PTSTR getPathToJar() {
// 2. $SPLUNK_HOME$\etc\apps\myapp\jars\0 myinput.exe0
// 3. $SPLUNK_HOME$\etc\apps\myapp\jars\myinput0
// 4. $SPLUNK_HOME$\etc\apps\myapp\jars\myinput.jar0
-
+
// Find 'myinput.exe', just after the last \.
endPtr = _tcsrchr(thisPath, '\\');
baseName = endPtr+1; // This is 'myinput.exe'
@@ -287,7 +324,7 @@ PTSTR getPathToJar() {
*endPtr = NULL;
endPtr = _tcsrchr(thisPath, '\\');
- if (baseName-endPtr < _tcslen(TEXT("\\jars\\"))) {
+ if ((size_t)(baseName-endPtr) < _tcslen(TEXT("\\jars\\"))) {
return NULL; // Not enough space to copy the path fragment in without clobbering the jar name.
}
@@ -302,4 +339,65 @@ PTSTR getPathToJar() {
_tcscpy_s(endPtr, jarSuffixLen, jarSuffix);
return thisPath;
-}
\ No newline at end of file
+}
+
+PTSTR getCustomizedJavaCmd() {
+ PTSTR javaHomePath, endPtr;
+ PCTSTR javaHomeFragment = TEXT("\\customized.java.path");
+ const DWORD javaHomeFragmentLen = 22;
+ const size_t N = 1024;
+
+ javaHomePath = (PTSTR)malloc(N*sizeof(TCHAR));
+ if (N == GetModuleFileName(NULL, javaHomePath, N) && ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
+ return NULL;
+ }
+
+ // thisPath is: $SPLUNK_HOME$\etc\apps\myapp\windows_x86_64\bin\myinput.exe0
+ // Take three directory levels off this path.
+ endPtr = _tcsrchr(javaHomePath, '\\');
+ _tcscpy_s(endPtr, javaHomeFragmentLen, javaHomeFragment);
+ endPtr += javaHomeFragmentLen;
+ *endPtr = NULL;
+
+ HANDLE javaHomeHandle = CreateFile(javaHomePath, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (INVALID_HANDLE_VALUE == javaHomeHandle) {
+ if (ERROR_FILE_NOT_FOUND == GetLastError() || ERROR_PATH_NOT_FOUND == GetLastError()) {
+ // We can't return a literal because we will try to deallocate it later.
+ free(javaHomePath);
+ javaHomePath = (PTSTR)malloc(sizeof(TCHAR));
+ _tcscpy_s(javaHomePath, 1, TEXT(""));
+ return javaHomePath;
+ } else {
+ return NULL;
+ }
+ }
+
+ DWORD fileSize = GetFileSize(javaHomeHandle, NULL);
+ if (INVALID_FILE_SIZE == fileSize) {
+ return NULL;
+ }
+
+ DWORD nRead;
+ char* buffer = (char*)malloc((fileSize+1) * sizeof(char)); // +1 to give space for a NULL character.
+ if (!ReadFile(javaHomeHandle, buffer, fileSize, &nRead, NULL)) {
+ return NULL;
+ }
+ buffer[nRead] = NULL; // Ensure options are null terminated.
+
+ if (NULL != javaHomeHandle) CloseHandle(javaHomeHandle);
+
+#ifdef _UNICODE
+ // Calculate how much space is needed.
+ DWORD nWchars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer, nRead, NULL, 0);
+ wchar_t *javaHome = (wchar_t*)malloc(sizeof(wchar_t) * (nWchars+1));
+ if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer, nRead, javaHome, nWchars)) {
+ return NULL;
+ }
+ javaHome[nWchars] = NULL;
+ return javaHome;
+#else
+ return buffer;
+#endif
+}
diff --git a/launchers/shim/shim/shim.h b/launchers/shim/shim/shim.h
index 82dce16d..7c86df56 100755
--- a/launchers/shim/shim/shim.h
+++ b/launchers/shim/shim/shim.h
@@ -73,13 +73,17 @@ PTSTR getPathToJar();
*/
PTSTR readJvmOptions(PTSTR pathToJar);
+/**
+ * get the customized java command
+ */
+PTSTR getCustomizedJavaCmd();
/**
* Construct the full command to run the jar. This will return a new buffer containing
*
* java [jvmOptions] -jar "[jarPath]" [argv[0]] [argv[1]] ...
*/
-PTSTR assembleJvmCommand(PTSTR pathToJar, PTSTR jvmOptions, int argc, _TCHAR* argv[]);
+PTSTR assembleJvmCommand(PTSTR customizedJavaCmd, PTSTR pathToJar, PTSTR jvmOptions, int argc, _TCHAR* argv[]);
/**
diff --git a/lib/commons-cli-1.2.jar b/lib/commons-cli-1.2.jar
deleted file mode 100644
index ce4b9fff..00000000
Binary files a/lib/commons-cli-1.2.jar and /dev/null differ
diff --git a/lib/gson-2.2.4.jar b/lib/gson-2.2.4.jar
deleted file mode 100644
index 9478253e..00000000
Binary files a/lib/gson-2.2.4.jar and /dev/null differ
diff --git a/lib/jacocoant.jar b/lib/jacocoant.jar
deleted file mode 100755
index 73baf677..00000000
Binary files a/lib/jacocoant.jar and /dev/null differ
diff --git a/lib/junit-4.11.jar b/lib/junit-4.11.jar
deleted file mode 100644
index 4d552a6f..00000000
Binary files a/lib/junit-4.11.jar and /dev/null differ
diff --git a/lib/opencsv-2.3.jar b/lib/opencsv-2.3.jar
deleted file mode 100644
index f6c88b86..00000000
Binary files a/lib/opencsv-2.3.jar and /dev/null differ
diff --git a/lib/org-openide-actions.jar b/lib/org-openide-actions.jar
deleted file mode 100644
index ca83aa26..00000000
Binary files a/lib/org-openide-actions.jar and /dev/null differ
diff --git a/lib/org-openide-awt.jar b/lib/org-openide-awt.jar
deleted file mode 100644
index 22972b7c..00000000
Binary files a/lib/org-openide-awt.jar and /dev/null differ
diff --git a/lib/org-openide-compat.jar b/lib/org-openide-compat.jar
deleted file mode 100644
index af1b2740..00000000
Binary files a/lib/org-openide-compat.jar and /dev/null differ
diff --git a/lib/org-openide-dialogs.jar b/lib/org-openide-dialogs.jar
deleted file mode 100644
index 06dcceb9..00000000
Binary files a/lib/org-openide-dialogs.jar and /dev/null differ
diff --git a/lib/org-openide-execution.jar b/lib/org-openide-execution.jar
deleted file mode 100644
index 47e7cf92..00000000
Binary files a/lib/org-openide-execution.jar and /dev/null differ
diff --git a/lib/org-openide-explorer.jar b/lib/org-openide-explorer.jar
deleted file mode 100644
index e15ac8af..00000000
Binary files a/lib/org-openide-explorer.jar and /dev/null differ
diff --git a/lib/org-openide-filesystems.jar b/lib/org-openide-filesystems.jar
deleted file mode 100644
index 1b1c581e..00000000
Binary files a/lib/org-openide-filesystems.jar and /dev/null differ
diff --git a/lib/org-openide-io.jar b/lib/org-openide-io.jar
deleted file mode 100644
index 49522467..00000000
Binary files a/lib/org-openide-io.jar and /dev/null differ
diff --git a/lib/org-openide-loaders.jar b/lib/org-openide-loaders.jar
deleted file mode 100644
index 0b36eb66..00000000
Binary files a/lib/org-openide-loaders.jar and /dev/null differ
diff --git a/lib/org-openide-modules.jar b/lib/org-openide-modules.jar
deleted file mode 100644
index 6008a329..00000000
Binary files a/lib/org-openide-modules.jar and /dev/null differ
diff --git a/lib/org-openide-nodes.jar b/lib/org-openide-nodes.jar
deleted file mode 100644
index ec1c9722..00000000
Binary files a/lib/org-openide-nodes.jar and /dev/null differ
diff --git a/lib/org-openide-options.jar b/lib/org-openide-options.jar
deleted file mode 100644
index 88b2fb30..00000000
Binary files a/lib/org-openide-options.jar and /dev/null differ
diff --git a/lib/org-openide-text.jar b/lib/org-openide-text.jar
deleted file mode 100644
index 819a9e20..00000000
Binary files a/lib/org-openide-text.jar and /dev/null differ
diff --git a/lib/org-openide-util-enumerations.jar b/lib/org-openide-util-enumerations.jar
deleted file mode 100644
index 1bd943a3..00000000
Binary files a/lib/org-openide-util-enumerations.jar and /dev/null differ
diff --git a/lib/org-openide-util-lookup.jar b/lib/org-openide-util-lookup.jar
deleted file mode 100644
index c9a082b2..00000000
Binary files a/lib/org-openide-util-lookup.jar and /dev/null differ
diff --git a/lib/org-openide-util.jar b/lib/org-openide-util.jar
deleted file mode 100644
index feb7c432..00000000
Binary files a/lib/org-openide-util.jar and /dev/null differ
diff --git a/lib/org-openide-windows.jar b/lib/org-openide-windows.jar
deleted file mode 100644
index 57c7cf76..00000000
Binary files a/lib/org-openide-windows.jar and /dev/null differ
diff --git a/licenses/LICENSE-COMMONS b/licenses/LICENSE-COMMONS
new file mode 100644
index 00000000..7a4a3ea2
--- /dev/null
+++ b/licenses/LICENSE-COMMONS
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/licenses/LICENSE-GSON b/licenses/LICENSE-GSON
new file mode 100644
index 00000000..7a4a3ea2
--- /dev/null
+++ b/licenses/LICENSE-GSON
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/licenses/LICENSE-JACOCO b/licenses/LICENSE-JACOCO
new file mode 100644
index 00000000..e19f0de1
--- /dev/null
+++ b/licenses/LICENSE-JACOCO
@@ -0,0 +1,74 @@
+Eclipse Public License - v 2.0
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (“AGREEMENT”). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+“Contribution” means:
+
+a) in the case of the initial Contributor, the initial content Distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are Distributed by that particular Contributor. A Contribution “originates” from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include changes or additions to the Program that are not Modified Works.
+“Contributor” means any person or entity that Distributes the Program.
+
+“Licensed Patents” mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+“Program” means the Contributions Distributed in accordance with this Agreement.
+
+“Recipient” means anyone who receives the Program under this Agreement or any Secondary License (as applicable), including Contributors.
+
+“Derivative Works” shall mean any work, whether in Source Code or other form, that is based on (or derived from) the Program and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship.
+
+“Modified Works” shall mean any work in Source Code or other form that results from an addition to, deletion from, or modification of the contents of the Program, including, for purposes of clarity any new file in Source Code form that contains any contents of the Program. Modified Works shall not include works that contain only declarations, interfaces, types, classes, structures, or files of the Program solely in each case in order to link to, bind by name, or subclass the Program or Modified Works thereof.
+
+“Distribute” means the acts of a) distributing or b) making available in any manner that enables the transfer of a copy.
+
+“Source Code” means the form of a Program preferred for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+“Secondary License” means either the GNU General Public License, Version 2.0, or any later versions of that license, including any exceptions or additional permissions as identified by the initial Contributor.
+
+2. GRANT OF RIGHTS
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, Distribute and sublicense the Contribution of such Contributor, if any, and such Derivative Works.
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in Source Code or other form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to Distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+e) Notwithstanding the terms of any Secondary License, no Contributor makes additional grants to any Recipient (other than those set forth in this Agreement) as a result of such Recipient's receipt of the Program under the terms of a Secondary License (if permitted under the terms of Section 3).
+3. REQUIREMENTS
+3.1 If a Contributor Distributes the Program in any form, then:
+
+a) the Program must also be made available as Source Code, in accordance with section 3.2, and the Contributor must accompany the Program with a statement that the Source Code for the Program is available under this Agreement, and informs Recipients how to obtain it in a reasonable manner on or through a medium customarily used for software exchange; and
+b) the Contributor may Distribute the Program under a license different than this Agreement, provided that such license:
+i) effectively disclaims on behalf of all other Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+ii) effectively excludes on behalf of all other Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+iii) does not attempt to limit or alter the recipients' rights in the Source Code under section 3.2; and
+iv) requires any subsequent distribution of the Program by any party to be under a license that satisfies the requirements of this section 3.
+3.2 When the Program is Distributed as Source Code:
+
+a) it must be made available under this Agreement, or if the Program (i) is combined with other material in a separate file or files made available under a Secondary License, and (ii) the initial Contributor attached to the Source Code the notice described in Exhibit A of this Agreement, then the Program may be made available under the terms of such Secondary Licenses, and
+b) a copy of this Agreement must be included with each copy of the Program.
+3.3 Contributors may not remove or alter any copyright, patent, trademark, attribution notices, disclaimers of warranty, or limitations of liability (‘notices’) contained within the Program from any copy of the Program which they Distribute, provided that Contributors may add their own appropriate notices.
+
+4. COMMERCIAL DISTRIBUTION
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (“Commercial Contributor”) hereby agrees to defend and indemnify every other Contributor (“Indemnified Contributor”) against any losses, damages and costs (collectively “Losses”) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be Distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to Distribute the Program (including its Contributions) under the new version.
+
+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. Nothing in this Agreement is intended to be enforceable by any entity that is not a Contributor or Recipient. No third-party beneficiary rights are created under this Agreement.
+
+Exhibit A – Form of Secondary Licenses Notice
+“This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), version(s), and exceptions or additional permissions here}.”
\ No newline at end of file
diff --git a/licenses/LICENSE-JUNIT b/licenses/LICENSE-JUNIT
new file mode 100644
index 00000000..3fa00836
--- /dev/null
+++ b/licenses/LICENSE-JUNIT
@@ -0,0 +1,86 @@
+Eclipse Public License - v 1.0
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
\ No newline at end of file
diff --git a/licenses/LICENSE-NETBEANS b/licenses/LICENSE-NETBEANS
new file mode 100644
index 00000000..4c9ad980
--- /dev/null
+++ b/licenses/LICENSE-NETBEANS
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/licenses/LICENSE-OPENCSV b/licenses/LICENSE-OPENCSV
new file mode 100644
index 00000000..8ca90d00
--- /dev/null
+++ b/licenses/LICENSE-OPENCSV
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 00000000..37ef9e19
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,91 @@
+
+
+ 4.0.0
+
+
+ 1.9.5
+ true
+ UTF-8
+ 8
+ 8
+
+
+ com.splunk
+ splunk-sdk-java
+ 1.0.1
+ pom
+ Splunk SDK for Java
+ https://dev.splunk.com/enterprise/docs/devtools/java/sdk-java
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.9
+
+
+ net.sf.opencsv
+ opencsv
+ 2.3
+
+
+
+ splunk
+ examples
+
+
+
+ package
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.0.0-M1
+
+ false
+
+
+
+
+
+
+
+ splunk-artifactory
+ Splunk Releases
+ https://splunk.jfrog.io/splunk/ext-releases-local
+
+
+
+
+
+ splunk-artifactory
+ Splunk Releases
+ https://splunk.jfrog.io/splunk/ext-releases-local
+
+
+
+
+
+ The Apache Software License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+
+ Splunk, Inc.
+ http://dev.splunk.com
+
+
diff --git a/scripts/test_specific.sh b/scripts/test_specific.sh
new file mode 100644
index 00000000..34aac979
--- /dev/null
+++ b/scripts/test_specific.sh
@@ -0,0 +1,2 @@
+echo "To run a specific test:"
+echo " mvn test -Dtest=[testclass]"
diff --git a/splunk/com/splunk/HttpService.java b/splunk/com/splunk/HttpService.java
deleted file mode 100644
index 4a1ee8af..00000000
--- a/splunk/com/splunk/HttpService.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright 2012 Splunk, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"): you may
- * not use this file except in compliance with the License. You may obtain
- * a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package com.splunk;
-
-import javax.net.ssl.*;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.net.*;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The {@code HttpService} class represents a generic HTTP service at a given
- * address ({@code host:port}), accessed using a given protocol scheme
- * ({@code http} or {@code https}).
- */
-public class HttpService {
- // For debugging purposes
- private static final boolean VERBOSE_REQUESTS = false;
-
- private static final SSLSocketFactory SSL_SOCKET_FACTORY = createSSLFactory();
-
- private static String HTTPS_SCHEME = "https";
- private static String HTTP_SCHEME = "http";
-
- private static final HostnameVerifier HOSTNAME_VERIFIER = new HostnameVerifier() {
- public boolean verify(String s, SSLSession sslSession) {
- return true;
- }
- };
-
- /** A variable to hold an optional custom HTTPS handler */
- protected URLStreamHandler httpsHandler = null;
-
- /** The scheme used to access the service. */
- protected String scheme = "https";
-
- /** The host name of the service. */
- protected String host = "localhost";
-
- /** The port number of the service. */
- protected int port = 8089;
-
- private String prefix = null;
-
- static Map defaultHeader = new HashMap() {{
- put("User-Agent", "splunk-sdk-java/1.3.2");
- put("Accept", "*/*");
- }};
-
- /** Constructs a new {@code HttpService} instance. */
- public HttpService() {
- }
-
- /**
- * Constructs a new {@code HttpService} instance at the given host.
- *
- * @param host The host name of the service.
- */
- public HttpService(String host) {
- this.host = host;
- }
-
- /**
- * Constructs a new {@code HttpService} instance at the given host and port.
- *
- * @param host The host name of the service.
- * @param port The port number of the service.
- */
- public HttpService(String host, int port) {
- this.host = host;
- this.port = port;
- }
-
- /**
- * Constructs a new {@code HttpService} instance using the given host,
- * port, and scheme.
- *
- * @param host The host name of the service.
- * @param port The port number of the service.
- * @param scheme Scheme for accessing the service ({@code http} or
- * {@code https}).
- */
- public HttpService(String host, int port, String scheme) {
- this.host = host;
- this.port = port;
- this.scheme = scheme;
- }
-
- /**
- * Constructs a new {@code HttpService} instance using the given host,
- * port, and scheme, and instructing it to use the specified HTTPS handler.
- *
- * @param host The host name of the service.
- * @param port The port number of the service.
- * @param scheme Scheme for accessing the service ({@code http} or
- * {@code https}).
- */
- public HttpService(String host, int port, String scheme,
- URLStreamHandler httpsHandler) {
- this.host = host;
- this.port = port;
- this.scheme = scheme;
- this.httpsHandler = httpsHandler;
- }
-
- // Returns the count of arguments in the given {@code args} map.
- private static int count(Map args) {
- if (args == null) return 0;
- return args.size();
- }
-
- /**
- * Issues an HTTP GET request against the service using a given path.
- *
- * @param path The request path.
- * @return The HTTP response.
- */
- public ResponseMessage get(String path) {
- return send(path, new RequestMessage("GET"));
- }
-
- /**
- * Issues an HTTP GET request against the service using a given path and
- * query arguments.
- *
- * @param path The request path.
- * @param args The query arguments.
- * @return The HTTP response.
- */
- public ResponseMessage get(String path, Map args) {
- if (count(args) > 0)
- path = path + "?" + Args.encode(args);
- RequestMessage request = new RequestMessage("GET");
- return send(path, request);
- }
-
- /**
- * Returns the host name of this service.
- *
- * @return The host name.
- */
- public String getHost() {
- return this.host;
- }
-
- /**
- * Returns the port number of this service.
- *
- * @return The port number.
- */
- public int getPort() {
- return this.port;
- }
-
- /**
- * Returns the URL prefix of this service, consisting of
- * {@code scheme://host[:port]}.
- *
- * @return The URL prefix.
- */
- public String getPrefix() {
- if (this.prefix == null)
- this.prefix = String.format("%s://%s:%s",
- this.scheme, this.host, this.port);
- return this.prefix;
- }
-
- /**
- * Returns the scheme used by this service.
- *
- * @return The scheme.
- */
- public String getScheme() {
- return this.scheme;
- }
-
- /**
- * Constructs a fully-qualified URL for this service using a given path.
- *
- * @param path The path to qualify.
- * @return The fully-qualified URL for the service.
- */
- public URL getUrl(String path) {
- try {
- if (HTTPS_SCHEME.equals(getScheme()) && httpsHandler != null) {
- // This branch is not currently covered by unit tests as I
- // could not figure out a generic way to get the default
- // HTTPS handler.
- return new URL(getScheme(), getHost(), getPort(), path,
- httpsHandler);
- } else {
- return new URL(getScheme(), getHost(), getPort(), path);
- }
- }
- catch (MalformedURLException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- /**
- * Issues a POST request against the service using a given path.
- *
- * @param path The request path.
- * @return The HTTP response.
- */
- public ResponseMessage post(String path) {
- return post(path, null);
- }
-
- /**
- * Issues a POST request against the service using a given path and
- * form arguments.
- *
- * @param path The request path.
- * @param args The form arguments.
- * @return The HTTP response.
- */
- public ResponseMessage post(String path, Map args) {
- RequestMessage request = new RequestMessage("POST");
- request.getHeader().put(
- "Content-Type", "application/x-www-form-urlencoded");
- if (count(args) > 0)
- request.setContent(Args.encode(args));
- return send(path, request);
- }
-
- /**
- * Issues a DELETE request against the service using a given path.
- *
- * @param path The request path.
- * @return The HTTP response.
- */
- public ResponseMessage delete(String path) {
- RequestMessage request = new RequestMessage("DELETE");
- return send(path, request);
- }
-
- /**
- * Issues a DELETE request against the service using a given path
- * and query arguments.
- *
- * @param path The request path.
- * @param args The query arguments.
- * @return The HTTP response.
- */
- public ResponseMessage delete(String path, Map args) {
- if (count(args) > 0)
- path = path + "?" + Args.encode(args);
- RequestMessage request = new RequestMessage("DELETE");
- return send(path, request);
- }
-
- /**
- * Opens a socket to this service.
- *
- * @return The socket.
- * @throws IOException
- */
- Socket open() throws IOException {
- if (this.scheme.equals("https")) {
- return SSL_SOCKET_FACTORY.createSocket(this.host, this.port);
- }
- return new Socket(this.host, this.port);
- }
-
- /**
- * Issue an HTTP request against the service using a given path and
- * request message.
- *
- * @param path The request path.
- * @param request The request message.
- * @return The HTTP response.
- */
- public ResponseMessage send(String path, RequestMessage request) {
- // Construct a full URL to the resource
- URL url = getUrl(path);
-
- // Create and initialize the connection object
- HttpURLConnection cn;
- try {
- cn = (HttpURLConnection)url.openConnection();
- }
- catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- if(cn instanceof HttpsURLConnection) {
- ((HttpsURLConnection)cn).setSSLSocketFactory(SSL_SOCKET_FACTORY);
- ((HttpsURLConnection)cn).setHostnameVerifier(HOSTNAME_VERIFIER);
- }
- cn.setUseCaches(false);
- cn.setAllowUserInteraction(false);
-
- // Set the request method
- String method = request.getMethod();
- try {
- cn.setRequestMethod(method);
- }
- catch (ProtocolException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
-
- // Add headers from request message
- Map header = request.getHeader();
- for (Entry entry : header.entrySet())
- cn.setRequestProperty(entry.getKey(), entry.getValue());
-
- // Add default headers that were absent from the request message
- for (Entry entry : defaultHeader.entrySet()) {
- String key = entry.getKey();
- if (header.containsKey(key)) continue;
- cn.setRequestProperty(key, entry.getValue());
- }
-
- // Write out request content, if any
- try {
- Object content = request.getContent();
- if (content != null) {
- cn.setDoOutput(true);
- OutputStream stream = cn.getOutputStream();
- OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8");
- writer.write((String)content);
- writer.close();
- }
- }
- catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
-
- if (VERBOSE_REQUESTS) {
- System.out.format("%s %s => ", method, url.toString());
- }
-
- // Execute the request
- try {
- cn.connect();
- }
- catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
-
- int status;
- try {
- status = cn.getResponseCode();
- }
- catch (IOException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
-
- InputStream input = null;
- try {
- input = status >= 400
- ? cn.getErrorStream()
- : cn.getInputStream();
- }
- catch (IOException e) { assert(false); }
-
- ResponseMessage response = new ResponseMessage(status, input);
-
- if (VERBOSE_REQUESTS) {
- System.out.format("%d\n", status);
- if (method.equals("POST")) {
- System.out.println(" " + request.getContent());
- }
- }
-
- if (status >= 400)
- throw HttpException.create(response);
-
- return response;
- }
-
- private static SSLSocketFactory createSSLFactory() {
- TrustManager[] trustAll = new TrustManager[]{
- new X509TrustManager() {
- public X509Certificate[] getAcceptedIssuers() { return null; }
- public void checkClientTrusted(X509Certificate[] certs, String authType) { }
- public void checkServerTrusted(X509Certificate[] certs, String authType) { }
- }
- };
- try {
- SSLContext context = SSLContext.getInstance("SSL");
- context.init(null, trustAll, new java.security.SecureRandom());
- return new SSLv3SocketFactory(context.getSocketFactory());
- } catch (Exception e) {
- throw new RuntimeException("Error setting up SSL socket factory: " + e, e);
- }
- }
-
- private static final class SSLv3SocketFactory extends SSLSocketFactory {
- private final SSLSocketFactory delegate;
-
- public static final String[] PROTOCOLS = {"SSLv3"};
-
- private SSLv3SocketFactory(SSLSocketFactory delegate) {
- this.delegate = delegate;
- }
-
- private Socket configure(Socket socket) {
- if (socket instanceof SSLSocket) {
- ((SSLSocket) socket).setEnabledProtocols(PROTOCOLS);
- }
- return socket;
- }
-
- @Override
- public String[] getDefaultCipherSuites() {
- return delegate.getDefaultCipherSuites();
- }
-
- @Override
- public String[] getSupportedCipherSuites() {
- return delegate.getSupportedCipherSuites();
- }
-
- @Override
- public Socket createSocket(Socket socket, String s, int i, boolean b) throws IOException {
- return configure(delegate.createSocket(socket, s, i, b));
- }
-
- @Override
- public Socket createSocket() throws IOException {
- return configure(delegate.createSocket());
- }
-
- @Override
- public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
- return configure(delegate.createSocket(s, i));
- }
-
- @Override
- public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException, UnknownHostException {
- return configure(delegate.createSocket(s, i, inetAddress, i1));
- }
-
- @Override
- public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
- return configure(delegate.createSocket(inetAddress, i));
- }
-
- @Override
- public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
- return configure(delegate.createSocket(inetAddress, i, inetAddress1, i1));
- }
- }
-
-}
-
diff --git a/splunk/com/splunk/PasswordCollection.java b/splunk/com/splunk/PasswordCollection.java
deleted file mode 100644
index d789af04..00000000
--- a/splunk/com/splunk/PasswordCollection.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2012 Splunk, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"): you may
- * not use this file except in compliance with the License. You may obtain
- * a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package com.splunk;
-
-/**
- * The {@code PasswordCollection} class represents a collection of credentials.
- */
-public class PasswordCollection extends EntityCollection {
-
- /**
- * Class constructor.
- *
- * @param service The connected {@code Service} instance.
- */
- PasswordCollection(Service service) {
- super(service, service.passwordEndPoint, Password.class);
- }
-
- /**
- * Class constructor.
- *
- * @param service The connected {@code Service} instance.
- * @param args Collection arguments that specify the number of entities to
- * return and how to sort them. See {@link CollectionArgs}.
- */
- PasswordCollection(Service service, Args args) {
- super(service, service.passwordEndPoint, Password.class, args);
- }
-
- /**
- * Creates a credential with a username and password.
- *
- * @param name The username.
- * @param password The password.
- *
- * @return The new credential.
- */
- public Password create(String name, String password) {
- Args args = new Args("password", password);
- return create(name, args);
- }
-
- /**
- * Creates a credential with a username, password, and realm.
- *
- * @param name The username.
- * @param password The password.
- * @param realm The credential realm.
- * @return The new credential.
- */
- public Password create(String name, String password, String realm) {
- Args args = new Args();
- args.put("password", password);
- args.put("realm", realm);
- return create(name, args);
- }
-
- /**
- * Returns the username for a credential.
- *
- * @param entry The {@code AtomEntry} object describing the credential.
- * @return The username.
- */
- @Override protected String itemKey(AtomEntry entry) {
- return (String)entry.content.get("username");
- }
-}
diff --git a/splunk/pom.xml b/splunk/pom.xml
new file mode 100644
index 00000000..7dede37e
--- /dev/null
+++ b/splunk/pom.xml
@@ -0,0 +1,97 @@
+
+
+ 4.0.0
+
+ splunk
+ 1.9.5
+
+ splunk-sdk-java
+ com.splunk
+ 1.0.1
+
+
+ TLSv1.2
+
+
+
+ junit
+ junit
+ 4.13.1
+ test
+
+
+ commons-cli
+ commons-cli
+ 1.2
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.0
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.3.0
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
+ ${skipTests}
+ alphabetical
+
+ ${https.protocols}
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.8
+
+
+
+ prepare-agent
+
+
+
+
+ report
+ test
+
+ report
+
+
+ target/test-report
+
+
+
+
+
+
+
+
diff --git a/splunk/com/splunk/Application.java b/splunk/src/main/java/com/splunk/Application.java
similarity index 100%
rename from splunk/com/splunk/Application.java
rename to splunk/src/main/java/com/splunk/Application.java
diff --git a/splunk/com/splunk/ApplicationArchive.java b/splunk/src/main/java/com/splunk/ApplicationArchive.java
similarity index 100%
rename from splunk/com/splunk/ApplicationArchive.java
rename to splunk/src/main/java/com/splunk/ApplicationArchive.java
diff --git a/splunk/com/splunk/ApplicationSetup.java b/splunk/src/main/java/com/splunk/ApplicationSetup.java
similarity index 100%
rename from splunk/com/splunk/ApplicationSetup.java
rename to splunk/src/main/java/com/splunk/ApplicationSetup.java
diff --git a/splunk/com/splunk/ApplicationUpdate.java b/splunk/src/main/java/com/splunk/ApplicationUpdate.java
similarity index 100%
rename from splunk/com/splunk/ApplicationUpdate.java
rename to splunk/src/main/java/com/splunk/ApplicationUpdate.java
diff --git a/splunk/com/splunk/Args.java b/splunk/src/main/java/com/splunk/Args.java
similarity index 98%
rename from splunk/com/splunk/Args.java
rename to splunk/src/main/java/com/splunk/Args.java
index d682a685..4e93f36a 100644
--- a/splunk/com/splunk/Args.java
+++ b/splunk/src/main/java/com/splunk/Args.java
@@ -28,7 +28,7 @@
*
* This extension is used mainly for encoding arguments for UTF8 transmission
* to a Splunk instance in a key=value pairing for a string, or
- * key=value1&key=value2 (and so on) for an array of strings.
+ * {@code key=value1&key=value2 } (and so on) for an array of strings.
*/
public class Args extends LinkedHashMap {
diff --git a/splunk/com/splunk/AtomEntry.java b/splunk/src/main/java/com/splunk/AtomEntry.java
similarity index 100%
rename from splunk/com/splunk/AtomEntry.java
rename to splunk/src/main/java/com/splunk/AtomEntry.java
diff --git a/splunk/com/splunk/AtomFeed.java b/splunk/src/main/java/com/splunk/AtomFeed.java
similarity index 100%
rename from splunk/com/splunk/AtomFeed.java
rename to splunk/src/main/java/com/splunk/AtomFeed.java
diff --git a/splunk/com/splunk/AtomObject.java b/splunk/src/main/java/com/splunk/AtomObject.java
similarity index 100%
rename from splunk/com/splunk/AtomObject.java
rename to splunk/src/main/java/com/splunk/AtomObject.java
diff --git a/splunk/com/splunk/BaseService.java b/splunk/src/main/java/com/splunk/BaseService.java
similarity index 100%
rename from splunk/com/splunk/BaseService.java
rename to splunk/src/main/java/com/splunk/BaseService.java
diff --git a/splunk/com/splunk/BooleanComparison.java b/splunk/src/main/java/com/splunk/BooleanComparison.java
similarity index 100%
rename from splunk/com/splunk/BooleanComparison.java
rename to splunk/src/main/java/com/splunk/BooleanComparison.java
diff --git a/splunk/com/splunk/BooleanPivotColumnSplit.java b/splunk/src/main/java/com/splunk/BooleanPivotColumnSplit.java
similarity index 100%
rename from splunk/com/splunk/BooleanPivotColumnSplit.java
rename to splunk/src/main/java/com/splunk/BooleanPivotColumnSplit.java
diff --git a/splunk/com/splunk/BooleanPivotFilter.java b/splunk/src/main/java/com/splunk/BooleanPivotFilter.java
similarity index 87%
rename from splunk/com/splunk/BooleanPivotFilter.java
rename to splunk/src/main/java/com/splunk/BooleanPivotFilter.java
index c355f405..3e08d6c0 100644
--- a/splunk/com/splunk/BooleanPivotFilter.java
+++ b/splunk/src/main/java/com/splunk/BooleanPivotFilter.java
@@ -43,8 +43,11 @@ JsonElement toJson() {
addCommonFields(root);
- root.add("comparator", new JsonPrimitive(this.comparison.toString()));
- root.add("compareTo", new JsonPrimitive(this.comparisonValue));
+ JsonObject filterRule = new JsonObject();
+ filterRule.add("comparator", new JsonPrimitive(this.comparison.toString()));
+ filterRule.add("compareTo", new JsonPrimitive(this.comparisonValue));
+
+ root.add("rule", filterRule);
return root;
}
diff --git a/splunk/com/splunk/BooleanPivotRowSplit.java b/splunk/src/main/java/com/splunk/BooleanPivotRowSplit.java
similarity index 100%
rename from splunk/com/splunk/BooleanPivotRowSplit.java
rename to splunk/src/main/java/com/splunk/BooleanPivotRowSplit.java
diff --git a/splunk/com/splunk/CollectionArgs.java b/splunk/src/main/java/com/splunk/CollectionArgs.java
similarity index 100%
rename from splunk/com/splunk/CollectionArgs.java
rename to splunk/src/main/java/com/splunk/CollectionArgs.java
diff --git a/util/com/splunk/Command.java b/splunk/src/main/java/com/splunk/Command.java
similarity index 98%
rename from util/com/splunk/Command.java
rename to splunk/src/main/java/com/splunk/Command.java
index af362071..4dbd39b6 100644
--- a/util/com/splunk/Command.java
+++ b/splunk/src/main/java/com/splunk/Command.java
@@ -32,7 +32,11 @@
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
-// Processes and capture command options and arguments
+/**
+ * This class serves as an example and is unsupported.
+ *
+ * Processes and capture command options and arguments
+ */
public class Command {
private String appName;
private Options rules = new Options();
diff --git a/splunk/com/splunk/ConfCollection.java b/splunk/src/main/java/com/splunk/ConfCollection.java
similarity index 100%
rename from splunk/com/splunk/ConfCollection.java
rename to splunk/src/main/java/com/splunk/ConfCollection.java
diff --git a/splunk/com/splunk/DataModel.java b/splunk/src/main/java/com/splunk/DataModel.java
similarity index 88%
rename from splunk/com/splunk/DataModel.java
rename to splunk/src/main/java/com/splunk/DataModel.java
index 98fe0b04..ce42f6f9 100644
--- a/splunk/com/splunk/DataModel.java
+++ b/splunk/src/main/java/com/splunk/DataModel.java
@@ -44,6 +44,7 @@ public class DataModel extends Entity {
private boolean accelerationEnabled;
private String earliestAcceleratedTime;
private String accelerationCronSchedule;
+ private boolean manualRebuilds;
DataModel(Service service, String path) {
super(service, path);
@@ -187,6 +188,15 @@ private void parseAcceleration(String input) {
earliestAcceleratedTime = entry.getValue().getAsString();
} else if (entry.getKey().equals("cron_schedule")) {
accelerationCronSchedule = entry.getValue().getAsString();
+ } else if (entry.getKey().equals("manual_rebuilds")) {
+ if (((JsonPrimitive)entry.getValue()).isBoolean()) {
+ manualRebuilds = entry.getValue().getAsBoolean();
+ } else if (((JsonPrimitive)entry.getValue()).isNumber()) {
+ manualRebuilds = entry.getValue().getAsInt() != 0;
+ } else {
+ throw new RuntimeException("splunkd returned an unknown value " + entry.getValue().toString() +
+ " for whether manual_rebuilds is enabled.");
+ }
} else {
// Allow new keys without complaining
}
@@ -250,12 +260,32 @@ public void setAccelerationCronSchedule(String accelerationCronSchedule) {
toUpdate.put("cron_schedule", accelerationCronSchedule);
}
+ /**
+ * This setting prevents outdated summaries from being rebuilt by the
+ * 'summarize' command.
+ *
+ * @return whether manual rebuilds are enabled for this data model.
+ */
+ public boolean isManualRebuilds() {
+ return this.manualRebuilds;
+ }
+
+ /**
+ * Enable or disable manual rebuilds on this data model.
+ *
+ * @param enabled true enabled, false disables.
+ */
+ public void setManualRebuilds(boolean enabled) {
+ this.manualRebuilds = enabled;
+ toUpdate.put("manual_rebuilds", enabled);
+ }
+
@Override
public void update() {
// We have to do some munging on the acceleration fields to pass them as JSON
// to the server.
Map accelerationMap = new HashMap();
- for (String key : new String[] {"enabled", "earliest_time", "cron_schedule"}) {
+ for (String key : new String[] {"enabled", "earliest_time", "cron_schedule", "manual_rebuilds"}) {
if (toUpdate.containsKey(key)) {
accelerationMap.put(key, toUpdate.get(key));
toUpdate.remove(key);
diff --git a/splunk/com/splunk/DataModelArgs.java b/splunk/src/main/java/com/splunk/DataModelArgs.java
similarity index 100%
rename from splunk/com/splunk/DataModelArgs.java
rename to splunk/src/main/java/com/splunk/DataModelArgs.java
diff --git a/splunk/com/splunk/DataModelCalculation.java b/splunk/src/main/java/com/splunk/DataModelCalculation.java
similarity index 100%
rename from splunk/com/splunk/DataModelCalculation.java
rename to splunk/src/main/java/com/splunk/DataModelCalculation.java
diff --git a/splunk/com/splunk/DataModelCollection.java b/splunk/src/main/java/com/splunk/DataModelCollection.java
similarity index 100%
rename from splunk/com/splunk/DataModelCollection.java
rename to splunk/src/main/java/com/splunk/DataModelCollection.java
diff --git a/splunk/com/splunk/DataModelConstraint.java b/splunk/src/main/java/com/splunk/DataModelConstraint.java
similarity index 100%
rename from splunk/com/splunk/DataModelConstraint.java
rename to splunk/src/main/java/com/splunk/DataModelConstraint.java
diff --git a/splunk/com/splunk/DataModelField.java b/splunk/src/main/java/com/splunk/DataModelField.java
similarity index 92%
rename from splunk/com/splunk/DataModelField.java
rename to splunk/src/main/java/com/splunk/DataModelField.java
index a8d71b05..d83dca1c 100644
--- a/splunk/com/splunk/DataModelField.java
+++ b/splunk/src/main/java/com/splunk/DataModelField.java
@@ -121,7 +121,12 @@ public static DataModelField parse(JsonElement fieldJson) {
} else if (entry.getKey().equals("displayName")) {
field.displayName = entry.getValue().getAsString();
} else if (entry.getKey().equals("comment")) {
- field.comment = entry.getValue().getAsString();
+ //Before Splunk 7, comment value was just a string but now, its JSON ("comment": {"description": "The body of a message."})
+ if(entry.getValue().isJsonObject()) {
+ field.comment = entry.getValue().getAsJsonObject().get("description").getAsString();
+ } else {
+ field.comment = entry.getValue().getAsString();
+ }
} else if (entry.getKey().equals("editable")) {
field.editable = entry.getValue().getAsBoolean();
} else if (entry.getKey().equals("fieldSearch")) {
diff --git a/splunk/com/splunk/DataModelObject.java b/splunk/src/main/java/com/splunk/DataModelObject.java
similarity index 100%
rename from splunk/com/splunk/DataModelObject.java
rename to splunk/src/main/java/com/splunk/DataModelObject.java
diff --git a/splunk/com/splunk/DataModelSearch.java b/splunk/src/main/java/com/splunk/DataModelSearch.java
similarity index 100%
rename from splunk/com/splunk/DataModelSearch.java
rename to splunk/src/main/java/com/splunk/DataModelSearch.java
diff --git a/splunk/com/splunk/DataModelTransaction.java b/splunk/src/main/java/com/splunk/DataModelTransaction.java
similarity index 100%
rename from splunk/com/splunk/DataModelTransaction.java
rename to splunk/src/main/java/com/splunk/DataModelTransaction.java
diff --git a/splunk/com/splunk/DeploymentClient.java b/splunk/src/main/java/com/splunk/DeploymentClient.java
similarity index 100%
rename from splunk/com/splunk/DeploymentClient.java
rename to splunk/src/main/java/com/splunk/DeploymentClient.java
diff --git a/splunk/com/splunk/DeploymentServer.java b/splunk/src/main/java/com/splunk/DeploymentServer.java
similarity index 100%
rename from splunk/com/splunk/DeploymentServer.java
rename to splunk/src/main/java/com/splunk/DeploymentServer.java
diff --git a/splunk/com/splunk/DeploymentServerClass.java b/splunk/src/main/java/com/splunk/DeploymentServerClass.java
similarity index 100%
rename from splunk/com/splunk/DeploymentServerClass.java
rename to splunk/src/main/java/com/splunk/DeploymentServerClass.java
diff --git a/splunk/com/splunk/DeploymentTenant.java b/splunk/src/main/java/com/splunk/DeploymentTenant.java
similarity index 100%
rename from splunk/com/splunk/DeploymentTenant.java
rename to splunk/src/main/java/com/splunk/DeploymentTenant.java
diff --git a/splunk/com/splunk/DistributedConfiguration.java b/splunk/src/main/java/com/splunk/DistributedConfiguration.java
similarity index 100%
rename from splunk/com/splunk/DistributedConfiguration.java
rename to splunk/src/main/java/com/splunk/DistributedConfiguration.java
diff --git a/splunk/com/splunk/DistributedPeer.java b/splunk/src/main/java/com/splunk/DistributedPeer.java
similarity index 98%
rename from splunk/com/splunk/DistributedPeer.java
rename to splunk/src/main/java/com/splunk/DistributedPeer.java
index e9f7fc9e..2a42a75f 100644
--- a/splunk/com/splunk/DistributedPeer.java
+++ b/splunk/src/main/java/com/splunk/DistributedPeer.java
@@ -37,8 +37,8 @@ public class DistributedPeer extends Entity {
*
* @return The build number.
*/
- public int getBuild() {
- return getInteger("build");
+ public String getBuild() {
+ return getString("build");
}
/**
diff --git a/splunk/com/splunk/Entity.java b/splunk/src/main/java/com/splunk/Entity.java
similarity index 94%
rename from splunk/com/splunk/Entity.java
rename to splunk/src/main/java/com/splunk/Entity.java
index 831b9852..a4856e2a 100644
--- a/splunk/com/splunk/Entity.java
+++ b/splunk/src/main/java/com/splunk/Entity.java
@@ -50,6 +50,8 @@ protected String actionPath(String action) {
return path + "/enable";
if (action.equals("remove"))
return path;
+ if (action.equals("acl"))
+ return path + "/acl";
throw new IllegalArgumentException("Invalid action: " + action);
}
@@ -450,6 +452,26 @@ public void update() {
update(Collections.EMPTY_MAP);
}
+
+ /**
+ * Update the access control list (ACL) properties for this entity,
+ *
+ * @param args: Properties to update for this entity.
+ * Required Properties in 'args'
+ * - `owner`: The Splunk username, such as "admin". A value of "nobody" means no specific user.
+ * - `sharing`: A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system".
+ */
+ public void aclUpdate(Map args){
+ if(!args.containsKey("sharing")){
+ throw new IllegalArgumentException("Required argument 'sharing' is missing.");
+ }
+ if(!args.containsKey("owner")){
+ throw new IllegalArgumentException("Required argument 'owner' is missing.");
+ }
+ service.post(actionPath("acl"), args);
+ invalidate();
+ }
+
/**
* Removes this entity from its corresponding collection.
*/
diff --git a/splunk/com/splunk/EntityCollection.java b/splunk/src/main/java/com/splunk/EntityCollection.java
similarity index 100%
rename from splunk/com/splunk/EntityCollection.java
rename to splunk/src/main/java/com/splunk/EntityCollection.java
diff --git a/splunk/com/splunk/EntityMetadata.java b/splunk/src/main/java/com/splunk/EntityMetadata.java
similarity index 100%
rename from splunk/com/splunk/EntityMetadata.java
rename to splunk/src/main/java/com/splunk/EntityMetadata.java
diff --git a/splunk/com/splunk/EvalDataModelCalculation.java b/splunk/src/main/java/com/splunk/EvalDataModelCalculation.java
similarity index 100%
rename from splunk/com/splunk/EvalDataModelCalculation.java
rename to splunk/src/main/java/com/splunk/EvalDataModelCalculation.java
diff --git a/splunk/com/splunk/Event.java b/splunk/src/main/java/com/splunk/Event.java
similarity index 100%
rename from splunk/com/splunk/Event.java
rename to splunk/src/main/java/com/splunk/Event.java
diff --git a/splunk/com/splunk/EventType.java b/splunk/src/main/java/com/splunk/EventType.java
similarity index 98%
rename from splunk/com/splunk/EventType.java
rename to splunk/src/main/java/com/splunk/EventType.java
index 293ba4ae..4766f256 100644
--- a/splunk/com/splunk/EventType.java
+++ b/splunk/src/main/java/com/splunk/EventType.java
@@ -91,6 +91,7 @@ public void setDescription(String description) {
* take effect immediately.
* @see Entity#disable
* @see Entity#enable
+ * @param disabled The boolean flag
*/
public void setDisabled(boolean disabled) {
setCacheValue("disabled", disabled);
diff --git a/splunk/com/splunk/EventTypeCollection.java b/splunk/src/main/java/com/splunk/EventTypeCollection.java
similarity index 100%
rename from splunk/com/splunk/EventTypeCollection.java
rename to splunk/src/main/java/com/splunk/EventTypeCollection.java
diff --git a/splunk/com/splunk/ExportResultsStream.java b/splunk/src/main/java/com/splunk/ExportResultsStream.java
similarity index 100%
rename from splunk/com/splunk/ExportResultsStream.java
rename to splunk/src/main/java/com/splunk/ExportResultsStream.java
diff --git a/splunk/com/splunk/FieldType.java b/splunk/src/main/java/com/splunk/FieldType.java
similarity index 100%
rename from splunk/com/splunk/FieldType.java
rename to splunk/src/main/java/com/splunk/FieldType.java
diff --git a/splunk/com/splunk/FiredAlert.java b/splunk/src/main/java/com/splunk/FiredAlert.java
similarity index 100%
rename from splunk/com/splunk/FiredAlert.java
rename to splunk/src/main/java/com/splunk/FiredAlert.java
diff --git a/splunk/com/splunk/FiredAlertGroup.java b/splunk/src/main/java/com/splunk/FiredAlertGroup.java
similarity index 100%
rename from splunk/com/splunk/FiredAlertGroup.java
rename to splunk/src/main/java/com/splunk/FiredAlertGroup.java
diff --git a/splunk/com/splunk/FiredAlertGroupCollection.java b/splunk/src/main/java/com/splunk/FiredAlertGroupCollection.java
similarity index 100%
rename from splunk/com/splunk/FiredAlertGroupCollection.java
rename to splunk/src/main/java/com/splunk/FiredAlertGroupCollection.java
diff --git a/splunk/com/splunk/GeoIPDataModelCalculation.java b/splunk/src/main/java/com/splunk/GeoIPDataModelCalculation.java
similarity index 100%
rename from splunk/com/splunk/GeoIPDataModelCalculation.java
rename to splunk/src/main/java/com/splunk/GeoIPDataModelCalculation.java
diff --git a/splunk/com/splunk/HttpException.java b/splunk/src/main/java/com/splunk/HttpException.java
similarity index 93%
rename from splunk/com/splunk/HttpException.java
rename to splunk/src/main/java/com/splunk/HttpException.java
index 51e5b6a2..4bdd7d17 100644
--- a/splunk/com/splunk/HttpException.java
+++ b/splunk/src/main/java/com/splunk/HttpException.java
@@ -63,17 +63,17 @@ static HttpException create(ResponseMessage response) {
s.appendCodePoint(c);
}
- String detail = "";
+ // Initialize detail with raw response data. Prevents XML parser failures.
+ String detail = s.toString();
try {
// Attempt to read the error detail from the error response content as XML
- Document document = Xml.parse(new ByteArrayInputStream(detail.getBytes()));
+ Document document = Xml.parse(new ByteArrayInputStream(detail.getBytes()), true);
NodeList msgs = document.getElementsByTagName("msg");
if (msgs.getLength() > 0)
detail = msgs.item(0).getTextContent();
}
catch (Exception e) {
- // Not an XML document; return the raw string.
- detail = s.toString();
+ // Not an XML document; keep the raw string.
}
String message = String.format("HTTP %d", status);
diff --git a/splunk/src/main/java/com/splunk/HttpService.java b/splunk/src/main/java/com/splunk/HttpService.java
new file mode 100644
index 00000000..70b99269
--- /dev/null
+++ b/splunk/src/main/java/com/splunk/HttpService.java
@@ -0,0 +1,614 @@
+/*
+ * Copyright 2012 Splunk, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"): you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.splunk;
+
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.*;
+import java.security.cert.X509Certificate;
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * The {@code HttpService} class represents a generic HTTP service at a given
+ * address ({@code host:port}), accessed using a given protocol scheme
+ * ({@code http} or {@code https}).
+ */
+public class HttpService {
+ // For debugging purposes
+ private static final boolean VERBOSE_REQUESTS = false;
+ protected static SSLSecurityProtocol sslSecurityProtocol = null;
+
+ /**
+ * Boolean flag for validating certificates at either of the sides (client/server).
+ * If true, then it will check and validate relevant certificates otherwise, in case of false, it will accept all certificates.
+ * For PROD environment, TRUE is strongly recommended, whereas working in localhost OR development environment, FALSE is used.
+ * Default Value: TRUE
+ */
+ protected static boolean validateCertificates = true;
+
+ private static SSLSocketFactory sslSocketFactory = createSSLFactory();
+ private static String HTTPS_SCHEME = "https";
+ private static String HTTP_SCHEME = "http";
+ private static List VALID_HOSTS = new ArrayList(Arrays.asList("localhost", "127.0.0.1", "::1"));
+
+ private static final HostnameVerifier HOSTNAME_VERIFIER = new HostnameVerifier() {
+ public boolean verify(String s, SSLSession sslSession) {
+ if(VALID_HOSTS.contains(s)){
+ return true;
+ } else {
+ HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
+ return hv.verify(s, sslSession);
+ }
+ }
+ };
+
+ /**
+ * A variable to hold an optional custom HTTPS handler
+ */
+ protected URLStreamHandler httpsHandler = null;
+
+ /**
+ * The scheme used to access the service.
+ */
+ protected String scheme = "https";
+
+ /**
+ * The host name of the service.
+ */
+ protected String host = "localhost";
+
+ /**
+ * The port number of the service.
+ */
+ protected int port = 8089;
+
+ protected Integer connectTimeout = null;
+ protected Integer readTimeout = null;
+
+ private String prefix = null;
+
+ static Map defaultHeader = new HashMap() {{
+ put("User-Agent", "splunk-sdk-java/1.9.5");
+ put("Accept", "*/*");
+ }};
+
+ protected Map customHeaders = new HashMap<>();
+
+ protected SimpleCookieStore cookieStore = new SimpleCookieStore();
+
+ /**
+ * Constructs a new {@code HttpService} instance.
+ */
+ public HttpService() {
+ }
+
+ /**
+ * Constructs a new {@code HttpService} instance at the given host.
+ *
+ * @param host The host name of the service.
+ */
+ public HttpService(String host) {
+ this.host = host;
+ }
+
+ /**
+ * Constructs a new {@code HttpService} instance at the given host and port.
+ *
+ * @param host The host name of the service.
+ * @param port The port number of the service.
+ */
+ public HttpService(String host, int port) {
+ this.host = host;
+ this.port = port;
+ }
+
+ /**
+ * Constructs a new {@code HttpService} instance using the given host,
+ * port, and scheme.
+ *
+ * @param host The host name of the service.
+ * @param port The port number of the service.
+ * @param scheme Scheme for accessing the service ({@code http} or
+ * {@code https}).
+ */
+ public HttpService(String host, int port, String scheme) {
+ this.host = host;
+ this.port = port;
+ this.scheme = scheme;
+ }
+
+ /**
+ * Constructs a new {@code HttpService} instance using the given host,
+ * port, and scheme, and instructing it to use the specified HTTPS handler.
+ *
+ * @param host The host name of the service.
+ * @param port The port number of the service.
+ * @param scheme Scheme for accessing the service ({@code http} or
+ * {@code https}).
+ * @param httpsHandler A custom URL Stream handler.
+ */
+ public HttpService(String host, int port, String scheme,
+ URLStreamHandler httpsHandler) {
+ this.host = host;
+ this.port = port;
+ this.scheme = scheme;
+ this.httpsHandler = httpsHandler;
+ }
+
+ // Returns the count of arguments in the given {@code args} map.
+ private static int count(Map args) {
+ if (args == null) return 0;
+ return args.size();
+ }
+
+ /**
+ * Issues an HTTP GET request against the service using a given path.
+ *
+ * @param path The request path.
+ * @return The HTTP response.
+ */
+ public ResponseMessage get(String path) {
+ return send(path, new RequestMessage("GET"));
+ }
+
+ /**
+ * Issues an HTTP GET request against the service using a given path and
+ * query arguments.
+ *
+ * @param path The request path.
+ * @param args The query arguments.
+ * @return The HTTP response.
+ */
+ public ResponseMessage get(String path, Map args) {
+ if (count(args) > 0)
+ path = path + "?" + Args.encode(args);
+ RequestMessage request = new RequestMessage("GET");
+ return send(path, request);
+ }
+
+ /**
+ * Returns the host name of this service.
+ *
+ * @return The host name.
+ */
+ public String getHost() {
+ return this.host;
+ }
+
+ /**
+ * Returns the port number of this service.
+ *
+ * @return The port number.
+ */
+ public int getPort() {
+ return this.port;
+ }
+
+ /**
+ * Sets Custom Headers of this service
+ *
+ * @param headers The custom headers.
+ */
+ public void setCustomHeaders(Map headers) {
+ if (Objects.nonNull(headers)) {
+ customHeaders = headers;
+ }
+ }
+
+ /**
+ * Returns the SSL security protocol of this service.
+ *
+ * @return The SSL security protocol.
+ */
+ public static SSLSecurityProtocol getSslSecurityProtocol() {
+ return sslSecurityProtocol;
+ }
+
+ /**
+ * Sets the SSL security protocol of this service.
+ * @param securityProtocol The SSLSecurityProtocal instance
+ */
+ public static void setSslSecurityProtocol(SSLSecurityProtocol securityProtocol) {
+ // Only update the SSL_SOCKET_FACTORY if changing protocols
+ if (sslSecurityProtocol != securityProtocol) {
+ sslSecurityProtocol = securityProtocol;
+ sslSocketFactory = createSSLFactory();
+ }
+ }
+
+ /**
+ * Adds list of Cluster Master Hosts to the list of Valid Hosts for Hostname verification.
+ * @param searchHeadService Splunk SearchHead Service instance
+ */
+ public static void addClusterMasterURIsToHosts(Service searchHeadService){
+ VALID_HOSTS.addAll(searchHeadService.getClusterMasters());
+ }
+
+ /**
+ * Returns the URL prefix of this service, consisting of
+ * {@code scheme://host[:port]}.
+ *
+ * @return The URL prefix.
+ */
+ public String getPrefix() {
+ if (this.prefix == null)
+ this.prefix = String.format("%s://%s:%s",
+ this.scheme, this.host, this.port);
+ return this.prefix;
+ }
+
+ /**
+ * Returns the scheme used by this service.
+ *
+ * @return The scheme.
+ */
+ public String getScheme() {
+ return this.scheme;
+ }
+
+ /**
+ * Constructs a fully-qualified URL for this service using a given path.
+ *
+ * @param path The path to qualify.
+ * @return The fully-qualified URL for the service.
+ */
+ public URL getUrl(String path) {
+ try {
+ if (HTTPS_SCHEME.equals(getScheme()) && httpsHandler != null) {
+ // This branch is not currently covered by unit tests as I
+ // could not figure out a generic way to get the default
+ // HTTPS handler.
+ return new URL(getScheme(), getHost(), getPort(), path,
+ httpsHandler);
+ } else {
+ return new URL(getScheme(), getHost(), getPort(), path);
+ }
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Returns all the stored custom headers
+ *
+ * @return customHeaders The custom headers
+ */
+ public Map getCustomHeaders() {
+ return customHeaders;
+ }
+
+ /**
+ * Returns all the stored cookies
+ *
+ * @return All cookies as in a string in the format key=value; key=value; etc=etc
+ */
+ public String stringifyCookies() {
+ return cookieStore.getCookies();
+ }
+
+ /**
+ * Adds the passed cookie header to the cookieStore
+ *
+ * @param setCookieHeader The result from a getRequestHeader("Set-Cookie") call
+ */
+ public void addCookie(String setCookieHeader) {
+ cookieStore.add(setCookieHeader);
+ }
+
+ /**
+ * Removes all cookies from the cookieStore
+ */
+ public void removeAllCookies() {
+ cookieStore.removeAll();
+ }
+
+ /**
+ * Returns true if the cookieStore has any Splunk Authorization cookies, false otherwise
+ *
+ * @return True if there are cookies, false otherwise
+ */
+ public Boolean hasSplunkAuthCookies() {
+ return cookieStore.hasSplunkAuthCookie();
+ }
+
+ /**
+ * Returns the connect timeout used by this service.
+ *
+ * @return The timeout in milliseconds.
+ */
+ public Integer getConnectTimeout() {
+ return connectTimeout;
+ }
+
+ /**
+ * Sets a specified timeout value, in milliseconds, to be used when opening a communications link.
+ *
+ * @param connectTimeout timeout in milliseconds, a timeout of zero is interpreted as an infinite timeout.
+ */
+ public void setConnectTimeout(Integer connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ }
+
+ /**
+ * Returns the read timeout used by this service.
+ *
+ * @return The timeout in milliseconds.
+ */
+ public Integer getReadTimeout() {
+ return readTimeout;
+ }
+
+ /**
+ * Sets a specified timeout value, in milliseconds, to be used when reading from a communications link.
+ *
+ * @param readTimeout timeout in milliseconds, a timeout of zero is interpreted as an infinite timeout.
+ */
+ public void setReadTimeout(Integer readTimeout) {
+ this.readTimeout = readTimeout;
+ }
+
+ /**
+ * Issues a POST request against the service using a given path.
+ *
+ * @param path The request path.
+ * @return The HTTP response.
+ */
+ public ResponseMessage post(String path) {
+ return post(path, null);
+ }
+
+ /**
+ * Issues a POST request against the service using a given path and
+ * form arguments.
+ *
+ * @param path The request path.
+ * @param args The form arguments.
+ * @return The HTTP response.
+ */
+ public ResponseMessage post(String path, Map args) {
+ RequestMessage request = new RequestMessage("POST");
+ request.getHeader().put(
+ "Content-Type", "application/x-www-form-urlencoded");
+ if (count(args) > 0)
+ request.setContent(Args.encode(args));
+ return send(path, request);
+ }
+
+ /**
+ * Issues a DELETE request against the service using a given path.
+ *
+ * @param path The request path.
+ * @return The HTTP response.
+ */
+ public ResponseMessage delete(String path) {
+ RequestMessage request = new RequestMessage("DELETE");
+ return send(path, request);
+ }
+
+ /**
+ * Issues a DELETE request against the service using a given path
+ * and query arguments.
+ *
+ * @param path The request path.
+ * @param args The query arguments.
+ * @return The HTTP response.
+ */
+ public ResponseMessage delete(String path, Map args) {
+ if (count(args) > 0)
+ path = path + "?" + Args.encode(args);
+ RequestMessage request = new RequestMessage("DELETE");
+ return send(path, request);
+ }
+
+ /**
+ * Opens a socket to this service.
+ *
+ * @return The socket.
+ * @throws IOException
+ */
+ Socket open() throws IOException {
+ if (this.scheme.equals("https")) {
+ return sslSocketFactory.createSocket(this.host, this.port);
+ }
+ return new Socket(this.host, this.port);
+ }
+
+ /**
+ * Issue an HTTP request against the service using a given path and
+ * request message.
+ *
+ * @param path The request path.
+ * @param request The request message.
+ * @return The HTTP response.
+ */
+ public ResponseMessage send(String path, RequestMessage request) {
+ // Construct a full URL to the resource
+ URL url = getUrl(path);
+ // Create and initialize the connection object
+ HttpURLConnection cn;
+ try {
+ cn = (HttpURLConnection) url.openConnection();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ if (cn instanceof HttpsURLConnection) {
+ ((HttpsURLConnection) cn).setSSLSocketFactory(sslSocketFactory);
+ ((HttpsURLConnection) cn).setHostnameVerifier(HOSTNAME_VERIFIER);
+ }
+ cn.setUseCaches(false);
+ cn.setAllowUserInteraction(false);
+ cn.setConnectTimeout(connectTimeout == null ? 0 : connectTimeout);
+ cn.setReadTimeout(readTimeout == null ? 0 : readTimeout);
+
+ // Set the request method
+ String method = request.getMethod();
+ try {
+ cn.setRequestMethod(method);
+ } catch (ProtocolException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ // Add headers from request message
+ Map header = request.getHeader();
+ for (Entry entry : header.entrySet())
+ cn.setRequestProperty(entry.getKey(), entry.getValue());
+ // Add default headers that were absent from the request message
+ for (Entry entry : defaultHeader.entrySet()) {
+ String key = entry.getKey();
+ if (header.containsKey(key)) continue;
+ cn.setRequestProperty(key, entry.getValue());
+ }
+ // Add Custom Headers
+ for (Entry entry: customHeaders.entrySet()) {
+ String key = entry.getKey();
+ if (!header.containsKey(key)) {
+ cn.setRequestProperty(key, entry.getValue());
+ }
+ }
+
+ // Add cookies to header
+ cn.setRequestProperty("Cookie", cookieStore.getCookies());
+
+ // Write out request content, if any
+ try {
+ Object content = request.getContent();
+ if (content != null) {
+ cn.setDoOutput(true);
+ OutputStream stream = cn.getOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(stream, "UTF-8");
+ writer.write((String) content);
+ writer.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ if (VERBOSE_REQUESTS) {
+ System.out.format("%s %s => ", method, url.toString());
+ }
+
+ // Execute the request
+ try {
+ cn.connect();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ int status;
+ try {
+ status = cn.getResponseCode();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+
+ InputStream input = null;
+ try {
+ input = status >= 400
+ ? cn.getErrorStream()
+ : cn.getInputStream();
+ } catch (IOException e) {
+ assert (false);
+ }
+
+ // Add cookies to cookie Store
+ Map> headers = cn.getHeaderFields();
+ if (headers.containsKey("Set-Cookie")) {
+ for (String cookieHeader : headers.get("Set-Cookie")) {
+ if (cookieHeader != null && cookieHeader.length() > 0)
+ cookieStore.add(cookieHeader);
+ }
+ }
+
+ ResponseMessage response = new ResponseMessage(status, input);
+
+ if (VERBOSE_REQUESTS) {
+ System.out.format("%d\n", status);
+ if (method.equals("POST")) {
+ System.out.println(" " + request.getContent());
+ }
+ }
+
+ if (status >= 400)
+ throw HttpException.create(response);
+
+ return response;
+ }
+
+ public static void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
+ if (sslSocketFactory == null)
+ throw new IllegalArgumentException("The sslSocketFactory cannot be null.");
+ HttpService.sslSocketFactory = sslSocketFactory;
+ }
+
+ public static SSLSocketFactory getSSLSocketFactory() {
+ return HttpService.sslSocketFactory;
+ }
+
+ public static void setValidateCertificates(boolean validateCertificate) {
+ // update the SSL_SOCKET_FACTORY if validateCertificates flag is changed
+ if (validateCertificates != validateCertificate) {
+ validateCertificates = validateCertificate;
+ sslSocketFactory = createSSLFactory();
+ }
+ }
+
+ public static SSLSocketFactory createSSLFactory() {
+
+ try {
+ SSLContext context;
+ if (sslSecurityProtocol != null) {
+ String contextStr = sslSecurityProtocol.toString().contains("SSL") ? "SSL" : "TLS";
+ context = SSLContext.getInstance(contextStr);
+ } else if (System.getProperty("java.version").compareTo("1.8") >= 0) {
+ context = SSLContext.getInstance("TLS");
+ } else {
+ context = SSLContext.getDefault();
+ }
+
+ if (validateCertificates) {
+ context.init(null, null, null);
+ // For now this check is set as null.
+ // TODO: Implementation logic for validating client certificate.
+ } else {
+ TrustManager[] trustAll = new TrustManager[]{
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs, String authType) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs, String authType) {
+ }
+ }
+ };
+ context.init(null, trustAll, null);
+ }
+
+ return context.getSocketFactory();
+ } catch (Exception e) {
+ throw new RuntimeException("Error setting up SSL socket factory: " + e, e);
+ }
+ }
+
+}
+
diff --git a/splunk/com/splunk/IPv4Comparison.java b/splunk/src/main/java/com/splunk/IPv4Comparison.java
similarity index 100%
rename from splunk/com/splunk/IPv4Comparison.java
rename to splunk/src/main/java/com/splunk/IPv4Comparison.java
diff --git a/splunk/com/splunk/IPv4PivotFilter.java b/splunk/src/main/java/com/splunk/IPv4PivotFilter.java
similarity index 86%
rename from splunk/com/splunk/IPv4PivotFilter.java
rename to splunk/src/main/java/com/splunk/IPv4PivotFilter.java
index 78490399..9fe794d4 100644
--- a/splunk/com/splunk/IPv4PivotFilter.java
+++ b/splunk/src/main/java/com/splunk/IPv4PivotFilter.java
@@ -44,8 +44,11 @@ JsonElement toJson() {
addCommonFields(root);
- root.add("comparator", new JsonPrimitive(this.comparison.toString()));
- root.add("compareTo", new JsonPrimitive(this.comparisonValue));
+ JsonObject filterRule = new JsonObject();
+ filterRule.add("comparator", new JsonPrimitive(this.comparison.toString()));
+ filterRule.add("compareTo", new JsonPrimitive(this.comparisonValue));
+
+ root.add("rule", filterRule);
return root;
}
diff --git a/splunk/com/splunk/Index.java b/splunk/src/main/java/com/splunk/Index.java
similarity index 97%
rename from splunk/com/splunk/Index.java
rename to splunk/src/main/java/com/splunk/Index.java
index 21d83953..f39dd2e7 100644
--- a/splunk/com/splunk/Index.java
+++ b/splunk/src/main/java/com/splunk/Index.java
@@ -40,7 +40,7 @@ public class Index extends Entity {
* Creates a writable socket to this index.
*
* @return The writable socket.
- * @throws IOException
+ * @throws IOException Throws exception if fails to write socket.
*/
public Socket attach() throws IOException {
Receiver receiver = service.getReceiver();
@@ -48,19 +48,20 @@ public Socket attach() throws IOException {
}
/**
- * Writes events to this index, reusing the connection.
- * This method passes an output stream connected to the index to the
- * {@code run} method of the {@code ReceiverBehavior} object, then handles
+ * Writes events to this index, reusing the connection.
+ * This method passes an output stream connected to the index to the
+ * {@code run} method of the {@code ReceiverBehavior} object, then handles
* setting up and tearing down the socket.
*
- * For an example of how to use this method, see
- * How to
- * get data into Splunk on
- * How to
+ * get data into Splunk on
+ * dev.splunk.com.
- *
- * @param behavior The body of a {@code try} block as an anonymous
+ *
+ * @param behavior The body of a {@code try} block as an anonymous
* implementation of the {@code ReceiverBehavior} interface.
+ * @throws IOException The IOException class
*/
public void attachWith(ReceiverBehavior behavior) throws IOException {
Socket socket = null;
@@ -82,7 +83,7 @@ public void attachWith(ReceiverBehavior behavior) throws IOException {
* @param args Optional arguments for this stream. Valid parameters are:
* "host", "host_regex", "source", and "sourcetype".
* @return The socket.
- * @throws IOException
+ * @throws IOException The IOException class
*/
public Socket attach(Args args) throws IOException {
Receiver receiver = service.getReceiver();
@@ -151,25 +152,6 @@ public boolean getAssureUTF8() {
return getBoolean("assureUTF8");
}
- /**
- * Returns the block signature database for this index.
- *
- * @return The block signature database.
- */
- public String getBlockSignatureDatabase() {
- return getString("blockSignatureDatabase");
- }
-
- /**
- * Returns the number of events that make up a block for block signatures.
- *
- * @return The block sign size. A value of 0 means block signing has been
- * disabled.
- */
- public int getBlockSignSize() {
- return getInteger("blockSignSize");
- }
-
/**
* Returns the total size of all bloom filter files.
*
@@ -346,6 +328,7 @@ public String getLastInitTime() {
* is older than this, Splunk does not create or rebuild its bloomfilter.
* The valid format is number followed by a time unit ("s", "m", "h",
* or "d"). For example, "30d" for 30 days.
+ * @return String value
*/
public String getMaxBloomBackfillBucketAge() {
return getString("maxBloomBackfillBucketAge", null);
@@ -377,10 +360,10 @@ public String getMaxDataSize() {
/**
* Returns the maximum number of hot buckets that can exist for this index.
*
- * @return The maximum number of hot buckets.
+ * @return The maximum number of hot buckets or "auto" (which means 3).
*/
- public int getMaxHotBuckets() {
- return getInteger("maxHotBuckets");
+ public String getMaxHotBuckets() {
+ return getString("maxHotBuckets");
}
/**
@@ -460,6 +443,7 @@ public int getMaxTotalDataSizeMB() {
* If there are any acknowledged events sharing this raw slice, the
* {@code MaxTimeUnreplicatedWithAcksparamater} applies instead.
* @see #getMaxTimeUnreplicatedWithAcks
+ * @return int value
*/
public int getMaxTimeUnreplicatedNoAcks() {
return getInteger("maxTimeUnreplicatedNoAcks");
@@ -470,6 +454,7 @@ public int getMaxTimeUnreplicatedNoAcks() {
* unacknowledged in a raw slice. This value only applies when indexer
* acknowledgement is enabled on forwarders and replication is enabled with
* clustering.
+ * @return int value
*/
public int getMaxTimeUnreplicatedWithAcks() {
return getInteger("maxTimeUnreplicatedWithAcks");
@@ -739,8 +724,7 @@ public void setBucketRebuildMemoryHint(String value) {
/**
* Sets the destination path for the frozen archive, where Splunk
* automatically puts frozen buckets. The bucket freezing policy is as
- *follows:
- *
+ * follows:
*
New-style buckets (4.2 and later): All files are removed
* except the raw data. To thaw frozen buckets, run {@code Splunk rebuild
* } on the bucket, then move the buckets to the thawed
@@ -847,9 +831,9 @@ public void setMaxDataSize(String size) {
* @see #setMaxHotIdleSecs
* @see #getMaxHotIdleSecs
*
- * @param size The maximum number of hot buckets per index.
+ * @param size The maximum number of hot buckets per index, or an 'auto' string.
*/
- public void setMaxHotBuckets(int size) {
+ public void setMaxHotBuckets(String size) {
setCacheValue("maxHotBuckets", size);
}
diff --git a/splunk/com/splunk/IndexCollection.java b/splunk/src/main/java/com/splunk/IndexCollection.java
similarity index 100%
rename from splunk/com/splunk/IndexCollection.java
rename to splunk/src/main/java/com/splunk/IndexCollection.java
diff --git a/splunk/com/splunk/IndexCollectionArgs.java b/splunk/src/main/java/com/splunk/IndexCollectionArgs.java
similarity index 100%
rename from splunk/com/splunk/IndexCollectionArgs.java
rename to splunk/src/main/java/com/splunk/IndexCollectionArgs.java
diff --git a/splunk/com/splunk/Input.java b/splunk/src/main/java/com/splunk/Input.java
similarity index 97%
rename from splunk/com/splunk/Input.java
rename to splunk/src/main/java/com/splunk/Input.java
index 09ac441b..95ca6c8d 100644
--- a/splunk/com/splunk/Input.java
+++ b/splunk/src/main/java/com/splunk/Input.java
@@ -39,6 +39,7 @@ public class Input extends Entity {
* Returns an {@code InputKind} representing this input's type.
*
* The input kind is inferred from the input's path.
+ * @return InputKind instance
*/
public InputKind getKind() {
String[] pathComponents =
diff --git a/splunk/com/splunk/InputCollection.java b/splunk/src/main/java/com/splunk/InputCollection.java
similarity index 98%
rename from splunk/com/splunk/InputCollection.java
rename to splunk/src/main/java/com/splunk/InputCollection.java
index 9714e66d..0fcefa02 100644
--- a/splunk/com/splunk/InputCollection.java
+++ b/splunk/src/main/java/com/splunk/InputCollection.java
@@ -64,7 +64,7 @@ public class InputCollection extends EntityCollection {
*
The stanza (for Windows Registry inputs)
*
The name of the configuration (for Windows AD inputs)
* @return No return value.
- * @throws UnsupportedOperationException
+ * @throws UnsupportedOperationException The UnsupportedOperationException instance
*/
@Override public Input create(String name) {
throw new UnsupportedOperationException();
@@ -88,7 +88,7 @@ public class InputCollection extends EntityCollection {
* dev.splunk.com.
* @return No return value.
- * @throws UnsupportedOperationException
+ * @throws UnsupportedOperationException The UnsupportedOperationException instance
*/
@Override public Input create(String name, Map args) {
throw new UnsupportedOperationException();
diff --git a/splunk/com/splunk/InputKind.java b/splunk/src/main/java/com/splunk/InputKind.java
similarity index 100%
rename from splunk/com/splunk/InputKind.java
rename to splunk/src/main/java/com/splunk/InputKind.java
diff --git a/splunk/com/splunk/InsertRootElementFilterInputStream.java b/splunk/src/main/java/com/splunk/InsertRootElementFilterInputStream.java
similarity index 67%
rename from splunk/com/splunk/InsertRootElementFilterInputStream.java
rename to splunk/src/main/java/com/splunk/InsertRootElementFilterInputStream.java
index 3d4da339..b668f850 100644
--- a/splunk/com/splunk/InsertRootElementFilterInputStream.java
+++ b/splunk/src/main/java/com/splunk/InsertRootElementFilterInputStream.java
@@ -16,9 +16,6 @@
package com.splunk;
import java.io.*;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.concurrent.Callable;
/**
* Takes an InputStream containing a UTF-8 encoded XML document containing one or more
@@ -31,22 +28,35 @@
* it is filtering.
*/
class InsertRootElementFilterInputStream extends FilterInputStream {
+ private static final int REREAD_BUFFER_SIZE = 512;
+ private static byte[] resultsTagBytes;
private final ByteArrayInputStream suffix = new ByteArrayInputStream("".getBytes("UTF-8"));
+ private ByteArrayInputStream beforeResultsBuffer;
private boolean wrotePrefix;
private byte[] oneByte = new byte[1];
+ static {
+ try {
+ resultsTagBytes = "results".getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ //should not be thrown because UTF-8 is supported
+ throw new RuntimeException(e);
+ }
+ }
+
InsertRootElementFilterInputStream(InputStream in) throws IOException {
// Wrap in with a pushback stream so we can write our modified version back
// onto the beginning of it.
- super(new PushbackInputStream(in, 512));
+ super(new PushbackInputStream(in, REREAD_BUFFER_SIZE));
+
PushbackInputStream pin = (PushbackInputStream)this.in;
// Read bytes until we reach '>', then push everything we read, followed by "",
// back onto the stream. If we run out of input before we reach '>', then don't
// modify the stream.
ByteArrayOutputStream beforeResultsChars = new ByteArrayOutputStream();
- ByteArrayOutputStream atResultsChars = new ByteArrayOutputStream();
+ beforeResultsBuffer = new ByteArrayInputStream(new byte[0]);
int ch;
while (true) {
@@ -57,32 +67,19 @@ class InsertRootElementFilterInputStream extends FilterInputStream {
pin.unread(beforeResultsChars.toByteArray());
return;
} else if (ch == (int)'<') {
- // Try extending
- atResultsChars.reset();
- int ech;
- boolean matched = true;
- for (byte b : "results".getBytes("UTF-8")) {
- ech = this.in.read();
- atResultsChars.write(ech);
- if (ech != b) {
- // Extension failed. Put the bytes back on and search again.
- pin.unread(atResultsChars.toByteArray());
- matched = false;
- break;
- }
- }
+ boolean resultsTag = isResultsTag(pin);
- if (matched) {
+ if (resultsTag) {
// If we reach here, the extension succeeded, so we insert , unread everything,
// and return.
// Unread the match.
- pin.unread(atResultsChars.toByteArray());
+ pin.unread(InsertRootElementFilterInputStream.resultsTagBytes);
// Unread the opening '<' that led to our extension
pin.unread(ch);
- // Add a '' element to our read charactes and unread them.
+ // Add a '' element to our read characters
beforeResultsChars.write("".getBytes("UTF-8"));
- pin.unread(beforeResultsChars.toByteArray());
+ beforeResultsBuffer = new ByteArrayInputStream(beforeResultsChars.toByteArray());
wrotePrefix = true;
return;
} else {
@@ -96,9 +93,38 @@ class InsertRootElementFilterInputStream extends FilterInputStream {
}
}
+ private boolean isResultsTag(PushbackInputStream pin) throws IOException {
+ // Try extending
+ ByteArrayOutputStream atResultsChars = new ByteArrayOutputStream();
+ int ech;
+ boolean resultsTag = true;
+ for (byte b : resultsTagBytes) {
+ ech = this.in.read();
+ atResultsChars.write(ech);
+ if (ech != b) {
+ // Extension failed. Put the bytes back on and search again.
+ pin.unread(atResultsChars.toByteArray());
+ resultsTag = false;
+ break;
+ }
+ }
+ return resultsTag;
+ }
+
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
- int result = in.read(buffer, offset, length);
+ // first we read from the buffer before the first results xml tag
+ int result = 0;
+ int availableFromBuffer = beforeResultsBuffer.available();
+ if (offset < availableFromBuffer) {
+ result = beforeResultsBuffer.read(buffer, offset, length);
+ if (length <= result) {
+ return result;
+ }
+ }
+
+ // then we read from the original input stream
+ result += in.read(buffer, offset+result, length-result);
if (result == -1 && wrotePrefix) {
// No more bytes to read from in, and we have written '' earlier in the stream
return suffix.read(buffer, offset, length);
diff --git a/splunk/com/splunk/Job.java b/splunk/src/main/java/com/splunk/Job.java
similarity index 94%
rename from splunk/com/splunk/Job.java
rename to splunk/src/main/java/com/splunk/Job.java
index b88f232e..354d413c 100644
--- a/splunk/com/splunk/Job.java
+++ b/splunk/src/main/java/com/splunk/Job.java
@@ -35,6 +35,7 @@ public class Job extends Entity {
*
* @param service The connected {@code Service} instance.
* @param path The search jobs endpoint.
+ * @param sid The sid of the job.
*/
Job(Service service, String path) {
super(service, path);
@@ -252,6 +253,16 @@ public int getEventCount() {
return getInteger("eventCount");
}
+ /**
+ * Returns the count of events (pre-transforming) that were generated as a long.
+ *
+ * @return The number of events.
+ */
+ public long getEventCountLong() {
+ checkReady();
+ return getLong("eventCount");
+ }
+
/**
* Returns the count of event fields.
*
@@ -357,7 +368,19 @@ private InputStream getEventsMethod(String methodPath, Map args) {
args.put("segmentation", "none");
}
- ResponseMessage response = service.get(path + methodPath, args);
+ // Splunk version pre-9.0 doesn't support v2
+ // v1(GET), v2(POST)
+ String fullPath;
+ ResponseMessage response;
+ if (!service.enableV2SearchApi()) {
+ fullPath = path.replace(JobCollection.REST_PATH_V2, JobCollection.REST_PATH) + methodPath;
+ response = service.get(fullPath, args);
+ }
+ else {
+ fullPath = path.replace(JobCollection.REST_PATH, JobCollection.REST_PATH_V2) + methodPath;
+ response = service.post(fullPath, args);
+ }
+
return response.getContent();
}
@@ -470,6 +493,18 @@ public int getResultCount() {
checkReady();
return getInteger("resultCount");
}
+
+ /**
+ * Returns the total count of results returned for this search job as a long.
+ * This is the subset of scanned events that actually matches the search
+ * terms.
+ *
+ * @return The number of results.
+ */
+ public long getResultCountLong() {
+ checkReady();
+ return getLong("resultCount");
+ }
/**
* Indicates whether the job's results are available by streaming.
@@ -588,6 +623,17 @@ public int getScanCount() {
checkReady();
return getInteger("scanCount");
}
+
+ /**
+ * Returns the number of events that are scanned or read off disk
+ * as a long.
+ *
+ * @return The number of events.
+ */
+ public long getScanCountLong() {
+ checkReady();
+ return getLong("scanCount");
+ }
/**
* Returns this job's search title.
@@ -769,6 +815,9 @@ public int getTtl() {
public boolean isDone() {
if (!isReady())
return false;
+ if (!getBoolean("isDone")) {
+ this.refresh();
+ }
return getBoolean("isDone");
}
diff --git a/splunk/com/splunk/JobArgs.java b/splunk/src/main/java/com/splunk/JobArgs.java
similarity index 100%
rename from splunk/com/splunk/JobArgs.java
rename to splunk/src/main/java/com/splunk/JobArgs.java
diff --git a/splunk/com/splunk/JobCollection.java b/splunk/src/main/java/com/splunk/JobCollection.java
similarity index 91%
rename from splunk/com/splunk/JobCollection.java
rename to splunk/src/main/java/com/splunk/JobCollection.java
index 529fb9da..661e21ff 100644
--- a/splunk/com/splunk/JobCollection.java
+++ b/splunk/src/main/java/com/splunk/JobCollection.java
@@ -27,13 +27,14 @@ public class JobCollection extends EntityCollection {
static String oneShotNotAllowed = String.format(
"Oneshot not allowed, use service oneshot search method");
static final String REST_PATH = "search/jobs";
+ static final String REST_PATH_V2 = "search/v2/jobs";
/**
* Class constructor.
*
* @param service The connected {@code Service} instance.
*/
JobCollection(Service service) {
- super(service, REST_PATH, Job.class);
+ super(service, service.enableV2SearchApi() ? REST_PATH_V2 : REST_PATH, Job.class);
this.refreshArgs.put("count", "0");
}
@@ -45,7 +46,7 @@ public class JobCollection extends EntityCollection {
* return and how to sort them (see {@link CollectionArgs}).
*/
JobCollection(Service service, Args args) {
- super(service, REST_PATH, Job.class, args);
+ super(service, service.enableV2SearchApi() ? REST_PATH_V2 : REST_PATH, Job.class);
this.refreshArgs.put("count", "0");
}
@@ -86,7 +87,8 @@ public Job create(String query, Map args) {
.item(0)
.getTextContent();
- Job job = new Job(service, REST_PATH + "/" + sid);
+ String path = service.enableV2SearchApi() ? REST_PATH_V2 : REST_PATH;
+ Job job = new Job(service, path + "/" + sid);
job.refresh();
return job;
diff --git a/splunk/com/splunk/JobEventsArgs.java b/splunk/src/main/java/com/splunk/JobEventsArgs.java
similarity index 100%
rename from splunk/com/splunk/JobEventsArgs.java
rename to splunk/src/main/java/com/splunk/JobEventsArgs.java
diff --git a/splunk/com/splunk/JobExportArgs.java b/splunk/src/main/java/com/splunk/JobExportArgs.java
similarity index 97%
rename from splunk/com/splunk/JobExportArgs.java
rename to splunk/src/main/java/com/splunk/JobExportArgs.java
index 27ec43cf..5d5f8930 100644
--- a/splunk/com/splunk/JobExportArgs.java
+++ b/splunk/src/main/java/com/splunk/JobExportArgs.java
@@ -292,12 +292,22 @@ public void setRemoteServerList(String[] remoteServerList) {
this.put("remote_server_list", String.valueOf(csv));
}
+
+ /**
+ * Sets one or more fields to the search. These fields, even if not referenced or used directly by the search, are still included by the events and summary endpoints. Splunk Web uses these fields to prepopulate panels in the Search view.
+ *
+ * @param fieldList
+ * The list of fields.
+ */
+ public void setFieldList(String[] fieldList) {
+ this.put("f", fieldList);
+ }
/**
* Sets one or more required fields to the search. These fields, even if not referenced or used directly by the search, are still included by the events and summary endpoints. Splunk Web uses these fields to prepopulate panels in the Search view.
*
* @param requiredFieldList
- * The list of fields.
+ * The list of required fields.
*/
public void setRequiredFieldList(String[] requiredFieldList) {
this.put("rf", requiredFieldList);
diff --git a/splunk/com/splunk/JobResultsArgs.java b/splunk/src/main/java/com/splunk/JobResultsArgs.java
similarity index 100%
rename from splunk/com/splunk/JobResultsArgs.java
rename to splunk/src/main/java/com/splunk/JobResultsArgs.java
diff --git a/splunk/com/splunk/JobResultsPreviewArgs.java b/splunk/src/main/java/com/splunk/JobResultsPreviewArgs.java
similarity index 100%
rename from splunk/com/splunk/JobResultsPreviewArgs.java
rename to splunk/src/main/java/com/splunk/JobResultsPreviewArgs.java
diff --git a/splunk/com/splunk/JobSummaryArgs.java b/splunk/src/main/java/com/splunk/JobSummaryArgs.java
similarity index 100%
rename from splunk/com/splunk/JobSummaryArgs.java
rename to splunk/src/main/java/com/splunk/JobSummaryArgs.java
diff --git a/splunk/com/splunk/License.java b/splunk/src/main/java/com/splunk/License.java
similarity index 100%
rename from splunk/com/splunk/License.java
rename to splunk/src/main/java/com/splunk/License.java
diff --git a/splunk/com/splunk/LicenseGroup.java b/splunk/src/main/java/com/splunk/LicenseGroup.java
similarity index 100%
rename from splunk/com/splunk/LicenseGroup.java
rename to splunk/src/main/java/com/splunk/LicenseGroup.java
diff --git a/splunk/com/splunk/LicenseMessage.java b/splunk/src/main/java/com/splunk/LicenseMessage.java
similarity index 100%
rename from splunk/com/splunk/LicenseMessage.java
rename to splunk/src/main/java/com/splunk/LicenseMessage.java
diff --git a/splunk/com/splunk/LicensePool.java b/splunk/src/main/java/com/splunk/LicensePool.java
similarity index 99%
rename from splunk/com/splunk/LicensePool.java
rename to splunk/src/main/java/com/splunk/LicensePool.java
index a878adf9..613fcaac 100644
--- a/splunk/com/splunk/LicensePool.java
+++ b/splunk/src/main/java/com/splunk/LicensePool.java
@@ -98,7 +98,7 @@ public Map getSlavesUsageBytes() {
/**
* Returns the stack ID for this license pool. Valid values are:
- *
+ *
*
"download-trial"
*
"enterprise"
*
"forwarder"
diff --git a/splunk/com/splunk/LicensePoolCollection.java b/splunk/src/main/java/com/splunk/LicensePoolCollection.java
similarity index 100%
rename from splunk/com/splunk/LicensePoolCollection.java
rename to splunk/src/main/java/com/splunk/LicensePoolCollection.java
diff --git a/splunk/com/splunk/LicenseSlave.java b/splunk/src/main/java/com/splunk/LicenseSlave.java
similarity index 100%
rename from splunk/com/splunk/LicenseSlave.java
rename to splunk/src/main/java/com/splunk/LicenseSlave.java
diff --git a/splunk/com/splunk/LicenseStack.java b/splunk/src/main/java/com/splunk/LicenseStack.java
similarity index 100%
rename from splunk/com/splunk/LicenseStack.java
rename to splunk/src/main/java/com/splunk/LicenseStack.java
diff --git a/splunk/com/splunk/LimitPivotFilter.java b/splunk/src/main/java/com/splunk/LimitPivotFilter.java
similarity index 99%
rename from splunk/com/splunk/LimitPivotFilter.java
rename to splunk/src/main/java/com/splunk/LimitPivotFilter.java
index ed29d4fa..dd4b89a0 100644
--- a/splunk/com/splunk/LimitPivotFilter.java
+++ b/splunk/src/main/java/com/splunk/LimitPivotFilter.java
@@ -54,6 +54,7 @@ public class LimitPivotFilter extends PivotFilter {
/**
* Return the name of the field to use for sorting.
+ * @return String value
*/
public String getAttributeName() {
return this.sortAttribute;
diff --git a/splunk/com/splunk/Logger.java b/splunk/src/main/java/com/splunk/Logger.java
similarity index 100%
rename from splunk/com/splunk/Logger.java
rename to splunk/src/main/java/com/splunk/Logger.java
diff --git a/splunk/com/splunk/LookupDataModelCalculation.java b/splunk/src/main/java/com/splunk/LookupDataModelCalculation.java
similarity index 100%
rename from splunk/com/splunk/LookupDataModelCalculation.java
rename to splunk/src/main/java/com/splunk/LookupDataModelCalculation.java
diff --git a/splunk/com/splunk/Message.java b/splunk/src/main/java/com/splunk/Message.java
similarity index 100%
rename from splunk/com/splunk/Message.java
rename to splunk/src/main/java/com/splunk/Message.java
diff --git a/splunk/com/splunk/MessageCollection.java b/splunk/src/main/java/com/splunk/MessageCollection.java
similarity index 100%
rename from splunk/com/splunk/MessageCollection.java
rename to splunk/src/main/java/com/splunk/MessageCollection.java
diff --git a/splunk/com/splunk/ModularInputKind.java b/splunk/src/main/java/com/splunk/ModularInputKind.java
similarity index 100%
rename from splunk/com/splunk/ModularInputKind.java
rename to splunk/src/main/java/com/splunk/ModularInputKind.java
diff --git a/splunk/com/splunk/ModularInputKindArgument.java b/splunk/src/main/java/com/splunk/ModularInputKindArgument.java
similarity index 100%
rename from splunk/com/splunk/ModularInputKindArgument.java
rename to splunk/src/main/java/com/splunk/ModularInputKindArgument.java
diff --git a/splunk/com/splunk/MonitorInput.java b/splunk/src/main/java/com/splunk/MonitorInput.java
similarity index 100%
rename from splunk/com/splunk/MonitorInput.java
rename to splunk/src/main/java/com/splunk/MonitorInput.java
diff --git a/splunk/com/splunk/MultiResultsReader.java b/splunk/src/main/java/com/splunk/MultiResultsReader.java
similarity index 94%
rename from splunk/com/splunk/MultiResultsReader.java
rename to splunk/src/main/java/com/splunk/MultiResultsReader.java
index c9707fa5..cc57b97f 100644
--- a/splunk/com/splunk/MultiResultsReader.java
+++ b/splunk/src/main/java/com/splunk/MultiResultsReader.java
@@ -44,7 +44,7 @@ public final Iterator iterator() {
/**
* Closes the reader and releases resources.
- * @throws IOException
+ * @throws IOException If reader is not closed.
*/
public final void close() throws IOException {
resultsReader.close();
diff --git a/splunk/com/splunk/MultiResultsReaderJson.java b/splunk/src/main/java/com/splunk/MultiResultsReaderJson.java
similarity index 94%
rename from splunk/com/splunk/MultiResultsReaderJson.java
rename to splunk/src/main/java/com/splunk/MultiResultsReaderJson.java
index 183c194e..77a2c9f6 100644
--- a/splunk/com/splunk/MultiResultsReaderJson.java
+++ b/splunk/src/main/java/com/splunk/MultiResultsReaderJson.java
@@ -34,7 +34,7 @@ public class MultiResultsReaderJson
* may occur if you try to parse a stream with a different format.
*
* @param inputStream The JSON stream to parse.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public MultiResultsReaderJson(InputStream inputStream) throws IOException {
super(new ResultsReaderJson(inputStream, true));
diff --git a/splunk/com/splunk/MultiResultsReaderXml.java b/splunk/src/main/java/com/splunk/MultiResultsReaderXml.java
similarity index 94%
rename from splunk/com/splunk/MultiResultsReaderXml.java
rename to splunk/src/main/java/com/splunk/MultiResultsReaderXml.java
index d2377529..53088389 100644
--- a/splunk/com/splunk/MultiResultsReaderXml.java
+++ b/splunk/src/main/java/com/splunk/MultiResultsReaderXml.java
@@ -34,7 +34,7 @@ public class MultiResultsReaderXml
* may occur if you try to parse a stream with a different format.
*
* @param inputStream The XML stream to parse.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public MultiResultsReaderXml(InputStream inputStream) throws IOException {
super(new ResultsReaderXml(inputStream, true));
diff --git a/splunk/com/splunk/NumberComparison.java b/splunk/src/main/java/com/splunk/NumberComparison.java
similarity index 100%
rename from splunk/com/splunk/NumberComparison.java
rename to splunk/src/main/java/com/splunk/NumberComparison.java
diff --git a/splunk/com/splunk/NumberPivotFilter.java b/splunk/src/main/java/com/splunk/NumberPivotFilter.java
similarity index 86%
rename from splunk/com/splunk/NumberPivotFilter.java
rename to splunk/src/main/java/com/splunk/NumberPivotFilter.java
index 52b31397..6b0a42f3 100644
--- a/splunk/com/splunk/NumberPivotFilter.java
+++ b/splunk/src/main/java/com/splunk/NumberPivotFilter.java
@@ -43,8 +43,11 @@ JsonElement toJson() {
addCommonFields(root);
- root.add("comparator", new JsonPrimitive(this.comparison.toString()));
- root.add("compareTo", new JsonPrimitive(this.comparisonValue));
+ JsonObject filterRule = new JsonObject();
+ filterRule.add("comparator", new JsonPrimitive(this.comparison.toString()));
+ filterRule.add("compareTo", new JsonPrimitive(this.comparisonValue));
+
+ root.add("rule", filterRule);
return root;
}
diff --git a/splunk/com/splunk/NumberPivotRowSplit.java b/splunk/src/main/java/com/splunk/NumberPivotRowSplit.java
similarity index 100%
rename from splunk/com/splunk/NumberPivotRowSplit.java
rename to splunk/src/main/java/com/splunk/NumberPivotRowSplit.java
diff --git a/splunk/com/splunk/NumericPivotColumnSplit.java b/splunk/src/main/java/com/splunk/NumericPivotColumnSplit.java
similarity index 100%
rename from splunk/com/splunk/NumericPivotColumnSplit.java
rename to splunk/src/main/java/com/splunk/NumericPivotColumnSplit.java
diff --git a/splunk/com/splunk/OutputDefault.java b/splunk/src/main/java/com/splunk/OutputDefault.java
similarity index 99%
rename from splunk/com/splunk/OutputDefault.java
rename to splunk/src/main/java/com/splunk/OutputDefault.java
index c8f10145..abd9733f 100644
--- a/splunk/com/splunk/OutputDefault.java
+++ b/splunk/src/main/java/com/splunk/OutputDefault.java
@@ -193,18 +193,18 @@ public boolean isForwardedIndexFilterDisable() {
/**
* Sets how long to wait before throwing out all new events until the output
* queue has space. The default value is -1, which means to not drop events.
- *
+ *
* Caution: Do not set this value to a positive integer if you are
* monitoring files.
*
* Setting this to -1 or 0 causes the output queue to block when it gets
* full, which causes further blocking up the processing chain. If any
* target group's queue is blocked, no more data reaches any other target
- * group.
+ * group.
*
* Using auto load-balancing is the best way to minimize this condition,
* because, in that case, multiple receivers must be down or jammed before
- * queue blocking can occur.
+ * queue blocking can occur.
* @see #getAutoLB
*
* @param dropEventsOnQueueFull The time to wait before throwing out events,
diff --git a/splunk/com/splunk/OutputGroup.java b/splunk/src/main/java/com/splunk/OutputGroup.java
similarity index 99%
rename from splunk/com/splunk/OutputGroup.java
rename to splunk/src/main/java/com/splunk/OutputGroup.java
index ca619343..66f8653c 100644
--- a/splunk/com/splunk/OutputGroup.java
+++ b/splunk/src/main/java/com/splunk/OutputGroup.java
@@ -112,18 +112,18 @@ public void setCompressed(boolean compressed) {
/**
* Sets how long to wait before throwing out all new events until the output
* queue has space. The default value is -1, which means to not drop events.
- *
+ *
* Caution: Do not set this value to a positive integer if you are
* monitoring files.
*
* Setting this to -1 or 0 causes the output queue to block when it gets
* full, which causes further blocking up the processing chain. If any
* target group's queue is blocked, no more data reaches any other target
- * group.
+ * group.
*
* Using auto load-balancing is the best way to minimize this condition,
* because, in that case, multiple receivers must be down or jammed before
- * queue blocking can occur.
+ * queue blocking can occur.
* @see #getAutoLB
*
* @param dropEventsOnQueueFull The time to wait before throwing out events,
diff --git a/splunk/com/splunk/OutputServer.java b/splunk/src/main/java/com/splunk/OutputServer.java
similarity index 92%
rename from splunk/com/splunk/OutputServer.java
rename to splunk/src/main/java/com/splunk/OutputServer.java
index 9ec8e223..cafec3f6 100644
--- a/splunk/com/splunk/OutputServer.java
+++ b/splunk/src/main/java/com/splunk/OutputServer.java
@@ -89,6 +89,15 @@ public String getStatus() {
return getString("status", null);
}
+ /**
+ * Returns client certificate path.
+ *
+ * @return Path of client certificate.
+ */
+ public String getClientCert() {
+ return getString("clientCert", "");
+ }
+
/**
* Sets the type of data distribution method when two or more servers
* exist in the same forwarder group. Valid values are: "clone", "balance",
@@ -172,6 +181,15 @@ public void setSslVerifyServerCert(boolean sslVerifyServerCert) {
setCacheValue("sslVerifyServerCert", sslVerifyServerCert);
}
+ /**
+ * Sets the client certificate path which is being supported in recent versions.
+ *
+ * @param clientCert The path for client certificate.
+ */
+ public void setClientCert(String clientCert) {
+ setCacheValue("clientCert", clientCert);
+ }
+
/**
* Returns an object that contains all current connections to the output
* server.
diff --git a/splunk/com/splunk/OutputServerAllConnections.java b/splunk/src/main/java/com/splunk/OutputServerAllConnections.java
similarity index 100%
rename from splunk/com/splunk/OutputServerAllConnections.java
rename to splunk/src/main/java/com/splunk/OutputServerAllConnections.java
diff --git a/splunk/com/splunk/OutputSyslog.java b/splunk/src/main/java/com/splunk/OutputSyslog.java
similarity index 100%
rename from splunk/com/splunk/OutputSyslog.java
rename to splunk/src/main/java/com/splunk/OutputSyslog.java
diff --git a/splunk/com/splunk/Password.java b/splunk/src/main/java/com/splunk/Password.java
similarity index 100%
rename from splunk/com/splunk/Password.java
rename to splunk/src/main/java/com/splunk/Password.java
diff --git a/splunk/src/main/java/com/splunk/PasswordCollection.java b/splunk/src/main/java/com/splunk/PasswordCollection.java
new file mode 100644
index 00000000..47a50a22
--- /dev/null
+++ b/splunk/src/main/java/com/splunk/PasswordCollection.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2012 Splunk, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"): you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.splunk;
+
+/**
+ * The {@code PasswordCollection} class represents a collection of credentials.
+ */
+public class PasswordCollection extends EntityCollection {
+
+ /**
+ * Class constructor.
+ *
+ * @param service The connected {@code Service} instance.
+ */
+ PasswordCollection(Service service) {
+ super(service, service.passwordEndPoint, Password.class);
+ }
+
+ /**
+ * Class constructor.
+ *
+ * @param service The connected {@code Service} instance.
+ * @param args Collection arguments that specify the number of entities to
+ * return and how to sort them. See {@link CollectionArgs}.
+ */
+ PasswordCollection(Service service, Args args) {
+ super(service, service.passwordEndPoint, Password.class, args);
+ }
+
+ /**
+ * Creates a credential with a username and password.
+ *
+ * @param name The username.
+ * @param password The password.
+ *
+ * @return The new credential.
+ */
+ public Password create(String name, String password) {
+ if(checkForWildcards()){
+ throw new IllegalArgumentException("While creating StoragePasswords, namespace cannot have wildcards.");
+ }
+ Args args = new Args("password", password);
+ return create(name, args);
+ }
+
+ /**
+ * Creates a credential with a username, password, and realm.
+ *
+ * @param name The username.
+ * @param password The password.
+ * @param realm The credential realm.
+ * @return The new credential.
+ */
+ public Password create(String name, String password, String realm) {
+ if(checkForWildcards()){
+ throw new IllegalArgumentException("While creating StoragePasswords, namespace cannot have wildcards.");
+ }
+ Args args = new Args();
+ args.put("password", password);
+ args.put("realm", realm);
+ return create(name, args);
+ }
+
+ /**
+ * Get a credential with realm and name.
+ *
+ * @param realm The credential realm.
+ * @param name The username.
+ * @return The credential, or null if not found.
+ */
+ public Password get(String realm, String name) {
+ return super.get(String.format("%s:%s:", realm, name));
+ }
+
+ @Override
+ public Password get(Object key) {
+ // Make it compatible with the old way (low-efficient)
+ if (key instanceof String && !((String) key).contains(":")) {
+ return getByUsername((String) key);
+ }
+ return super.get(key);
+ }
+
+ /**
+ * Remove a credential with realm and name.
+ *
+ * @param realm The credential realm.
+ * @param name The username.
+ * @return The removed credential, or null if not found.
+ */
+ public Password remove(String realm, String name) {
+ if(checkForWildcards()){
+ throw new IllegalArgumentException("app context must be specified when removing a password.");
+ }
+ return super.remove(String.format("%s:%s:", realm, name));
+ }
+
+ @Override
+ public Password remove(String key) {
+ if(checkForWildcards()){
+ throw new IllegalArgumentException("app context must be specified when removing a password.");
+ }
+ // Make it compatible with the old way (low-efficient)
+ if (!key.contains(":")) {
+ Password password = getByUsername((String) key);
+ validate();
+ if (password == null) return null;
+ password.remove();
+ // by invalidating any access to items will get refreshed
+ invalidate();
+ return password;
+ }
+ return super.remove(key);
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ if (key instanceof String && !((String) key).contains(":")) {
+ return getByUsername((String) key) != null;
+ }
+ return super.containsKey(key);
+ }
+
+ private Password getByUsername(String name) {
+ for (Password password : this.values()) {
+ if (password.getUsername().equals(name)) return password;
+ }
+ return null;
+ }
+
+ private boolean checkForWildcards(){
+ boolean isWildCard = false;
+ if(("-").equals(service.getOwner()) || ("-").equals(service.getApp())){
+ isWildCard = true;
+ }
+ return isWildCard;
+ }
+}
diff --git a/splunk/com/splunk/Pivot.java b/splunk/src/main/java/com/splunk/Pivot.java
similarity index 100%
rename from splunk/com/splunk/Pivot.java
rename to splunk/src/main/java/com/splunk/Pivot.java
diff --git a/splunk/com/splunk/PivotCellValue.java b/splunk/src/main/java/com/splunk/PivotCellValue.java
similarity index 100%
rename from splunk/com/splunk/PivotCellValue.java
rename to splunk/src/main/java/com/splunk/PivotCellValue.java
diff --git a/splunk/com/splunk/PivotColumnSplit.java b/splunk/src/main/java/com/splunk/PivotColumnSplit.java
similarity index 100%
rename from splunk/com/splunk/PivotColumnSplit.java
rename to splunk/src/main/java/com/splunk/PivotColumnSplit.java
diff --git a/splunk/com/splunk/PivotFilter.java b/splunk/src/main/java/com/splunk/PivotFilter.java
similarity index 100%
rename from splunk/com/splunk/PivotFilter.java
rename to splunk/src/main/java/com/splunk/PivotFilter.java
diff --git a/splunk/com/splunk/PivotRowSplit.java b/splunk/src/main/java/com/splunk/PivotRowSplit.java
similarity index 100%
rename from splunk/com/splunk/PivotRowSplit.java
rename to splunk/src/main/java/com/splunk/PivotRowSplit.java
diff --git a/splunk/com/splunk/PivotSpecification.java b/splunk/src/main/java/com/splunk/PivotSpecification.java
similarity index 98%
rename from splunk/com/splunk/PivotSpecification.java
rename to splunk/src/main/java/com/splunk/PivotSpecification.java
index 0ddd0e03..1aa154a9 100644
--- a/splunk/com/splunk/PivotSpecification.java
+++ b/splunk/src/main/java/com/splunk/PivotSpecification.java
@@ -49,6 +49,7 @@ public class PivotSpecification {
* namespace for acceleration.
*
* @param namespace a string specifying a namespace.
+ * @return PivotSpecification instance
*/
public PivotSpecification setAccelerationNamespace(String namespace) {
this.accelerationNamespace = namespace;
@@ -60,6 +61,7 @@ public PivotSpecification setAccelerationNamespace(String namespace) {
* DataModelObject instance, as the acceleration cache for this pivot.
*
* @param sid the SID of a job.
+ * @return PivotSpecification instance
*/
public PivotSpecification setAccelerationJob(String sid) {
if (sid == null) {
@@ -75,6 +77,7 @@ public PivotSpecification setAccelerationJob(String sid) {
* DataModelObject instance, as the acceleration cache for this pivot.
*
* @param job a Job object.
+ * @return PivotSpecification instance
*/
public PivotSpecification setAccelerationJob(Job job) {
setAccelerationJob(job.getSid());
@@ -282,6 +285,8 @@ public PivotSpecification addRowSplit(String field, String label, Integer start,
/**
* Add a row split on a boolean valued field.
*
+ * @param field String value
+ * @param label String value
* @param trueDisplayValue the string to display in the true valued row label.
* @param falseDisplayValue the string to display in the false valued row label;
* @return The PivotSpecification you are modifying.
diff --git a/splunk/com/splunk/PortInput.java b/splunk/src/main/java/com/splunk/PortInput.java
similarity index 98%
rename from splunk/com/splunk/PortInput.java
rename to splunk/src/main/java/com/splunk/PortInput.java
index af9aa9a3..f0f2be1f 100644
--- a/splunk/com/splunk/PortInput.java
+++ b/splunk/src/main/java/com/splunk/PortInput.java
@@ -39,6 +39,7 @@ abstract class PortInput extends Input {
/**
* Returns the port that this input is listening on.
+ * @return int value
*/
public int getPort() {
String[] nameComponents = this.getName().split(":");
diff --git a/splunk/com/splunk/RangePivotColumnSplit.java b/splunk/src/main/java/com/splunk/RangePivotColumnSplit.java
similarity index 100%
rename from splunk/com/splunk/RangePivotColumnSplit.java
rename to splunk/src/main/java/com/splunk/RangePivotColumnSplit.java
diff --git a/splunk/com/splunk/RangePivotRowSplit.java b/splunk/src/main/java/com/splunk/RangePivotRowSplit.java
similarity index 100%
rename from splunk/com/splunk/RangePivotRowSplit.java
rename to splunk/src/main/java/com/splunk/RangePivotRowSplit.java
diff --git a/splunk/com/splunk/Receiver.java b/splunk/src/main/java/com/splunk/Receiver.java
similarity index 81%
rename from splunk/com/splunk/Receiver.java
rename to splunk/src/main/java/com/splunk/Receiver.java
index c625cffa..8ae4d826 100644
--- a/splunk/com/splunk/Receiver.java
+++ b/splunk/src/main/java/com/splunk/Receiver.java
@@ -16,14 +16,14 @@
package com.splunk;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
+import java.io.*;
import java.net.Socket;
+import java.lang.StringBuilder;
+import java.util.ArrayList;
+import java.util.List;
/**
- * The {@code Receiver} class represents a named index and unnamed index
+ * The {@code Receiver} class represents a named index and unnamed index
* receivers.
*/
public class Receiver {
@@ -43,7 +43,7 @@ public class Receiver {
* Creates a writable socket to this index.
*
* @return The socket.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public Socket attach() throws IOException {
return attach(null, null);
@@ -54,7 +54,7 @@ public Socket attach() throws IOException {
*
* @param indexName The index to write to.
* @return The socket.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public Socket attach(String indexName) throws IOException {
return attach(indexName, null);
@@ -63,10 +63,10 @@ public Socket attach(String indexName) throws IOException {
/**
* Creates a writable socket to this index.
*
- * @param args Optional arguments for this stream. Valid parameters are:
+ * @param args Optional arguments for this stream. Valid parameters are:
* "host", "host_regex", "source", and "sourcetype".
* @return The socket.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public Socket attach(Args args) throws IOException {
return attach(null, args);
@@ -76,15 +76,14 @@ public Socket attach(Args args) throws IOException {
* Creates a writable socket to this index.
*
* @param indexName The index to write to.
- * @param args Optional arguments for this stream. Valid parameters are:
+ * @param args Optional arguments for this stream. Valid parameters are:
* "host", "host_regex", "source", and "sourcetype".
* @return The socket.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public Socket attach(String indexName, Args args) throws IOException {
Socket socket = service.open();
- OutputStream ostream = socket.getOutputStream();
- Writer out = new OutputStreamWriter(ostream, "UTF-8");
+ PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
String postUrl = "POST /services/receivers/stream";
if (indexName != null) {
postUrl = postUrl + "?index=" + indexName;
@@ -93,17 +92,24 @@ public Socket attach(String indexName, Args args) throws IOException {
postUrl = postUrl + ((indexName == null) ? "?" : "&");
postUrl = postUrl + args.encode();
}
- String header = String.format(
- "%s HTTP/1.1\r\n" +
- "Host: %s:%d\r\n" +
- "Accept-Encoding: identity\r\n" +
- "Authorization: %s\r\n" +
- "X-Splunk-Input-Mode: Streaming\r\n\r\n",
- postUrl,
- service.getHost(), service.getPort(),
- service.getToken());
- out.write(header);
- out.flush();
+
+ List headers = new ArrayList<>();
+ headers.add(String.format("%s HTTP/1.1", postUrl));
+ headers.add("Accept-Encoding: identity");
+ headers.add("X-Splunk-Input-Mode: Streaming");
+
+ if (service.hasSplunkAuthCookies()) {
+ headers.add(String.format("Cookie: %s", service.stringifyCookies()));
+ } else {
+ // to persist the cookies other than Splunk such as from Load Balancer
+ if(!service.cookieStore.isEmpty()){
+ headers.add(String.format("Cookie: %s", service.stringifyCookies()));
+ }
+ headers.add(String.format("Authorization: %s", service.getToken()));
+ }
+ headers.add("");
+ headers.forEach(header -> writer.println(header));
+ writer.flush();
return socket;
}
@@ -130,7 +136,7 @@ public void submit(String indexName, String data) {
* Submits an event to this index through HTTP POST.
*
* @param data A string containing event data.
- * @param args Optional arguments for this stream. Valid parameters are:
+ * @param args Optional arguments for this stream. Valid parameters are:
* "host", "host_regex", "source", and "sourcetype".
*/
public void submit(Args args, String data) {
@@ -142,7 +148,7 @@ public void submit(Args args, String data) {
*
* @param indexName The index to write to.
* @param data A string containing event data.
- * @param args Optional arguments for this stream. Valid parameters are:
+ * @param args Optional arguments for this stream. Valid parameters are:
* "host", "host_regex", "source", and "sourcetype".
*/
public void submit(String indexName, Args args, String data) {
@@ -190,7 +196,7 @@ public void log(String indexName, String data) {
* Submits an event to this index through HTTP POST. This method is an alias
* for {@code submit()}.
*
- * @param args Optional arguments for this stream. Valid parameters are:
+ * @param args Optional arguments for this stream. Valid parameters are:
* "host", "host_regex", "source", and "sourcetype".
* @param data A string containing event data.
*/
@@ -203,11 +209,11 @@ public void log(Args args, String data) {
* for {@code submit()}.
*
* @param indexName The index to write to.
- * @param args Optional arguments for this stream. Valid parameters are:
+ * @param args Optional arguments for this stream. Valid parameters are:
* "host", "host_regex", "source", and "sourcetype".
* @param data A string containing event data.
*/
public void log(String indexName, Args args, String data) {
submit(indexName, args, data);
}
-}
\ No newline at end of file
+}
diff --git a/splunk/com/splunk/ReceiverBehavior.java b/splunk/src/main/java/com/splunk/ReceiverBehavior.java
similarity index 100%
rename from splunk/com/splunk/ReceiverBehavior.java
rename to splunk/src/main/java/com/splunk/ReceiverBehavior.java
diff --git a/splunk/com/splunk/Record.java b/splunk/src/main/java/com/splunk/Record.java
similarity index 100%
rename from splunk/com/splunk/Record.java
rename to splunk/src/main/java/com/splunk/Record.java
diff --git a/splunk/com/splunk/RegexpDataModelCalculation.java b/splunk/src/main/java/com/splunk/RegexpDataModelCalculation.java
similarity index 100%
rename from splunk/com/splunk/RegexpDataModelCalculation.java
rename to splunk/src/main/java/com/splunk/RegexpDataModelCalculation.java
diff --git a/splunk/com/splunk/RequestMessage.java b/splunk/src/main/java/com/splunk/RequestMessage.java
similarity index 95%
rename from splunk/com/splunk/RequestMessage.java
rename to splunk/src/main/java/com/splunk/RequestMessage.java
index 5e258ed2..816e1fe2 100644
--- a/splunk/com/splunk/RequestMessage.java
+++ b/splunk/src/main/java/com/splunk/RequestMessage.java
@@ -32,7 +32,11 @@ public class RequestMessage {
/** Creates a new {@code RequestMessage} instance. */
public RequestMessage() {}
- /** Creates a new {@code RequestMessage} instance with a given method */
+ /**
+ * Creates a new {@code RequestMessage} instance with a given method
+ *
+ * @param method String value
+ */
public RequestMessage(String method) {
this.method = method;
}
diff --git a/splunk/com/splunk/Resource.java b/splunk/src/main/java/com/splunk/Resource.java
similarity index 93%
rename from splunk/com/splunk/Resource.java
rename to splunk/src/main/java/com/splunk/Resource.java
index 8d8ecc42..4dc43e27 100644
--- a/splunk/com/splunk/Resource.java
+++ b/splunk/src/main/java/com/splunk/Resource.java
@@ -16,7 +16,7 @@
package com.splunk;
-
+import java.util.Date;
import java.util.Map;
/**
@@ -35,6 +35,7 @@ public abstract class Resource {
/* Initialized by {@link #load()}. */
protected Map actions;
protected String title;
+ protected Date updated;
private boolean maybeValid = false;
/**
@@ -128,6 +129,16 @@ public String getTitle() {
return validate().title;
}
+ /**
+ * Return the last updated time of this resource, which corresponds to the Atom
+ * {@code } element.
+ *
+ * @return The resource last updated time.
+ */
+ public Date getUpdated() {
+ return validate().updated;
+ }
+
/**
* Marks the local state of this resource as no longer current.
*
@@ -152,6 +163,7 @@ Resource load(AtomObject value) {
else {
this.actions = value.links;
this.title = value.title;
+ this.updated = Value.toDate(value.updated);
}
this.maybeValid = true;
return this;
diff --git a/splunk/com/splunk/ResourceCollection.java b/splunk/src/main/java/com/splunk/ResourceCollection.java
similarity index 98%
rename from splunk/com/splunk/ResourceCollection.java
rename to splunk/src/main/java/com/splunk/ResourceCollection.java
index 02b52499..b81ecb8a 100644
--- a/splunk/com/splunk/ResourceCollection.java
+++ b/splunk/src/main/java/com/splunk/ResourceCollection.java
@@ -259,6 +259,12 @@ private Args namespace(AtomEntry entry) {
HashMap entityMetadata =
(HashMap)entry.content.get("eai:acl");
+
+ // If there is no ACL info, we just create an empty map
+ if (entityMetadata == null) {
+ entityMetadata = new HashMap();
+ }
+
if (entityMetadata.containsKey("owner"))
namespace.put("owner", entityMetadata.get("owner"));
if (entityMetadata.containsKey("app"))
diff --git a/splunk/com/splunk/ResponseMessage.java b/splunk/src/main/java/com/splunk/ResponseMessage.java
similarity index 100%
rename from splunk/com/splunk/ResponseMessage.java
rename to splunk/src/main/java/com/splunk/ResponseMessage.java
diff --git a/splunk/com/splunk/ResultsReader.java b/splunk/src/main/java/com/splunk/ResultsReader.java
similarity index 100%
rename from splunk/com/splunk/ResultsReader.java
rename to splunk/src/main/java/com/splunk/ResultsReader.java
diff --git a/splunk/com/splunk/ResultsReaderCsv.java b/splunk/src/main/java/com/splunk/ResultsReaderCsv.java
similarity index 95%
rename from splunk/com/splunk/ResultsReaderCsv.java
rename to splunk/src/main/java/com/splunk/ResultsReaderCsv.java
index 6cfb4e13..64b3dec8 100644
--- a/splunk/com/splunk/ResultsReaderCsv.java
+++ b/splunk/src/main/java/com/splunk/ResultsReaderCsv.java
@@ -43,7 +43,7 @@ public class ResultsReaderCsv extends ResultsReader {
* a different type of stream, unpredictable results may occur.
*
* @param inputStream The CSV stream to parse.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public ResultsReaderCsv(InputStream inputStream) throws IOException {
super(inputStream, false);
diff --git a/splunk/com/splunk/ResultsReaderJson.java b/splunk/src/main/java/com/splunk/ResultsReaderJson.java
similarity index 97%
rename from splunk/com/splunk/ResultsReaderJson.java
rename to splunk/src/main/java/com/splunk/ResultsReaderJson.java
index fdf3bcd8..6544f614 100644
--- a/splunk/com/splunk/ResultsReaderJson.java
+++ b/splunk/src/main/java/com/splunk/ResultsReaderJson.java
@@ -49,7 +49,7 @@ public class ResultsReaderJson extends ResultsReader {
* a different type of stream, unpredictable results may occur.
*
* @param inputStream The JSON stream to parse.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public ResultsReaderJson(InputStream inputStream) throws IOException {
this(inputStream, false);
diff --git a/splunk/com/splunk/ResultsReaderXml.java b/splunk/src/main/java/com/splunk/ResultsReaderXml.java
similarity index 96%
rename from splunk/com/splunk/ResultsReaderXml.java
rename to splunk/src/main/java/com/splunk/ResultsReaderXml.java
index 76cb45c0..e242ff8e 100644
--- a/splunk/com/splunk/ResultsReaderXml.java
+++ b/splunk/src/main/java/com/splunk/ResultsReaderXml.java
@@ -53,7 +53,7 @@ public class ResultsReaderXml
* data, and only extracts finalized data.
*
* @param inputStream The XML stream to parse.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
public ResultsReaderXml(InputStream inputStream) throws IOException {
this(inputStream, false);
diff --git a/splunk/com/splunk/Role.java b/splunk/src/main/java/com/splunk/Role.java
similarity index 98%
rename from splunk/com/splunk/Role.java
rename to splunk/src/main/java/com/splunk/Role.java
index 5be53397..5de4dc9a 100644
--- a/splunk/com/splunk/Role.java
+++ b/splunk/src/main/java/com/splunk/Role.java
@@ -290,14 +290,14 @@ public void setDefaultApp(String defaultApp) {
* allowed indexes to search. In combining multiple roles, the effective
* value for each attribute is the value with the broadest permissions.
*
- * Default Splunk roles are:
- *
+ * Default Splunk roles are:
+ *
*
admin
*
can_delete
*
power
*
user
*
- * You also can specify additional roles that have been created.
+ * You also can specify additional roles that have been created.
*
* @param importedRoles An array of roles from which to import attributes.
*/
@@ -309,16 +309,16 @@ public void setImportedRoles(String[] importedRoles) {
* Sets a role to import attributes from, such as capabilities and allowed
* indexes to search. Use this method to set a single role.
*
Importing other roles imports all aspects of that role, such as
- * capabilities and allowed indexes to search.
+ * capabilities and allowed indexes to search.
*
- * Default Splunk roles are:
- *
+ * Default Splunk roles are:
+ *
*
admin
*
can_delete
*
power
*
user
*
- * You also can specify additional roles that have been created.
+ * You also can specify additional roles that have been created.
*
* @param importedRole A role from which to import attributes.
*/
diff --git a/splunk/src/main/java/com/splunk/SSLSecurityProtocol.java b/splunk/src/main/java/com/splunk/SSLSecurityProtocol.java
new file mode 100644
index 00000000..8e223cac
--- /dev/null
+++ b/splunk/src/main/java/com/splunk/SSLSecurityProtocol.java
@@ -0,0 +1,16 @@
+package com.splunk;
+
+public enum SSLSecurityProtocol {
+ TLSv1_2 {
+ public String toString() { return "TLSv1.2"; }
+ },
+ TLSv1_1 {
+ public String toString() { return "TLSv1.1"; }
+ },
+ TLSv1 {
+ public String toString() { return "TLSv1"; }
+ },
+ SSLv3 {
+ public String toString() { return "SSLv3"; }
+ }
+}
diff --git a/splunk/com/splunk/SavedSearch.java b/splunk/src/main/java/com/splunk/SavedSearch.java
similarity index 97%
rename from splunk/com/splunk/SavedSearch.java
rename to splunk/src/main/java/com/splunk/SavedSearch.java
index adf87fcb..b01fe17d 100644
--- a/splunk/com/splunk/SavedSearch.java
+++ b/splunk/src/main/java/com/splunk/SavedSearch.java
@@ -58,6 +58,7 @@ public void acknowledge() {
* Runs the saved search.
*
* @return The search job.
+ * @throws InterruptedException The InterruptedException instance
*/
public Job dispatch() throws InterruptedException {
return dispatch(null);
@@ -67,24 +68,23 @@ public Job dispatch() throws InterruptedException {
* Runs the saved search using dispatch arguments.
*
* @param args Dispatch arguments:
- *
"dispatch.now": A time string that is used to dispatch the search as
+ *
"dispatch.now": A time string that is used to dispatch the search as
* though the specified time were the current time.
- *
"dispatch.*": Overwrites the value of the search field specified in
+ *
"dispatch.*": Overwrites the value of the search field specified in
* "*".
- *
"trigger_actions": A Boolean that indicates whether to trigger alert
+ *
"trigger_actions": A Boolean that indicates whether to trigger alert
* actions.
- *
"force_dispatch": A Boolean that indicates whether to start a new
+ *
"force_dispatch": A Boolean that indicates whether to start a new
* search if another instance of this search is already running.
* @return The search job.
+ * @throws InterruptedException The InterruptedException instance
*/
public Job dispatch(Map args) throws InterruptedException {
ResponseMessage response = service.post(actionPath("dispatch"), args);
invalidate();
String sid = Job.getSid(response);
- Job job;
- JobCollection jobs = service.getJobs();
- job = jobs.get(sid);
+ Job job = service.getJob(sid);
// if job not yet scheduled, create an empty job object
if (job == null) {
@@ -93,12 +93,13 @@ public Job dispatch(Map args) throws InterruptedException {
return job;
}
-
+
/**
* Runs the saved search using dispatch arguments.
*
* @param args Dispatch arguments (see {@link SavedSearchDispatchArgs}).
* @return The search job.
+ * @throws InterruptedException The InterruptedException instance
*/
// NOTE: This overload exists primarily to provide better documentation
// for the "args" parameter.
@@ -113,6 +114,28 @@ public Job dispatch(SavedSearchDispatchArgs args) throws InterruptedException {
*/
public Job[] history() {
ResponseMessage response = service.get(actionPath("history"));
+ AtomFeed feed;
+ return parseHistoryResponse(response);
+ }
+
+ /**
+ * Returns an array of search jobs based on passed search arguments
+ *
+ * @param args
+ * @return An array of search jobs
+ */
+ public Job[] history(Map 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());
@@ -169,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).
@@ -629,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).
@@ -905,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.
@@ -927,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.
@@ -1163,6 +1186,30 @@ public boolean isVisible() {
return getBoolean("is_visible");
}
+ /**
+ * Indicates whether embedding is enabled for the search.
+ *
+ * @return {@code true} if the search is enabled for the search, {@code false} if not.
+ */
+ public boolean isEmbedEnabled() {
+ if (service.versionIsEarlierThan("6.2.0")){
+ throw new UnsupportedOperationException();
+ }
+ return getBoolean("embed.enabled");
+ }
+
+ /**
+ * Returns the authorization token for embedding the search.
+ *
+ * @return The authorization token for embedding the search.
+ */
+ public String getEmbedToken() {
+ if (service.versionIsEarlierThan("6.2.0")) {
+ throw new UnsupportedOperationException();
+ }
+ return getString("embed.token", null);
+ }
+
/**
* Sets the password to use when authenticating with the SMTP server.
* Normally this value will be set when editing the email settings, however
@@ -1210,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).
@@ -1522,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).
@@ -1589,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).
@@ -1677,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).
@@ -1807,7 +1854,7 @@ public void setAlertSuppress(boolean suppress) {
/**
* Specifies a list of fields to use for alert suppression. This attribute
- * is required when alert supression and per-result alerting are enabled.
+ * is required when alert suppression and per-result alerting are enabled.
* @see #setAlertSuppress
* @see #isDigestMode
*
@@ -1929,7 +1976,7 @@ public void setDisabled(boolean disabled) {
public void setDispatchBuckets(String buckets) {
setDispatchBuckets(Integer.parseInt(buckets));
}
-
+
/**
* Sets the maximum number of timeline buckets.
*
@@ -2136,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/com/splunk/SavedSearchCollection.java b/splunk/src/main/java/com/splunk/SavedSearchCollection.java
similarity index 100%
rename from splunk/com/splunk/SavedSearchCollection.java
rename to splunk/src/main/java/com/splunk/SavedSearchCollection.java
diff --git a/splunk/com/splunk/SavedSearchCollectionArgs.java b/splunk/src/main/java/com/splunk/SavedSearchCollectionArgs.java
similarity index 100%
rename from splunk/com/splunk/SavedSearchCollectionArgs.java
rename to splunk/src/main/java/com/splunk/SavedSearchCollectionArgs.java
diff --git a/splunk/com/splunk/SavedSearchDispatchArgs.java b/splunk/src/main/java/com/splunk/SavedSearchDispatchArgs.java
similarity index 100%
rename from splunk/com/splunk/SavedSearchDispatchArgs.java
rename to splunk/src/main/java/com/splunk/SavedSearchDispatchArgs.java
diff --git a/splunk/com/splunk/ScriptInput.java b/splunk/src/main/java/com/splunk/ScriptInput.java
similarity index 100%
rename from splunk/com/splunk/ScriptInput.java
rename to splunk/src/main/java/com/splunk/ScriptInput.java
diff --git a/splunk/com/splunk/SearchResults.java b/splunk/src/main/java/com/splunk/SearchResults.java
similarity index 100%
rename from splunk/com/splunk/SearchResults.java
rename to splunk/src/main/java/com/splunk/SearchResults.java
diff --git a/splunk/com/splunk/Service.java b/splunk/src/main/java/com/splunk/Service.java
similarity index 86%
rename from splunk/com/splunk/Service.java
rename to splunk/src/main/java/com/splunk/Service.java
index 3eed2944..57609010 100644
--- a/splunk/com/splunk/Service.java
+++ b/splunk/src/main/java/com/splunk/Service.java
@@ -19,9 +19,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
-import java.net.Socket;
-import java.net.URLEncoder;
-import java.net.URLStreamHandler;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
/**
@@ -58,7 +58,7 @@ public class Service extends BaseService {
protected String password = null;
/** The default simple receiver endpoint. */
- protected String simpleReceiverEndPoint = "receivers/simple";
+ protected String simpleReceiverEndPoint = "/services/receivers/simple";
/** The default password endpoint, can change over Splunk versions. */
protected String passwordEndPoint = "admin/passwords";
@@ -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";
@@ -106,18 +109,19 @@ public Service(String host, int port) {
public Service(String host, int port, String scheme) {
super(host, port, scheme);
}
-
+
/**
* Constructs a new {@code Service} instance using the given host,
* port, and scheme, and instructing it to use the specified HTTPS handler.
*
* @param host The host name of the service.
* @param port The port number of the service.
- * @param scheme Scheme for accessing the service ({@code http} or
+ * @param scheme Scheme for accessing the service ({@code http} or
* {@code https}).
+ * @param httpsHandler The URLStreamHandler instance
*/
- public Service(String host, int port, String scheme,
- URLStreamHandler httpsHandler) {
+ public Service(String host, int port, String scheme,
+ URLStreamHandler httpsHandler) {
this.host = host;
this.port = port;
this.scheme = scheme;
@@ -149,6 +153,9 @@ public Service(ServiceArgs args) {
this.username = (String)args.get("username");
this.password = (String)args.get("password");
this.httpsHandler = Args.get(args, "httpsHandler", null);
+ this.setSslSecurityProtocol(Args.get(args, "SSLSecurityProtocol", Service.getSslSecurityProtocol()));
+ this.addCookie((String)args.get("cookie"));
+ this.setCustomHeaders((Map) args.get("customHeaders"));
}
/**
@@ -167,11 +174,15 @@ public Service(Map args) {
this.username = (String)args.get("username");
this.password = (String)args.get("password");
this.httpsHandler = Args.get(args, "httpsHandler", null);
+ this.setSslSecurityProtocol(Args.get(args, "SSLSecurityProtocol", Service.getSslSecurityProtocol()));
+ this.addCookie((String)args.get("cookie"));
+ this.connectTimeout = Args.get(args, "connectTimeout", null);
+ this.readTimeout = Args.get(args, "readTimeout", null);
}
/**
- * Establishes a connection to a Splunk service using a map of arguments.
- * This member creates a new {@code Service} instance and authenticates
+ * Establishes a connection to a Splunk service using a map of arguments.
+ * This member creates a new {@code Service} instance and authenticates
* the session using credentials passed in from the {@code args} map.
*
* @param args The {@code args} map.
@@ -186,7 +197,7 @@ public static Service connect(Map args) {
}
/**
- * Runs an export search (using the {@code search/jobs/export} endpoint),
+ * Runs an export search (using the {@code search/jobs/export} endpoint),
* and streams results back in an input stream.
*
* @param search The search query to run.
@@ -201,12 +212,12 @@ public InputStream export(String search) {
* endpoint), and streams results back in an input stream.
*
* @param search The search query to run.
- * @param args Additional search arguments.
+ * @param args Additional search arguments.
* For a list of possible parameters, see
- * Saved search parameters on
- * dev.splunk.com.
+ * Saved search parameters on
+ * dev.splunk.com.
* @return The {@code InputStream} object that contains the search results.
*/
public InputStream export(String search, Map args) {
@@ -215,10 +226,16 @@ public InputStream export(String search, Map args) {
if (!args.containsKey("segmentation")) {
args.put("segmentation", "none");
}
- ResponseMessage response = get(JobCollection.REST_PATH + "/export", args);
+ ResponseMessage response;
+
+ if(enableV2SearchApi())
+ response = post(JobCollection.REST_PATH_V2 + "/export", args);
+ else {
+ response = post(JobCollection.REST_PATH + "/export", args);
+ }
return new ExportResultsStream(response.getContent());
}
-
+
/**
* Runs an export search with arguments (using the {@code search/jobs/export}
* endpoint), and streams results back in an input stream.
@@ -235,7 +252,7 @@ public InputStream export(String search, JobExportArgs args) {
/**
* Ensures that the given path is fully qualified, prepending a path
- * prefix if necessary. The path prefix is constructed using the current
+ * prefix if necessary. The path prefix is constructed using the current
* owner and app context when available.
*
* @param path The path to verify.
@@ -315,8 +332,8 @@ else if (localSharing.equals("system")) {
}
/**
- * Returns the app context for this {@code Service} instance.
- * A {@code null} value indicates no app context, and a value of
+ * Returns the app context for this {@code Service} instance.
+ * A {@code null} value indicates no app context, and a value of
* {@code "-"} indicates an app wildcard.
*
* @return The app context.
@@ -347,7 +364,7 @@ public ConfCollection getConfs() {
/**
* Returns the collection of configurations.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return The configurations collection.
*/
@@ -367,6 +384,7 @@ public String[] getCapabilities() {
/**
* Returns the collection of data models.
+ * @return DataModelCollection instance
*/
public DataModelCollection getDataModels() {
return new DataModelCollection(this);
@@ -393,7 +411,7 @@ public EntityCollection getDeploymentServers() {
/**
* Returns the collection of deployment servers.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return The configuration of deployment servers.
*/
@@ -420,7 +438,7 @@ public EntityCollection getDeploymentServerClasses(){
/**
* Returns a collection of class configurations for a deployment server.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of server class configurations.
*/
@@ -448,7 +466,7 @@ public EntityCollection getDeploymentTenants() {
/**
* Returns a collection of multi-tenant configurations.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of multi-tenant configurations.
*/
@@ -484,7 +502,7 @@ public EntityCollection getDistributedPeers() {
* The Splunk server where the search originates is referred to as the
* search head.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of search peers.
*/
@@ -506,7 +524,7 @@ public EventTypeCollection getEventTypes() {
/**
* Returns a collection of saved event types.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of saved event types.
*/
@@ -526,7 +544,7 @@ public FiredAlertGroupCollection getFiredAlertGroups() {
/**
* Returns a collection of alerts that have been fired by the service.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of fired alerts.
*/
@@ -542,11 +560,11 @@ public FiredAlertGroupCollection getFiredAlertsGroups(Args args) {
public IndexCollection getIndexes() {
return getIndexes((IndexCollectionArgs)null);
}
-
+
/**
* Returns a collection of Splunk indexes.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link IndexCollectionArgs}.
* @return A collection of indexes.
*/
@@ -559,7 +577,7 @@ public IndexCollection getIndexes(IndexCollectionArgs args) {
/**
* Returns a collection of Splunk indexes.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link IndexCollectionArgs}.
* @return A collection of indexes.
*/
@@ -576,6 +594,35 @@ public ServiceInfo getInfo() {
return new ServiceInfo(this);
}
+ /**
+ * Returns list of all applicable Cluster Master Hosts for the SearchHead Service.
+ *
+ * @return List of Cluster Master Host(s).
+ */
+ public List getClusterMasters(){
+ Entity caps = new Entity(this, "cluster/config");
+ List hosts = new ArrayList();
+ try {
+ String clusterMasterURIs = caps.getString("master_uri");
+ URL clusterMasterUrl;
+ //for multi-cluster environment, there might be more than cluster master for the searchHead
+ if(clusterMasterURIs.contains(",")){
+ String[] masterURIs = clusterMasterURIs.split(",");
+ for(String uri : masterURIs){
+ clusterMasterUrl = new URL(uri);
+ hosts.add(clusterMasterUrl.getHost());
+ }
+ }else {
+ clusterMasterUrl = new URL(clusterMasterURIs);
+ hosts.add(clusterMasterUrl.getHost());
+ }
+ return hosts;
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ }
+ return hosts;
+ }
+
/**
* Returns a collection of configured inputs.
*
@@ -588,7 +635,7 @@ public InputCollection getInputs() {
/**
* Returns a collection of configured inputs.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of inputs.
*/
@@ -604,11 +651,11 @@ public InputCollection getInputs(Args args) {
public JobCollection getJobs() {
return getJobs((CollectionArgs)null);
}
-
+
/**
* Returns a collection of current search jobs.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of search jobs.
*/
@@ -621,7 +668,7 @@ public JobCollection getJobs(CollectionArgs args) {
/**
* Returns a collection of current search jobs.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of search jobs.
*/
@@ -651,7 +698,7 @@ public EntityCollection getLicenseGroups() {
/**
* Returns a collection of license group configurations.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of license group configurations.
*/
@@ -672,7 +719,7 @@ public EntityCollection getLicenseMessages() {
/**
* Returns a collection of messages from the licenser.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of licenser messages.
*/
@@ -682,8 +729,8 @@ public EntityCollection getLicenseMessages(Args args) {
}
/**
- * Returns the current owner context for this {@code Service} instance.
- * A value of {@code "-"} indicates a wildcard, and a {@code null} value
+ * Returns the current owner context for this {@code Service} instance.
+ * A value of {@code "-"} indicates a wildcard, and a {@code null} value
* indicates no owner context.
*
* @return The current owner context.
@@ -704,7 +751,7 @@ public LicensePoolCollection getLicensePools() {
/**
* Returns a collection of licenser pool configurations.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of licenser pool configurations.
*/
@@ -724,7 +771,7 @@ public EntityCollection getLicenseSlaves() {
/**
* Returns a collection of slaves reporting to this license master.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of licenser slaves.
*/
@@ -745,7 +792,7 @@ public EntityCollection getLicenseStacks() {
/**
* Returns a collection of license stack configurations.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of license stack configurations.
*/
@@ -766,7 +813,7 @@ public EntityCollection getLicenses() {
/**
* Returns a collection of licenses for this service.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of licenses.
*/
@@ -787,7 +834,7 @@ public EntityCollection getLoggers() {
/**
* Returns a collection of service logging categories and their status.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of logging categories.
*/
@@ -808,14 +855,14 @@ public MessageCollection getMessages() {
/**
* Returns a collection of system messages.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of system messages.
*/
public MessageCollection getMessages(Args args) {
return new MessageCollection(this, args);
}
-
+
/**
* Returns a collection of modular inputs.
*
@@ -828,7 +875,7 @@ public ResourceCollection getModularInputKinds() {
/**
* Returns a collection of modular inputs.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of modular inputs.
*/
@@ -858,7 +905,7 @@ public EntityCollection getOutputGroups() {
/**
* Returns a collection of output group configurations.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of output group configurations.
*/
@@ -879,7 +926,7 @@ public EntityCollection getOutputServers() {
/**
* Returns a collection of data-forwarding configurations.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of data-forwarding configurations.
*/
@@ -902,7 +949,7 @@ public EntityCollection getOutputSyslogs() {
* Returns a collection of configurations for forwarding data in standard
* syslog format.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of syslog forwarders.
*/
@@ -934,7 +981,7 @@ public PasswordCollection getPasswords() {
* Returns a collection of passwords. This collection is used for managing
* secure credentials.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of passwords.
*/
@@ -963,7 +1010,7 @@ public EntityCollection getRoles() {
/**
* Returns a collection of Splunk user roles.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of user roles.
*/
@@ -980,11 +1027,11 @@ public EntityCollection getRoles(Args args) {
public SavedSearchCollection getSavedSearches() {
return getSavedSearches((SavedSearchCollectionArgs)null);
}
-
+
/**
* Returns a collection of saved searches.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link SavedSearchCollectionArgs}.
* @return A collection of saved searches.
*/
@@ -997,7 +1044,7 @@ public SavedSearchCollection getSavedSearches(SavedSearchCollectionArgs args) {
/**
* Returns a collection of saved searches.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of saved searches.
*/
@@ -1005,6 +1052,16 @@ public SavedSearchCollection getSavedSearches(Args args) {
return new SavedSearchCollection(this, args);
}
+ /**
+ * Returns a Saved Search by the provided title key.
+ *
+ * @param title The title for a job.
+ * @return A SavedSearch.
+ */
+ public SavedSearch getSavedSearch(String title) {
+ return new SavedSearch(this, JobCollection.REST_PATH + "/" + title);
+ }
+
/**
* Returns service configuration information for an instance of Splunk.
*
@@ -1067,7 +1124,7 @@ public UserCollection getUsers() {
/**
* Returns a collection of Splunk users.
*
- * @param args Collection arguments that specify the number of entities to
+ * @param args Collection arguments that specify the number of entities to
* return and how to sort them. See {@link CollectionArgs}.
* @return A collection of users.
*/
@@ -1078,21 +1135,29 @@ public UserCollection getUsers(Args args) {
/**
* Authenticates the {@code Service} instance with the username and password
* that were specified when the instance was created.
- *
+ *
+ * Three cases:
+ * 1. If we have a cookie, but are missing username and/or password, login is noop
+ * 2. If we don't have a cookie, and are missing username and/or password we can't login
+ * 3. Otherwise login as usual
+ *
* @return The current {@code Service} instance.
*/
public Service login() {
- if (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) {
throw new IllegalStateException("Missing username or password.");
}
else {
return login(this.username, this.password);
}
}
-
+
/**
- * Authenticates the {@code Service} instance with a specified username and
- * password. Note that these values override any previously-set values for
+ * Authenticates the {@code Service} instance with a specified username and
+ * password. Note that these values override any previously-set values for
* username and password.
*
* @param username The Splunk account username.
@@ -1106,6 +1171,7 @@ public Service login(String username, String password) {
Args args = new Args();
args.put("username", username);
args.put("password", password);
+ args.put("cookie", "1");
ResponseMessage response = post("/services/auth/login", args);
String sessionKey = Xml.parse(response.getContent())
.getElementsByTagName("sessionKey")
@@ -1113,6 +1179,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";
@@ -1126,6 +1193,7 @@ public Service login(String username, String password) {
*/
public Service logout() {
this.token = null;
+ this.removeAllCookies();
return this;
}
@@ -1146,11 +1214,11 @@ public InputStream oneshotSearch(String query) {
* @param args The search arguments:
*
"output_mode": Specifies the output format of the results (XML, JSON,
* or CSV).
- *
"earliest_time": Specifies the earliest time in the time range to
- * search. The time string can be a UTC time (with fractional seconds), a
+ *
"earliest_time": Specifies the earliest time in the time range to
+ * search. The time string can be a UTC time (with fractional seconds), a
* relative time specifier (to now), or a formatted time string.
*
"latest_time": Specifies the latest time in the time range to search.
- * The time string can be a UTC time (with fractional seconds), a relative
+ * The time string can be a UTC time (with fractional seconds), a relative
* time specifier (to now), or a formatted time string.
*
"rf": Specifies one or more fields to add to the search.
* @return The search results.
@@ -1176,11 +1244,11 @@ public InputStream oneshotSearch(String query, Map args) {
* @param args The search arguments:
*
"output_mode": Specifies the output format of the results (XML, JSON,
* or CSV).
- *
"earliest_time": Specifies the earliest time in the time range to
- * search. The time string can be a UTC time (with fractional seconds), a
+ *
"earliest_time": Specifies the earliest time in the time range to
+ * search. The time string can be a UTC time (with fractional seconds), a
* relative time specifier (to now), or a formatted time string.
*
"latest_time": Specifies the latest time in the time range to search.
- * The time string can be a UTC time (with fractional seconds), a relative
+ * The time string can be a UTC time (with fractional seconds), a relative
* time specifier (to now), or a formatted time string.
*
"rf": Specifies one or more fields to add to the search.
* @return The search results.
@@ -1195,14 +1263,14 @@ public InputStream oneshotSearch(String query, Args args) {
* @param port The port to open. This port must already have been
* created as an allowable TCP input to the service.
* @return The socket.
- * @throws java.io.IOException
+ * @throws java.io.IOException The IOException instance
*/
public Socket open(int port) throws IOException {
return new Socket(this.host, port);
}
/**
- * Parses a search query and returns a semantic map for the search in JSON
+ * Parses a search query and returns a semantic map for the search in JSON
* format.
*
* @param query The search query.
@@ -1222,12 +1290,16 @@ public ResponseMessage parse(String query) {
*/
public ResponseMessage parse(String query, Map args) {
args = Args.create(args).add("q", query);
- return get("search/parser", args);
+
+ if(enableV2SearchApi())
+ return post("search/v2/parser", args);
+ else
+ return get("search/parser", args);
}
/**
* Restarts the service. The service will be unavailable until it has
- * sucessfully restarted.
+ * successfully restarted.
*
* @return The restart response message.
*/
@@ -1261,10 +1333,10 @@ public Job search(String query, Map args) {
}
/**
- * Issues an HTTP request against the service using a request path and
- * message.
+ * Issues an HTTP request against the service using a request path and
+ * message.
* This method overrides the base {@code HttpService.send} method
- * and applies the Splunk authorization header, which is required for
+ * and applies the Splunk authorization header, which is required for
* authenticated interactions with the Splunk service.
*
* @param path The request path.
@@ -1272,24 +1344,57 @@ public Job search(String query, Map args) {
* @return The HTTP response.
*/
@Override public ResponseMessage send(String path, RequestMessage request) {
- if (token != null) {
+ // cookieStore is a protected member of HttpService
+ if (token != null && !cookieStore.hasSplunkAuthCookie() ) {
request.getHeader().put("Authorization", token);
}
return super.send(fullpath(path), request);
}
/**
- * Provides a session token for use by this {@code Service} instance.
+ * Provides a session token for use by this {@code Service} instance.
* Session tokens can be shared across multiple {@code Service} instances.
*
- * @param value The session token, which is a basic authorization header in
- * the format "Basic sessiontoken", where sessiontoken is the
+ * @param value The session token, which is a basic authorization header in
+ * the format "Basic sessiontoken", where sessiontoken is the
* Base64-encoded "username:password" string.
*/
public void setToken(String value) {
this.token = value;
}
+ /**
+ * Provides a session token having Splunk added before token.
+ * This method is specifically used when user just have token value.
+ *
+ * @param value The token value
+ */
+ public void setSplunkToken(String value) {
+ this.token = value.contains("Splunk") ? value : "Splunk " + value;
+ }
+
+ /**
+ * Provides a session token having Bearer added before token.
+ * This method is specifically used when user just have token value.
+ *
+ * @param value The token value
+ */
+ public void setBearerToken(String value) {
+ this.token = value.contains("Splunk") || value.contains("Bearer") ? value : "Bearer " + value;
+ }
+
+
+ public boolean enableV2SearchApi(){
+ if(null == this.instanceType){
+ this.instanceType = this.getInfo().getInstanceType();
+ }
+ 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}.
@@ -1325,23 +1430,26 @@ boolean versionIsEarlierThan(String version) {
}
/**
- * Returns a value indicating how the version of this Splunk instance
- * compares to a given version:
+ * Returns a value indicating how the version of this Splunk instance
+ * compares to a given version:
*
*
{@code -1 if this version < the given version}
*
{@code 0 if this version = the given version}
*
{@code 1 if this version > the given version}
*
- *
- * @param otherVersion The other version to compare to.
- * @return -1 if this version is less than, 0 if this version is equal to,
+ *
+ * @param otherVersion The other version to compare to.
+ * @return -1 if this version is less than, 0 if this version is equal to,
* or 1 if this version is greater than the given version.
*/
public int versionCompare(String otherVersion) {
+ if(null == this.version){
+ this.version = this.getInfo().getVersion();
+ }
String[] components1 = this.version.split("\\.");
String[] components2 = otherVersion.split("\\.");
int numComponents = Math.max(components1.length, components2.length);
-
+
for (int i = 0; i < numComponents; i++) {
int c1 = (i < components1.length)
? Integer.parseInt(components1[i], 10) : 0;
diff --git a/splunk/com/splunk/ServiceArgs.java b/splunk/src/main/java/com/splunk/ServiceArgs.java
similarity index 84%
rename from splunk/com/splunk/ServiceArgs.java
rename to splunk/src/main/java/com/splunk/ServiceArgs.java
index a4040990..bf8f7f03 100644
--- a/splunk/com/splunk/ServiceArgs.java
+++ b/splunk/src/main/java/com/splunk/ServiceArgs.java
@@ -17,15 +17,16 @@
package com.splunk;
import java.net.URLStreamHandler;
+import java.util.Map;
/**
- * The {@code ServiceArgs} class contains a collection of arguments that are
+ * The {@code ServiceArgs} class contains a collection of arguments that are
* used to initialize a Splunk {@code Service} instance.
*/
public class ServiceArgs extends Args {
/**
* The application context of the service.
- *
+ *
* @deprecated
* Use {@link #setApp(String)} instead.
*/
@@ -33,7 +34,7 @@ public class ServiceArgs extends Args {
/**
* The host name of the service.
- *
+ *
* @deprecated
* Use {@link #setHost(String)} instead.
*/
@@ -41,7 +42,7 @@ public class ServiceArgs extends Args {
/**
* The owner context of the service.
- *
+ *
* @deprecated
* Use {@link #setOwner(String)} instead.
*/
@@ -49,7 +50,7 @@ public class ServiceArgs extends Args {
/**
* The port number of the service.
- *
+ *
* @deprecated
* Use {@link #setPort(int)} instead.
*/
@@ -57,7 +58,7 @@ public class ServiceArgs extends Args {
/**
* The scheme to use for accessing the service.
- *
+ *
* @deprecated
* Use {@link #setScheme(String)} instead.
*/
@@ -65,12 +66,12 @@ public class ServiceArgs extends Args {
/**
* A Splunk authentication token to use for the session.
- *
+ *
* @deprecated
* Use {@link #setToken(String)} instead.
*/
public String token = null;
-
+
/**
* @param app
* The application context of the service.
@@ -79,7 +80,7 @@ public void setApp(String app) {
this.app = app; // for backward compatibility
this.put("app", app);
}
-
+
/**
* @param host
* The host name of the service.
@@ -88,7 +89,7 @@ public void setHost(String host) {
this.host = host; // for backward compatibility
this.put("host", host);
}
-
+
/**
* @param handler
* A URLStreamHandler to handle HTTPS requests for the service.
@@ -96,7 +97,7 @@ public void setHost(String host) {
public void setHTTPSHandler(URLStreamHandler handler) {
this.put("httpsHandler", handler);
}
-
+
/**
* @param owner
* The owner context of the service.
@@ -105,7 +106,7 @@ public void setOwner(String owner) {
this.owner = owner; // for backward compatibility
this.put("owner", owner);
}
-
+
/**
* @param password
* The password to use when logging in.
@@ -113,7 +114,7 @@ public void setOwner(String owner) {
public void setPassword(String password) {
this.put("password", password);
}
-
+
/**
* @param port
* The port number of the service.
@@ -122,7 +123,7 @@ public void setPort(int port) {
this.port = port; // for backward compatibility
this.put("port", port);
}
-
+
/**
* @param scheme
* The scheme to use for accessing the service.
@@ -131,7 +132,15 @@ public void setScheme(String scheme) {
this.scheme = scheme; // for backward compatibility
this.put("scheme", scheme);
}
-
+
+ /**
+ * @param securityProtocol
+ * The SSL security protocol for the service.
+ */
+ public void setSSLSecurityProtocol(SSLSecurityProtocol securityProtocol) {
+ this.put("SSLSecurityProtocol", securityProtocol);
+ }
+
/**
* @param token
* A Splunk authentication token to use for the session.
@@ -140,7 +149,7 @@ public void setToken(String token) {
this.token = token; // for backward compatibility
this.put("token", token);
}
-
+
/**
* @param username
* The username to use when logging in.
@@ -148,4 +157,20 @@ public void setToken(String token) {
public void setUsername(String username) {
this.put("username", username);
}
+
+ /**
+ * @param cookie
+ * A valid login cookie.
+ */
+ public void setCookie(String cookie) {
+ this.put("cookie", cookie);
+ }
+
+ /**
+ * @param httpHeaders
+ * A map of customHeaders.
+ */
+ public void setHttpHeaders(Map httpHeaders) {
+ this.put("customHeaders", httpHeaders);
+ }
}
diff --git a/splunk/com/splunk/ServiceInfo.java b/splunk/src/main/java/com/splunk/ServiceInfo.java
similarity index 96%
rename from splunk/com/splunk/ServiceInfo.java
rename to splunk/src/main/java/com/splunk/ServiceInfo.java
index 45d74ccb..16ec8aaa 100644
--- a/splunk/com/splunk/ServiceInfo.java
+++ b/splunk/src/main/java/com/splunk/ServiceInfo.java
@@ -34,8 +34,8 @@ public class ServiceInfo extends Entity {
*
* @return The build number.
*/
- public int getBuild() {
- return getInteger("build");
+ public String getBuild() {
+ return getString("build");
}
/**
@@ -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/com/splunk/Settings.java b/splunk/src/main/java/com/splunk/Settings.java
similarity index 100%
rename from splunk/com/splunk/Settings.java
rename to splunk/src/main/java/com/splunk/Settings.java
diff --git a/splunk/src/main/java/com/splunk/SimpleCookieStore.java b/splunk/src/main/java/com/splunk/SimpleCookieStore.java
new file mode 100644
index 00000000..4fd60664
--- /dev/null
+++ b/splunk/src/main/java/com/splunk/SimpleCookieStore.java
@@ -0,0 +1,93 @@
+
+/*
+ * Copyright 2015 Splunk, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"): you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.splunk;
+
+import java.util.List;
+import java.net.HttpCookie;
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.StringBuilder;
+
+/**
+ * The {@code SimpleCookieStore} class stores cookies for authentication.
+ */
+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.
+ *
+ * @param setCookieHeader The result from a getRequestHeader("Set-Cookie") call
+ */
+ public void add(String setCookieHeader) {
+ if (setCookieHeader != null) {
+ List cookies = HttpCookie.parse(setCookieHeader);
+ for (HttpCookie cookie : cookies) {
+ cookieJar.put(cookie.getName(), cookie.getValue());
+ }
+ }
+ }
+
+ /**
+ * Returns a string to be set as a "Cookie" header
+ *
+ * @return Cookie String in the format "Key=Value; Key=Value; etc"
+ */
+ public String getCookies() {
+ StringBuilder cookieStringBuilder = new StringBuilder();
+
+ for (Map.Entry cookie : cookieJar.entrySet()) {
+ cookieStringBuilder.append(cookie.getKey());
+ cookieStringBuilder.append("=");
+ cookieStringBuilder.append(cookie.getValue());
+ cookieStringBuilder.append("; ");
+ }
+ return cookieStringBuilder.toString();
+ }
+
+ /**
+ * Returns true if the cookie store is empty, false otherwise
+ *
+ * @return Boolean for whether or not the cookie store is empty
+ */
+ 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
+ */
+ public void removeAll() {
+ cookieJar.clear();
+ }
+
+}
diff --git a/splunk/com/splunk/SortDirection.java b/splunk/src/main/java/com/splunk/SortDirection.java
similarity index 100%
rename from splunk/com/splunk/SortDirection.java
rename to splunk/src/main/java/com/splunk/SortDirection.java
diff --git a/splunk/com/splunk/SplunkException.java b/splunk/src/main/java/com/splunk/SplunkException.java
similarity index 100%
rename from splunk/com/splunk/SplunkException.java
rename to splunk/src/main/java/com/splunk/SplunkException.java
diff --git a/splunk/com/splunk/StatsFunction.java b/splunk/src/main/java/com/splunk/StatsFunction.java
similarity index 96%
rename from splunk/com/splunk/StatsFunction.java
rename to splunk/src/main/java/com/splunk/StatsFunction.java
index cb753774..43b3cf86 100644
--- a/splunk/com/splunk/StatsFunction.java
+++ b/splunk/src/main/java/com/splunk/StatsFunction.java
@@ -1,8 +1,5 @@
package com.splunk;
-/**
- * Created by fross on 2/28/14.
- */
public enum StatsFunction {
LIST {
public String toString() { return "list"; }
diff --git a/splunk/com/splunk/StreamIterableBase.java b/splunk/src/main/java/com/splunk/StreamIterableBase.java
similarity index 95%
rename from splunk/com/splunk/StreamIterableBase.java
rename to splunk/src/main/java/com/splunk/StreamIterableBase.java
index 8f69e8f1..8c423d3d 100644
--- a/splunk/com/splunk/StreamIterableBase.java
+++ b/splunk/src/main/java/com/splunk/StreamIterableBase.java
@@ -61,7 +61,7 @@ public void remove() {
/**
* Get the next element.
* @return null if the end is reached.
- * @throws IOException
+ * @throws IOException The IOException instance
*/
abstract T getNextElement() throws IOException;
diff --git a/splunk/com/splunk/StringComparison.java b/splunk/src/main/java/com/splunk/StringComparison.java
similarity index 100%
rename from splunk/com/splunk/StringComparison.java
rename to splunk/src/main/java/com/splunk/StringComparison.java
diff --git a/splunk/com/splunk/StringPivotColumnSplit.java b/splunk/src/main/java/com/splunk/StringPivotColumnSplit.java
similarity index 100%
rename from splunk/com/splunk/StringPivotColumnSplit.java
rename to splunk/src/main/java/com/splunk/StringPivotColumnSplit.java
diff --git a/splunk/com/splunk/StringPivotFilter.java b/splunk/src/main/java/com/splunk/StringPivotFilter.java
similarity index 86%
rename from splunk/com/splunk/StringPivotFilter.java
rename to splunk/src/main/java/com/splunk/StringPivotFilter.java
index cb1eab86..ca6769ee 100644
--- a/splunk/com/splunk/StringPivotFilter.java
+++ b/splunk/src/main/java/com/splunk/StringPivotFilter.java
@@ -43,9 +43,11 @@ JsonElement toJson() {
addCommonFields(root);
- root.add("comparator", new JsonPrimitive(this.comparison.toString()));
- root.add("compareTo", new JsonPrimitive(this.comparisonValue));
+ JsonObject filterRule = new JsonObject();
+ filterRule.add("comparator", new JsonPrimitive(this.comparison.toString()));
+ filterRule.add("compareTo", new JsonPrimitive(this.comparisonValue));
+ root.add("rule", filterRule);
return root;
}
}
diff --git a/splunk/com/splunk/StringPivotRowSplit.java b/splunk/src/main/java/com/splunk/StringPivotRowSplit.java
similarity index 100%
rename from splunk/com/splunk/StringPivotRowSplit.java
rename to splunk/src/main/java/com/splunk/StringPivotRowSplit.java
diff --git a/splunk/com/splunk/TcpConnections.java b/splunk/src/main/java/com/splunk/TcpConnections.java
similarity index 100%
rename from splunk/com/splunk/TcpConnections.java
rename to splunk/src/main/java/com/splunk/TcpConnections.java
diff --git a/splunk/com/splunk/TcpInput.java b/splunk/src/main/java/com/splunk/TcpInput.java
similarity index 97%
rename from splunk/com/splunk/TcpInput.java
rename to splunk/src/main/java/com/splunk/TcpInput.java
index 57e434e4..29faa6b5 100644
--- a/splunk/com/splunk/TcpInput.java
+++ b/splunk/src/main/java/com/splunk/TcpInput.java
@@ -39,6 +39,8 @@ public class TcpInput extends PortInput {
/**
* Returns a socket attached to this raw TCP input.
+ * @return Socket instance
+ * @throws IOException The IOException instance
*/
public Socket attach() throws IOException {
return new Socket(this.service.getHost(), this.getPort());
@@ -54,7 +56,9 @@ public Socket attach() throws IOException {
* How to
* get data into Splunk on
* dev.splunk.com.
+ * target="_blank">dev.splunk.com.
+ * @param behavior The ReceiverBehavior instance
+ * @throws IOException The IOException instance
*/
public void attachWith(ReceiverBehavior behavior) throws IOException {
Socket socket = null;
@@ -249,6 +253,7 @@ public void setIndex(String index) {
* @see #attachWith
*
* @param eventBody A string that contains the event.
+ * @throws IOException The IOException instance
*/
public void submit(String eventBody) throws IOException {
Socket socket = null;
diff --git a/splunk/com/splunk/TcpSplunkInput.java b/splunk/src/main/java/com/splunk/TcpSplunkInput.java
similarity index 100%
rename from splunk/com/splunk/TcpSplunkInput.java
rename to splunk/src/main/java/com/splunk/TcpSplunkInput.java
diff --git a/splunk/com/splunk/TimestampBinning.java b/splunk/src/main/java/com/splunk/TimestampBinning.java
similarity index 100%
rename from splunk/com/splunk/TimestampBinning.java
rename to splunk/src/main/java/com/splunk/TimestampBinning.java
diff --git a/splunk/com/splunk/TimestampPivotColumnSplit.java b/splunk/src/main/java/com/splunk/TimestampPivotColumnSplit.java
similarity index 100%
rename from splunk/com/splunk/TimestampPivotColumnSplit.java
rename to splunk/src/main/java/com/splunk/TimestampPivotColumnSplit.java
diff --git a/splunk/com/splunk/TimestampPivotRowSplit.java b/splunk/src/main/java/com/splunk/TimestampPivotRowSplit.java
similarity index 100%
rename from splunk/com/splunk/TimestampPivotRowSplit.java
rename to splunk/src/main/java/com/splunk/TimestampPivotRowSplit.java
diff --git a/splunk/com/splunk/UdpConnections.java b/splunk/src/main/java/com/splunk/UdpConnections.java
similarity index 100%
rename from splunk/com/splunk/UdpConnections.java
rename to splunk/src/main/java/com/splunk/UdpConnections.java
diff --git a/splunk/com/splunk/UdpInput.java b/splunk/src/main/java/com/splunk/UdpInput.java
similarity index 99%
rename from splunk/com/splunk/UdpInput.java
rename to splunk/src/main/java/com/splunk/UdpInput.java
index a68bf5a8..baa6ff7d 100644
--- a/splunk/com/splunk/UdpInput.java
+++ b/splunk/src/main/java/com/splunk/UdpInput.java
@@ -257,6 +257,7 @@ public void setSourceType(String sourcetype) {
* Send a string to this UDP input.
*
* @param eventBody The text to send.
+ * @throws IOException The IOException instance
*/
public void submit(String eventBody) throws IOException {
DatagramSocket socket = new DatagramSocket();
diff --git a/splunk/com/splunk/Upload.java b/splunk/src/main/java/com/splunk/Upload.java
similarity index 100%
rename from splunk/com/splunk/Upload.java
rename to splunk/src/main/java/com/splunk/Upload.java
diff --git a/splunk/com/splunk/User.java b/splunk/src/main/java/com/splunk/User.java
similarity index 100%
rename from splunk/com/splunk/User.java
rename to splunk/src/main/java/com/splunk/User.java
diff --git a/splunk/com/splunk/UserCollection.java b/splunk/src/main/java/com/splunk/UserCollection.java
similarity index 100%
rename from splunk/com/splunk/UserCollection.java
rename to splunk/src/main/java/com/splunk/UserCollection.java
diff --git a/splunk/com/splunk/Util.java b/splunk/src/main/java/com/splunk/Util.java
similarity index 100%
rename from splunk/com/splunk/Util.java
rename to splunk/src/main/java/com/splunk/Util.java
diff --git a/splunk/com/splunk/Value.java b/splunk/src/main/java/com/splunk/Value.java
similarity index 92%
rename from splunk/com/splunk/Value.java
rename to splunk/src/main/java/com/splunk/Value.java
index 9c7694ce..812bfcad 100644
--- a/splunk/com/splunk/Value.java
+++ b/splunk/src/main/java/com/splunk/Value.java
@@ -80,9 +80,9 @@ else if (value.endsWith("GB"))
* @param value Value to convert.
* @return Date value.
*/
- static Date toDate(String value) {
+ static synchronized Date toDate(String value) {
if (dateFormat == null) {
- dateFormat = new SimpleDateFormat[4];
+ dateFormat = new SimpleDateFormat[6];
dateFormat[0] = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
dateFormat[0].setLenient(true);
dateFormat[1] = new SimpleDateFormat("E MMM d HH:mm:ss z y");
@@ -91,6 +91,10 @@ static Date toDate(String value) {
dateFormat[2].setLenient(true);
dateFormat[3] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
dateFormat[3].setLenient(true);
+ dateFormat[4] = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
+ dateFormat[4].setLenient(true);
+ dateFormat[5] = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+ dateFormat[5].setLenient(true);
}
if (datePattern == null) {
String pattern = "(.*)\\.\\d+([\\-+]\\d+):(\\d+)";
@@ -98,9 +102,6 @@ static Date toDate(String value) {
}
for (SimpleDateFormat simpleDateFormat: dateFormat) {
- // Must first remove the colon (':') from the timezone
- // field, or SimpleDataFormat will not parse correctly.
- // Eg: 2010-01-01T12:00:00+01:00 => 2010-01-01T12:00:00+0100
try {
Matcher matcher = datePattern.matcher(value);
diff --git a/splunk/com/splunk/WindowsActiveDirectoryInput.java b/splunk/src/main/java/com/splunk/WindowsActiveDirectoryInput.java
similarity index 100%
rename from splunk/com/splunk/WindowsActiveDirectoryInput.java
rename to splunk/src/main/java/com/splunk/WindowsActiveDirectoryInput.java
diff --git a/splunk/com/splunk/WindowsEventLogInput.java b/splunk/src/main/java/com/splunk/WindowsEventLogInput.java
similarity index 100%
rename from splunk/com/splunk/WindowsEventLogInput.java
rename to splunk/src/main/java/com/splunk/WindowsEventLogInput.java
diff --git a/splunk/com/splunk/WindowsPerfmonInput.java b/splunk/src/main/java/com/splunk/WindowsPerfmonInput.java
similarity index 100%
rename from splunk/com/splunk/WindowsPerfmonInput.java
rename to splunk/src/main/java/com/splunk/WindowsPerfmonInput.java
diff --git a/splunk/com/splunk/WindowsRegistryInput.java b/splunk/src/main/java/com/splunk/WindowsRegistryInput.java
similarity index 100%
rename from splunk/com/splunk/WindowsRegistryInput.java
rename to splunk/src/main/java/com/splunk/WindowsRegistryInput.java
diff --git a/splunk/com/splunk/WindowsWmiInput.java b/splunk/src/main/java/com/splunk/WindowsWmiInput.java
similarity index 100%
rename from splunk/com/splunk/WindowsWmiInput.java
rename to splunk/src/main/java/com/splunk/WindowsWmiInput.java
diff --git a/splunk/com/splunk/Xml.java b/splunk/src/main/java/com/splunk/Xml.java
similarity index 54%
rename from splunk/com/splunk/Xml.java
rename to splunk/src/main/java/com/splunk/Xml.java
index 961be96f..ef582f72 100644
--- a/splunk/com/splunk/Xml.java
+++ b/splunk/src/main/java/com/splunk/Xml.java
@@ -20,6 +20,9 @@
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
/**
* The {@code Xml} class represents a collection of XML utilities.
@@ -34,16 +37,43 @@ public class Xml {
* @return The XML DOM.
*/
public static Document parse(InputStream input) {
+ return parse(input, false);
+ }
+
+ /**
+ * Parses the given input stream and returns it as an XML document object
+ * model (DOM).
+ *
+ * @param input The {@code InputStream} to parse.
+ * @param silent Suppress logging of parse errors
+ * @return The XML DOM.
+ */
+ public static Document parse(InputStream input, boolean silent) {
try {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ factory.setExpandEntityReferences(false);
+ factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
+ if (silent)
+ builder.setErrorHandler(NO_OP_ERROR_HANDLER);
+
return builder.parse(input);
}
catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
+
+ private static final ErrorHandler NO_OP_ERROR_HANDLER = new ErrorHandler() {
+ @Override public void warning(SAXParseException exception) throws SAXException { }
+
+ @Override public void error(SAXParseException exception) throws SAXException { }
+
+ @Override public void fatalError(SAXParseException exception) throws SAXException { }
+ };
}
diff --git a/splunk/com/splunk/modularinput/Argument.java b/splunk/src/main/java/com/splunk/modularinput/Argument.java
similarity index 100%
rename from splunk/com/splunk/modularinput/Argument.java
rename to splunk/src/main/java/com/splunk/modularinput/Argument.java
diff --git a/splunk/com/splunk/modularinput/Event.java b/splunk/src/main/java/com/splunk/modularinput/Event.java
similarity index 100%
rename from splunk/com/splunk/modularinput/Event.java
rename to splunk/src/main/java/com/splunk/modularinput/Event.java
diff --git a/splunk/com/splunk/modularinput/EventWriter.java b/splunk/src/main/java/com/splunk/modularinput/EventWriter.java
similarity index 96%
rename from splunk/com/splunk/modularinput/EventWriter.java
rename to splunk/src/main/java/com/splunk/modularinput/EventWriter.java
index 8bb6858c..c6ce3425 100755
--- a/splunk/com/splunk/modularinput/EventWriter.java
+++ b/splunk/src/main/java/com/splunk/modularinput/EventWriter.java
@@ -102,6 +102,7 @@ protected void setError() {
* {@code EventWriter} does not throw {@code IOException} errors, but does not ignore them entirely either. Instead it operates
* the same way as {@code PrintStream} in the standard library. You can always check if an {@code IOException} has been thrown
* by calling {@code checkError}.
+ * @return boolean value
*/
public boolean checkError() {
return hadIOException;
@@ -110,6 +111,8 @@ public boolean checkError() {
/**
* Thread safe version of {@code writeEvent}.
* @see #writeEvent
+ * @param event The Event instance
+ * @throws MalformedDataException The MalformedDataException instance
*/
public synchronized void synchronizedWriteEvent(Event event) throws MalformedDataException {
writeEvent(event);
@@ -123,7 +126,7 @@ public synchronized void synchronizedWriteEvent(Event event) throws MalformedDat
*
* @see #synchronizedWriteEvent
* @param event The {@code Event} object to write.
- * @throws MalformedDataException
+ * @throws MalformedDataException The MalformedDataException instance
*/
public void writeEvent(Event event) throws MalformedDataException {
try {
@@ -144,6 +147,8 @@ public void writeEvent(Event event) throws MalformedDataException {
/**
* Thread safe version of {@code log}.
* @see #log
+ * @param severity String value
+ * @param errorMessage String value
*/
public synchronized void synchronizedLog(String severity, String errorMessage) {
log(severity, errorMessage);
diff --git a/splunk/com/splunk/modularinput/InputDefinition.java b/splunk/src/main/java/com/splunk/modularinput/InputDefinition.java
similarity index 93%
rename from splunk/com/splunk/modularinput/InputDefinition.java
rename to splunk/src/main/java/com/splunk/modularinput/InputDefinition.java
index aee87fcb..f7431e78 100755
--- a/splunk/com/splunk/modularinput/InputDefinition.java
+++ b/splunk/src/main/java/com/splunk/modularinput/InputDefinition.java
@@ -16,7 +16,6 @@
package com.splunk.modularinput;
-import com.splunk.modularinput.Parameter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
@@ -69,6 +68,7 @@ public String getField(String fieldName) {
/**
* Sets the name of the server on which this modular input is being run.
+ * @param serverHost String value
*/
public void setServerHost(String serverHost) {
this.metadata.put(serverHostField, serverHost);
@@ -175,16 +175,20 @@ public static InputDefinition parseDefinition(InputStream stream) throws ParserC
IOException, SAXException, MalformedDataException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setIgnoringElementContentWhitespace(true);
+ documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ documentBuilderFactory.setExpandEntityReferences(false);
+ documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(stream);
InputDefinition definition = new InputDefinition();
for (Node node = doc.getDocumentElement().getFirstChild(); node != null; node = node.getNextSibling()) {
- if (node.getNodeType() == node.TEXT_NODE) {
+ if (node.getNodeType() == Node.TEXT_NODE) {
continue;
} else if (node.getNodeName().equals("configuration")) {
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
- if (child.getNodeType() == child.TEXT_NODE) {
+ if (child.getNodeType() == Node.TEXT_NODE) {
continue;
}
if (!child.getNodeName().equals("stanza")) {
diff --git a/splunk/com/splunk/modularinput/MalformedDataException.java b/splunk/src/main/java/com/splunk/modularinput/MalformedDataException.java
similarity index 100%
rename from splunk/com/splunk/modularinput/MalformedDataException.java
rename to splunk/src/main/java/com/splunk/modularinput/MalformedDataException.java
diff --git a/splunk/com/splunk/modularinput/MultiValueParameter.java b/splunk/src/main/java/com/splunk/modularinput/MultiValueParameter.java
similarity index 100%
rename from splunk/com/splunk/modularinput/MultiValueParameter.java
rename to splunk/src/main/java/com/splunk/modularinput/MultiValueParameter.java
diff --git a/splunk/com/splunk/modularinput/NonblockingInputStream.java b/splunk/src/main/java/com/splunk/modularinput/NonblockingInputStream.java
similarity index 100%
rename from splunk/com/splunk/modularinput/NonblockingInputStream.java
rename to splunk/src/main/java/com/splunk/modularinput/NonblockingInputStream.java
diff --git a/splunk/com/splunk/modularinput/Parameter.java b/splunk/src/main/java/com/splunk/modularinput/Parameter.java
similarity index 92%
rename from splunk/com/splunk/modularinput/Parameter.java
rename to splunk/src/main/java/com/splunk/modularinput/Parameter.java
index 05fc21dc..23cb8585 100755
--- a/splunk/com/splunk/modularinput/Parameter.java
+++ b/splunk/src/main/java/com/splunk/modularinput/Parameter.java
@@ -63,21 +63,21 @@ public static List nodeToParameterList(Node node) throws MalformedDat
List parameters = new ArrayList();
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
- if (child.getNodeType() == child.TEXT_NODE) {
+ if (child.getNodeType() == Node.TEXT_NODE) {
continue;
}
- if (child.getNodeName() == "param") {
+ if ("param".equals(child.getNodeName())) {
// This is a single value parameter
String name = child.getAttributes().getNamedItem("name").getNodeValue();
String value = XmlUtil.textInNode(child, "Element param with name=\"" + name +
"\" did not contain text.");
parameters.add(new SingleValueParameter(name, value));
- } else if (child.getNodeName() == "param_list") {
+ } else if ("param_list".equals(child.getNodeName())) {
String name = child.getAttributes().getNamedItem("name").getNodeValue();
MultiValueParameter parameter = new MultiValueParameter(name);
for (Node valueNode = child.getFirstChild(); valueNode != null; valueNode = valueNode.getNextSibling()) {
- if (valueNode.getNodeType() == valueNode.TEXT_NODE) continue;
- if (valueNode.getNodeName() != "value") {
+ if (valueNode.getNodeType() == Node.TEXT_NODE) continue;
+ if (!"value".equals(valueNode.getNodeName())) {
throw new MalformedDataException("Expected a value element in parameter named " +
child.getNodeName() + "; found " + valueNode.getNodeName());
} else {
diff --git a/splunk/com/splunk/modularinput/Scheme.java b/splunk/src/main/java/com/splunk/modularinput/Scheme.java
similarity index 100%
rename from splunk/com/splunk/modularinput/Scheme.java
rename to splunk/src/main/java/com/splunk/modularinput/Scheme.java
diff --git a/splunk/com/splunk/modularinput/Script.java b/splunk/src/main/java/com/splunk/modularinput/Script.java
similarity index 95%
rename from splunk/com/splunk/modularinput/Script.java
rename to splunk/src/main/java/com/splunk/modularinput/Script.java
index 249b61ed..96447c73 100755
--- a/splunk/com/splunk/modularinput/Script.java
+++ b/splunk/src/main/java/com/splunk/modularinput/Script.java
@@ -149,6 +149,7 @@ protected String stackTraceToLogEntry(Exception e) {
* The default implementation always passes.
*
* @param definition The parameters for the proposed input passed by splunkd.
+ * @throws Exception The exception instance
*/
public void validateInput(ValidationDefinition definition) throws Exception {}
@@ -156,7 +157,11 @@ public void validateInput(ValidationDefinition definition) throws Exception {}
* Streams events into Splunk. It should do all of its output via
* {@code EventWriter} rather than assuming that there is a console attached.
*
+ * @param inputs InputDefinition instance
* @param ew An object with methods to write events and log messages to Splunk.
+ * @throws MalformedDataException The MalformedDataException instance
+ * @throws XMLStreamException The XMLStreamException instance
+ * @throws IOException The IOException instance
*/
public abstract void streamEvents(InputDefinition inputs, EventWriter ew)
throws MalformedDataException, XMLStreamException, IOException;
diff --git a/splunk/com/splunk/modularinput/SingleValueParameter.java b/splunk/src/main/java/com/splunk/modularinput/SingleValueParameter.java
similarity index 100%
rename from splunk/com/splunk/modularinput/SingleValueParameter.java
rename to splunk/src/main/java/com/splunk/modularinput/SingleValueParameter.java
diff --git a/splunk/com/splunk/modularinput/ValidationDefinition.java b/splunk/src/main/java/com/splunk/modularinput/ValidationDefinition.java
similarity index 94%
rename from splunk/com/splunk/modularinput/ValidationDefinition.java
rename to splunk/src/main/java/com/splunk/modularinput/ValidationDefinition.java
index eadb3e36..3ce60106 100755
--- a/splunk/com/splunk/modularinput/ValidationDefinition.java
+++ b/splunk/src/main/java/com/splunk/modularinput/ValidationDefinition.java
@@ -194,12 +194,16 @@ public static ValidationDefinition parseDefinition(InputStream stream) throws Pa
IOException, SAXException, MalformedDataException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setIgnoringElementContentWhitespace(true);
+ documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ documentBuilderFactory.setExpandEntityReferences(false);
+ documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(stream);
ValidationDefinition definition = new ValidationDefinition();
for (Node node = doc.getDocumentElement().getFirstChild(); node != null; node = node.getNextSibling()) {
- if (node.getNodeType() == node.TEXT_NODE || node.getNodeType() == node.COMMENT_NODE) {
+ if (node.getNodeType() == Node.TEXT_NODE || node.getNodeType() == Node.COMMENT_NODE) {
continue;
} else if (node.getNodeName().equals("item")) {
String name = node.getAttributes().getNamedItem("name").getNodeValue();
diff --git a/splunk/com/splunk/modularinput/XmlUtil.java b/splunk/src/main/java/com/splunk/modularinput/XmlUtil.java
similarity index 94%
rename from splunk/com/splunk/modularinput/XmlUtil.java
rename to splunk/src/main/java/com/splunk/modularinput/XmlUtil.java
index 349b25a0..3082aa47 100755
--- a/splunk/com/splunk/modularinput/XmlUtil.java
+++ b/splunk/src/main/java/com/splunk/modularinput/XmlUtil.java
@@ -35,10 +35,12 @@ class XmlUtil {
*/
static String textInNode(Node node, String errorMessage) throws MalformedDataException {
Node child = node.getFirstChild();
- if (child.getNodeType() != child.TEXT_NODE) {
+ if (null == child) {
+ return "";
+ } else if (child.getNodeType() != Node.TEXT_NODE) {
throw new MalformedDataException(errorMessage);
} else {
- return ((Text)child).getData();
+ return ((Text) child).getData();
}
}
diff --git a/tests/com/splunk/ApplicationTest.java b/splunk/src/test/java/com/splunk/ApplicationTest.java
similarity index 91%
rename from tests/com/splunk/ApplicationTest.java
rename to splunk/src/test/java/com/splunk/ApplicationTest.java
index cdd60211..df8afe2a 100644
--- a/tests/com/splunk/ApplicationTest.java
+++ b/splunk/src/test/java/com/splunk/ApplicationTest.java
@@ -16,10 +16,7 @@
package com.splunk;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -74,17 +71,9 @@ public boolean predicate() {
@Test
public void testForEmptySetup() {
- // Newly created applications have no setup.
- try {
- application.setup().getSetupXml();
- Assert.fail("Expected HTTP 500.");
- }
- catch (HttpException e) {
- Assert.assertEquals(500, e.getStatus());
- Assert.assertTrue(
- e.getMessage().contains("does not exits") || // 4.3.2
- e.getMessage().contains("does not exist")); // 5.0rc5
- }
+ final String setupXml = application.setup().getSetupXml();
+ // Newly created applications now has a setup stub.
+ Assert.assertTrue(setupXml.contains("stub"));
}
@Test
@@ -96,18 +85,18 @@ public void testForSetupPresent() throws Exception {
installApplicationFromTestData("has_setup_xml");
Assert.assertTrue(service.getApplications().containsKey("has_setup_xml"));
Application applicationWithSetupXml = service.getApplications().get("has_setup_xml");
-
+
ApplicationSetup applicationSetup = applicationWithSetupXml.setup();
Assert.assertEquals("has_setup_xml", applicationSetup.getName());
Assert.assertFalse(applicationSetup.getRefresh());
-
+
String setupXml = applicationSetup.getSetupXml();
Document parsedSetupXml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new ByteArrayInputStream(setupXml.getBytes("UTF-8")));
parsedSetupXml.getDocumentElement().normalize();
-
+
Assert.assertEquals(parsedSetupXml.getDocumentElement().getNodeName(), "SetupInfo");
-
+
NodeList blocks = parsedSetupXml.getDocumentElement().getElementsByTagName("block");
Assert.assertEquals(1, blocks.getLength());
Node block = blocks.item(0);
diff --git a/tests/com/splunk/ArgsTest.java b/splunk/src/test/java/com/splunk/ArgsTest.java
similarity index 100%
rename from tests/com/splunk/ArgsTest.java
rename to splunk/src/test/java/com/splunk/ArgsTest.java
diff --git a/tests/com/splunk/AtomFeedTest.java b/splunk/src/test/java/com/splunk/AtomFeedTest.java
similarity index 96%
rename from tests/com/splunk/AtomFeedTest.java
rename to splunk/src/test/java/com/splunk/AtomFeedTest.java
index 2142d082..e534e21a 100644
--- a/tests/com/splunk/AtomFeedTest.java
+++ b/splunk/src/test/java/com/splunk/AtomFeedTest.java
@@ -38,7 +38,7 @@ public class AtomFeedTest {
private static Map expectedData = reader.fromJson(
SDKTestCase.streamToString(
SDKTestCase.openResource(
- "data/atom_test_data.json")),
+ "/data/atom_test_data.json")),
Map.class);
private Map expectedFeed;
@@ -48,7 +48,7 @@ public class AtomFeedTest {
public AtomFeedTest(String testName) {
this.testName = testName;
this.expectedFeed = (Map)expectedData.get(testName);
- this.xmlStream = SDKTestCase.openResource("data/atom/" + testName + ".xml");
+ this.xmlStream = SDKTestCase.openResource("/data/atom/" + testName + ".xml");
}
@Test
diff --git a/tests/com/splunk/ConfigurationTest.java b/splunk/src/test/java/com/splunk/ConfigurationTest.java
similarity index 100%
rename from tests/com/splunk/ConfigurationTest.java
rename to splunk/src/test/java/com/splunk/ConfigurationTest.java
diff --git a/splunk/src/test/java/com/splunk/CookieTest.java b/splunk/src/test/java/com/splunk/CookieTest.java
new file mode 100644
index 00000000..d11cda76
--- /dev/null
+++ b/splunk/src/test/java/com/splunk/CookieTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2015 Splunk, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"): you may
+ * not use this file except in compliance with the License. You may obtain
+ * a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.splunk;
+
+import java.net.HttpCookie;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.*;
+
+public class CookieTest extends SDKTestCase {
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // Cookies were not around before version 6.2
+ Assume.assumeTrue(service.versionIsAtLeast("6.2"));
+ }
+
+ @Test
+ public void testGotCookieOnLogin() {
+ Map args = getStandardArgs();
+ args.put("scheme", (String) command.opts.get("scheme"));
+ args.put("username", (String) command.opts.get("username"));
+ args.put("password", (String) command.opts.get("password"));
+ Service s = new Service(args);
+
+ s.login();
+
+ Assert.assertNotEquals(s.stringifyCookies().length(), 0);
+ }
+
+ @Test
+ public void testLoginWithCookie() {
+ String validCookie = service.stringifyCookies();
+
+ Map args = getStandardArgs();
+ args.put("cookie", validCookie);
+
+ Service s = new Service(args);
+
+ // Ensure we can perform some action.
+ // In particular we don't expect an unauthenticated error.
+ s.getSettings().refresh();
+
+ // Make sure we're still using the same token.
+ // In particular we don't want to trigger auto-login functionality
+ // that may get a new cookie.
+ Assert.assertEquals(s.stringifyCookies(), validCookie);
+ }
+
+ @Test
+ public void testLoginWithCookieFromAnotherService() {
+ String validCookie = service.stringifyCookies();
+
+ Map args = getStandardArgs();
+ args.put("cookie", validCookie);
+
+ Service s = new Service(args);
+
+ // Ensure we can perform some action.
+ // In particular we don't expect an unauthenticated error.
+ s.getSettings().refresh();
+
+ // Make sure we're still using the same token.
+ // In particular we don't want to trigger auto-login functionality
+ // that may get a new cookie.
+ Assert.assertEquals(s.stringifyCookies(), validCookie);
+
+ // Now we should be able to login with only a cookie
+ args.remove("username");
+ args.remove("password");
+ Service s2 = new Service(args);
+
+ s2.getApplications();
+ }
+
+ @Test(expected=HttpException.class)
+ public void testLoginFailsWithBadCookie() {
+ Map args = getStandardArgs();
+ args.put("cookie", "bad=cookie");
+
+ Service s = new Service(args);
+
+ s.getSettings().refresh();
+ }
+
+ @Test(expected=HttpException.class)
+ public void testAuthenticationFailsWithNoCookieOrLogin() {
+ Service s = new Service(service.getHost(), service.getPort());
+
+ s.getSettings().refresh();
+ }
+
+ @Test
+ public void testLoginWithMultipleCookies() {
+ String validCookie = service.stringifyCookies();
+
+ Map args = getStandardArgs();
+ args.put("cookie", validCookie);
+
+ Service s = new Service(args);
+
+ s.addCookie("bad=cookie");
+
+ 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();
+
+ Map args = getStandardArgs();
+
+ Service s = new Service(args);
+
+ s.addCookie("bad=cookie");
+ s.addCookie(validCookie);
+ s.addCookie("another_bad=cookie");
+
+ s.getSettings().refresh();
+ }
+
+ @Test
+ public void testLoginWithMultipleCookiesReversed() {
+ String validCookie = service.stringifyCookies();
+
+ Map args = getStandardArgs();
+ args.put("cookie", "bad=cookie");
+ Service s = new Service(args);
+
+ s.addCookie(validCookie);
+
+ s.getSettings().refresh();
+ }
+
+ @Test
+ public void testHttpServiceWithValidCookie() {
+ String validCookie = service.stringifyCookies();
+
+ HttpService httpService;
+
+ httpService = new HttpService(
+ (String)command.opts.get("host"),
+ (Integer)command.opts.get("port"),
+ (String)command.opts.get("scheme")
+ );
+
+ httpService.addCookie(validCookie);
+
+ httpService.get("/services/authentication/users");
+
+ Assert.assertEquals(validCookie, httpService.stringifyCookies());
+ }
+
+ @Test(expected=HttpException.class)
+ public void testHttpServiceWithInvalidCookie() {
+ HttpService httpService;
+
+ httpService = new HttpService(
+ (String)command.opts.get("host"),
+ (Integer)command.opts.get("port"),
+ (String)command.opts.get("scheme")
+ );
+
+ httpService.addCookie("bad=cookie");
+
+ httpService.get("/services/authentication/users");
+ }
+
+ @Test(expected=HttpException.class)
+ public void testHttpServiceWithNoCookie() {
+ HttpService httpService;
+
+ httpService = new HttpService(
+ (String)command.opts.get("host"),
+ (Integer)command.opts.get("port"),
+ (String)command.opts.get("scheme")
+ );
+
+ httpService.get("/services/authentication/users");
+ }
+
+ private Map getStandardArgs() {
+ Map args = new HashMap();
+ args.put("host", (String)command.opts.get("host"));
+ args.put("port", (Integer) command.opts.get("port"));
+
+ return args;
+ }
+
+}
diff --git a/tests/com/splunk/DataModelTest.java b/splunk/src/test/java/com/splunk/DataModelTest.java
similarity index 91%
rename from tests/com/splunk/DataModelTest.java
rename to splunk/src/test/java/com/splunk/DataModelTest.java
index ae2e5465..2a8585e8 100644
--- a/tests/com/splunk/DataModelTest.java
+++ b/splunk/src/test/java/com/splunk/DataModelTest.java
@@ -39,7 +39,7 @@ public void testDataModelCollectionCreateAndDelete() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/empty_data_model.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/empty_data_model.json")));
int initialN = dataModels.size();
@@ -65,7 +65,7 @@ public void testDataModelWithZeroObjects() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/empty_data_model.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/empty_data_model.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
Assert.assertEquals(0, model.getObjects().size());
@@ -80,7 +80,7 @@ public void testDataModelWithOneObject() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/object_with_one_search.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/object_with_one_search.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
Assert.assertEquals(1, model.getObjects().size());
@@ -95,7 +95,7 @@ public void testDataModelWithTwoObjects() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/object_with_two_searches.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/object_with_two_searches.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
Assert.assertEquals(2, model.getObjects().size());
@@ -110,7 +110,7 @@ public void testGetAndContainsObjectWork() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/object_with_two_searches.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/object_with_two_searches.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
Assert.assertTrue(model.containsObject("search1"));
@@ -132,7 +132,7 @@ public void testDataModelWithUnicodeAttributes() {
String modelName = createTemporaryName();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/model_with_unicode_headers.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/model_with_unicode_headers.json")));
DataModel model = dataModels.create(modelName, args);
Assert.assertEquals(modelName, model.getName());
@@ -147,7 +147,7 @@ public void testDataModelWithEmptyAttributes() {
String modelName = createTemporaryName();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/model_with_empty_headers.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/model_with_empty_headers.json")));
DataModel model = dataModels.create(modelName, args);
Assert.assertEquals(modelName, model.getName());
@@ -170,33 +170,49 @@ public void testAccelerationSettings() {
EntityCollection dataModels = nonprivateService.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/data_model_with_test_objects.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/data_model_with_test_objects.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
+ final String crontabA = "*/5 * * * *";
+ final String crontabB = "* * * * *";
+
model.setAcceleration(true);
model.setEarliestAcceleratedTime("-2mon");
- model.setAccelerationCronSchedule("5/* * * * *");
+ model.setAccelerationCronSchedule(crontabA);
model.update();
Assert.assertTrue(model.isAccelerated());
Assert.assertEquals("-2mon", model.getEarliestAcceleratedTime());
- Assert.assertEquals("5/* * * * *", model.getAccelerationCronSchedule());
+ Assert.assertEquals(crontabA, model.getAccelerationCronSchedule());
+ Assert.assertFalse(model.isManualRebuilds());
model.update(); // An empty update should also work
model.refresh();
Assert.assertTrue(model.isAccelerated());
Assert.assertEquals("-2mon", model.getEarliestAcceleratedTime());
- Assert.assertEquals("5/* * * * *", model.getAccelerationCronSchedule());
+ Assert.assertEquals(crontabA, model.getAccelerationCronSchedule());
+ Assert.assertFalse(model.isManualRebuilds());
model.setAcceleration(false);
model.setEarliestAcceleratedTime("-1mon");
- model.setAccelerationCronSchedule("* * * * *");
+ model.setAccelerationCronSchedule(crontabB);
+ model.update();
+
+ Assert.assertFalse(model.isAccelerated());
+ Assert.assertEquals("-1mon", model.getEarliestAcceleratedTime());
+ Assert.assertEquals(crontabB, model.getAccelerationCronSchedule());
+ Assert.assertFalse(model.isManualRebuilds());
+
+ model.setManualRebuilds(true);
+ // Acceleration must be set, or splunkd will crash
+ model.setAcceleration(false);
model.update();
Assert.assertFalse(model.isAccelerated());
Assert.assertEquals("-1mon", model.getEarliestAcceleratedTime());
- Assert.assertEquals("* * * * *", model.getAccelerationCronSchedule());
+ Assert.assertEquals(crontabB, model.getAccelerationCronSchedule());
+ Assert.assertTrue(model.isManualRebuilds());
}
@Test
@@ -204,7 +220,7 @@ public void testObjectMetadata() {
DataModelCollection models = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/data_model_with_test_objects.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/data_model_with_test_objects.json")));
DataModel model = models.create(createTemporaryName(), args);
DataModelObject object = model.getObject("event1");
@@ -220,7 +236,7 @@ public void testParentOnChild() {
DataModelCollection models = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/data_model_with_test_objects.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/data_model_with_test_objects.json")));
DataModel model = models.create(createTemporaryName(), args);
DataModelObject object = model.getObject("event1");
@@ -234,7 +250,7 @@ public void testLineage() {
DataModelCollection models = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/inheritance_test_data.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/inheritance_test_data.json")));
DataModel model = models.create(createTemporaryName(), args);
Collection children;
@@ -260,7 +276,7 @@ public void testObjectFields() {
DataModelCollection models = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/inheritance_test_data.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/inheritance_test_data.json")));
DataModel model = models.create(createTemporaryName(), args);
DataModelObject object = model.getObject("level_2");
@@ -297,7 +313,7 @@ public void testOutputObjectFields() {
DataModelCollection models = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/data_model_for_pivot.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/data_model_for_pivot.json")));
DataModel model = models.create(createTemporaryName(), args);
DataModelObject object = model.getObject("test_data");
@@ -314,7 +330,7 @@ public void testCreateLocalAccelerationJob() {
String dataModelName = createTemporaryName();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/inheritance_test_data.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/inheritance_test_data.json")));
DataModel model = models.create(dataModelName, args);
DataModelObject object = model.getObject("level_2");
@@ -345,7 +361,7 @@ public void testCreateLocalAccelerationJobWithEarliestTime() {
String dataModelName = createTemporaryName();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/inheritance_test_data.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/inheritance_test_data.json")));
DataModel model = models.create(dataModelName, args);
DataModelObject object = model.getObject("level_2");
@@ -376,7 +392,7 @@ public void testConstraints() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/data_model_with_test_objects.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/data_model_with_test_objects.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
DataModelObject object = model.getObject("event1");
@@ -398,7 +414,7 @@ public void testCalculations() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/data_model_with_test_objects.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/data_model_with_test_objects.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
DataModelObject object = model.getObject("event1");
@@ -494,7 +510,7 @@ public void testBaseSearchProperlyParsed() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/model_with_multiple_types.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/model_with_multiple_types.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
DataModelObject object = model.getObject("search1");
@@ -511,7 +527,7 @@ public void testBaseTransactionProperlyParsed() {
EntityCollection dataModels = service.getDataModels();
DataModelArgs args = new DataModelArgs();
- args.setRawJsonDescription(streamToString(openResource("data/datamodels/model_with_multiple_types.json")));
+ args.setRawJsonDescription(streamToString(openResource("/data/datamodels/model_with_multiple_types.json")));
DataModel model = dataModels.create(createTemporaryName(), args);
DataModelObject object = model.getObject("transaction1");
diff --git a/tests/com/splunk/DeploymentClientTest.java b/splunk/src/test/java/com/splunk/DeploymentClientTest.java
similarity index 100%
rename from tests/com/splunk/DeploymentClientTest.java
rename to splunk/src/test/java/com/splunk/DeploymentClientTest.java
diff --git a/tests/com/splunk/DeploymentServerClassTest.java b/splunk/src/test/java/com/splunk/DeploymentServerClassTest.java
similarity index 99%
rename from tests/com/splunk/DeploymentServerClassTest.java
rename to splunk/src/test/java/com/splunk/DeploymentServerClassTest.java
index 13c5532f..94dc00e8 100644
--- a/tests/com/splunk/DeploymentServerClassTest.java
+++ b/splunk/src/test/java/com/splunk/DeploymentServerClassTest.java
@@ -17,7 +17,6 @@
package com.splunk;
import org.junit.Assert;
-import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
diff --git a/tests/com/splunk/DeploymentServerTest.java b/splunk/src/test/java/com/splunk/DeploymentServerTest.java
similarity index 98%
rename from tests/com/splunk/DeploymentServerTest.java
rename to splunk/src/test/java/com/splunk/DeploymentServerTest.java
index 15c5f51b..ba75489f 100644
--- a/tests/com/splunk/DeploymentServerTest.java
+++ b/splunk/src/test/java/com/splunk/DeploymentServerTest.java
@@ -17,7 +17,6 @@
package com.splunk;
import org.junit.Assert;
-import org.junit.Assume;
import org.junit.Test;
public class DeploymentServerTest extends SDKTestCase {
diff --git a/tests/com/splunk/DeploymentTenantTest.java b/splunk/src/test/java/com/splunk/DeploymentTenantTest.java
similarity index 98%
rename from tests/com/splunk/DeploymentTenantTest.java
rename to splunk/src/test/java/com/splunk/DeploymentTenantTest.java
index 95129079..153b1064 100644
--- a/tests/com/splunk/DeploymentTenantTest.java
+++ b/splunk/src/test/java/com/splunk/DeploymentTenantTest.java
@@ -17,7 +17,6 @@
package com.splunk;
import org.junit.Assert;
-import org.junit.Assume;
import org.junit.Test;
public class DeploymentTenantTest extends SDKTestCase {
diff --git a/tests/com/splunk/DistributedConfTest.java b/splunk/src/test/java/com/splunk/DistributedConfTest.java
similarity index 100%
rename from tests/com/splunk/DistributedConfTest.java
rename to splunk/src/test/java/com/splunk/DistributedConfTest.java
diff --git a/tests/com/splunk/DistributedPeerTest.java b/splunk/src/test/java/com/splunk/DistributedPeerTest.java
similarity index 96%
rename from tests/com/splunk/DistributedPeerTest.java
rename to splunk/src/test/java/com/splunk/DistributedPeerTest.java
index 8bdb75dc..1b627f89 100644
--- a/tests/com/splunk/DistributedPeerTest.java
+++ b/splunk/src/test/java/com/splunk/DistributedPeerTest.java
@@ -16,11 +16,13 @@
package com.splunk;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
+@Ignore
+/**
+ * To execute these test we need a separate splunk instance. Post splunk6.4, it is no longer allowed to connect to
+ * self as a peer because of name conflicts.
+ */
public class DistributedPeerTest extends SDKTestCase {
EntityCollection peers;
String temporaryUsername;
diff --git a/tests/com/splunk/EntityTest.java b/splunk/src/test/java/com/splunk/EntityTest.java
similarity index 100%
rename from tests/com/splunk/EntityTest.java
rename to splunk/src/test/java/com/splunk/EntityTest.java
diff --git a/tests/com/splunk/EventTypesTest.java b/splunk/src/test/java/com/splunk/EventTypesTest.java
similarity index 100%
rename from tests/com/splunk/EventTypesTest.java
rename to splunk/src/test/java/com/splunk/EventTypesTest.java
diff --git a/tests/com/splunk/ExportResultsReaderTest.java b/splunk/src/test/java/com/splunk/ExportResultsReaderTest.java
similarity index 91%
rename from tests/com/splunk/ExportResultsReaderTest.java
rename to splunk/src/test/java/com/splunk/ExportResultsReaderTest.java
index 293483ef..0c460372 100644
--- a/tests/com/splunk/ExportResultsReaderTest.java
+++ b/splunk/src/test/java/com/splunk/ExportResultsReaderTest.java
@@ -40,7 +40,7 @@ public class ExportResultsReaderTest {
private static Map expectedData = reader.fromJson(
SDKTestCase.streamToString(
SDKTestCase.openResource(
- "data/export_test_data.json")),
+ "/data/export_test_data.json")),
Map.class
);
@@ -70,7 +70,7 @@ public void testExportWithoutPreview() throws IOException, XMLStreamException {
InputStream xmlStream = new ExportResultsStream(
SDKTestCase.openResource(
- "data/export/" + this.version + "/export_results.xml"));
+ "/data/export/" + this.version + "/export_results.xml"));
ResultsReaderXml resultsReader = new ResultsReaderXml(xmlStream);
ResultsReaderTestFromExpectedFile.verifyResultsReader(resultsReader, expectedEvents);
@@ -85,7 +85,7 @@ public void testExportWithPreview() throws IOException {
List