DRILL-8370: Upgrade splunk-sdk-java to 1.9.3 (#2719)
* Upgrade splunk-sdk-java to 1.9.3.
* Fix default value of validateCertificates in SplunkConnection.
* Patch Splunk's broken validateCertificates toggle.
* Adjust unit test queries to work with populated indexes.
diff --git a/contrib/storage-splunk/pom.xml b/contrib/storage-splunk/pom.xml
index 140bcb3..81abc6e 100644
--- a/contrib/storage-splunk/pom.xml
+++ b/contrib/storage-splunk/pom.xml
@@ -42,7 +42,7 @@
<dependency>
<groupId>com.splunk</groupId>
<artifactId>splunk</artifactId>
- <version>1.9.1</version>
+ <version>1.9.3</version>
<exclusions>
<exclusion>
<groupId>org.apache.maven.plugins</groupId>
diff --git a/contrib/storage-splunk/src/main/java/org/apache/drill/exec/store/splunk/SplunkConnection.java b/contrib/storage-splunk/src/main/java/org/apache/drill/exec/store/splunk/SplunkConnection.java
index f3a1e45..c9571c6 100644
--- a/contrib/storage-splunk/src/main/java/org/apache/drill/exec/store/splunk/SplunkConnection.java
+++ b/contrib/storage-splunk/src/main/java/org/apache/drill/exec/store/splunk/SplunkConnection.java
@@ -31,6 +31,15 @@
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
import java.util.Optional;
/**
@@ -71,7 +80,7 @@
this.owner = config.getOwner();
this.token = config.getToken();
this.cookie = config.getCookie();
- this.validateCertificates = Optional.ofNullable(config.getValidateCertificates()).orElse(false);
+ this.validateCertificates = Optional.ofNullable(config.getValidateCertificates()).orElse(true);
this.connectionAttempts = config.getReconnectRetries();
service = connect();
}
@@ -100,9 +109,19 @@
* Connects to Splunk instance
* @return an active Splunk connection.
*/
+
public Service connect() {
HttpService.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);
HttpService.setValidateCertificates(validateCertificates);
+ if (! validateCertificates) {
+ try {
+ HttpService.setSSLSocketFactory(createAllTrustingSSLFactory());
+ } catch (KeyManagementException e) {
+ throw UserException.connectionError(e)
+ .message("Error validating SSL Certificates: " + e.getMessage())
+ .build(logger);
+ }
+ }
ServiceArgs loginArgs = new ServiceArgs();
if (scheme != null) {
@@ -139,6 +158,7 @@
throw UserException
.connectionError(e)
.message("Unable to connect to Splunk at %s:%s", hostname, port)
+ .addContext(e.getMessage())
.build(logger);
}
logger.info("Successfully connected to {} on port {}", hostname, port);
@@ -152,4 +172,45 @@
public EntityCollection<Index> getIndexes() {
return service.getIndexes();
}
+
+ /**
+ * As of version 1.8, Splunk's SDK introduced a boolean parameter which
+ * is supposed to control whether the SDK will validate SSL certificates
+ * or not. Unfortunately the parameter does not actually seem to have
+ * any effect and the end result is that when making Splunk calls,
+ * Splunk will always attempt to verify the SSL certificates, even when
+ * the parameter is set to false. This method does what the parameter
+ * is supposed to do in the SDK and adds and all trusting SSL Socket
+ * Factory to the HTTP client in Splunk's SDK. In the event Splunk
+ * fixes this issue, we can remove this method.
+ *
+ * @return A {@link SSLSocketFactory} which trusts any SSL certificate,
+ * even ones from Splunk
+ * @throws KeyManagementException Thros
+ */
+ private SSLSocketFactory createAllTrustingSSLFactory() throws KeyManagementException {
+ SSLContext context;
+ try {
+ context = SSLContext.getInstance("TLS");
+ } catch (NoSuchAlgorithmException e) {
+ throw UserException.validationError(e)
+ .message("Error establishing SSL connection: Invalid scheme: " + e.getMessage())
+ .build(logger);
+ }
+ TrustManager[] trustAll = new TrustManager[]{
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(X509Certificate[] certs, String authType) {
+ // No op
+ }
+ public void checkServerTrusted(X509Certificate[] certs, String authType) {
+ // No op
+ }
+ }
+ };
+ context.init(null, trustAll, null);
+ return context.getSocketFactory();
+ }
}
diff --git a/contrib/storage-splunk/src/test/java/org/apache/drill/exec/store/splunk/SplunkPluginTest.java b/contrib/storage-splunk/src/test/java/org/apache/drill/exec/store/splunk/SplunkPluginTest.java
index ecc00c7..2109de2 100644
--- a/contrib/storage-splunk/src/test/java/org/apache/drill/exec/store/splunk/SplunkPluginTest.java
+++ b/contrib/storage-splunk/src/test/java/org/apache/drill/exec/store/splunk/SplunkPluginTest.java
@@ -152,23 +152,23 @@
@Test
public void testExplictFieldsQuery() throws Exception {
- String sql = "SELECT acceleration_id, action, add_offset, add_timestamp FROM splunk._audit LIMIT 2";
+ String sql = "SELECT component, event_message, host, _time FROM splunk._introspection LIMIT 3";
client.testBuilder()
.sqlQuery(sql)
.unOrdered()
- .baselineColumns("acceleration_id", "action", "add_offset", "add_timestamp")
- .expectsNumRecords(2)
+ .baselineColumns("component", "event_message", "host", "_time")
+ .expectsNumRecords(3)
.go();
}
@Test
public void testExplicitFieldsWithLimitQuery() throws Exception {
- String sql = "SELECT action, _sourcetype, _subsecond, _time FROM splunk._audit LIMIT 3";
+ String sql = "SELECT `group`, _sourcetype, _subsecond, _time FROM splunk._introspection LIMIT 3";
client.testBuilder()
.sqlQuery(sql)
.unOrdered()
- .baselineColumns( "acceleration_id", "action", "add_offset", "add_timestamp")
+ .baselineColumns( "group", "_sourcetype", "_subsecond", "_time")
.expectsNumRecords(3)
.go();
}
@@ -176,18 +176,18 @@
@Test
@Ignore("the result is not consistent on system tables")
public void testExplicitFieldsWithSourceType() throws Exception {
- String sql = "SELECT action, _sourcetype, _subsecond, _time FROM splunk._audit WHERE sourcetype='audittrail' LIMIT 5";
+ String sql = "SELECT `group`, _sourcetype, _subsecond, _time FROM splunk._introspection WHERE sourcetype='splunkd' LIMIT 3";
client.testBuilder()
.sqlQuery(sql)
.unOrdered()
- .baselineColumns( "acceleration_id", "action", "add_offset", "add_timestamp")
- .expectsNumRecords(5)
+ .baselineColumns( "group", "_sourcetype", "_subsecond", "_time")
+ .expectsNumRecords(3)
.go();
}
@Test
public void testExplicitFieldsWithOneFieldLimitQuery() throws Exception {
- String sql = "SELECT `component` FROM splunk.`_introspection` ORDER BY `component` LIMIT 2";
+ String sql = "SELECT distinct `component` FROM splunk.`_introspection` ORDER BY `component` LIMIT 2";
RowSet results = client.queryBuilder().sql(sql).rowSet();
TupleMetadata expectedSchema = new SchemaBuilder()
@@ -233,12 +233,12 @@
@Test
public void testFilterOnUnProjectedColumnQuery() throws Exception {
- String sql = "SELECT action, _sourcetype, _subsecond, _time FROM splunk._audit WHERE sourcetype='audittrail' LIMIT 5";
+ String sql = "SELECT `group`, _sourcetype, _subsecond, _time FROM splunk._introspection WHERE sourcetype='splunk_disk_objects' LIMIT 3";
client.testBuilder()
.sqlQuery(sql)
.unOrdered()
- .baselineColumns( "acceleration_id", "action", "add_offset", "add_timestamp")
- .expectsNumRecords(5)
+ .baselineColumns( "group", "_sourcetype", "_subsecond", "_time")
+ .expectsNumRecords(3)
.go();
}