You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ex...@apache.org on 2023/10/09 20:59:44 UTC
[nifi] 02/02: NIFI-11940 Added SSLContextService to GetSplunk
This is an automated email from the ASF dual-hosted git repository.
exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
commit 87b8f230d253b539b2ce85ee9ed32b4626095f84
Author: Nandor Soma Abonyi <ns...@apache.org>
AuthorDate: Tue Sep 5 01:00:30 2023 +0200
NIFI-11940 Added SSLContextService to GetSplunk
- Included ClassLoader isolation to work around Splunk Service static configuration limitations
This closes #7668
Signed-off-by: David Handermann <ex...@apache.org>
---
.../apache/nifi/processors/splunk/GetSplunk.java | 35 ++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/src/main/java/org/apache/nifi/processors/splunk/GetSplunk.java b/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/src/main/java/org/apache/nifi/processors/splunk/GetSplunk.java
index b575bf6ca4..0cbcf325e6 100644
--- a/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/src/main/java/org/apache/nifi/processors/splunk/GetSplunk.java
+++ b/nifi-nar-bundles/nifi-splunk-bundle/nifi-splunk-processors/src/main/java/org/apache/nifi/processors/splunk/GetSplunk.java
@@ -24,6 +24,7 @@ import com.splunk.ServiceArgs;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.annotation.behavior.InputRequirement;
+import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
import org.apache.nifi.annotation.behavior.Stateful;
import org.apache.nifi.annotation.behavior.TriggerSerially;
import org.apache.nifi.annotation.behavior.WritesAttribute;
@@ -35,11 +36,13 @@ import org.apache.nifi.annotation.lifecycle.OnRemoved;
import org.apache.nifi.annotation.lifecycle.OnScheduled;
import org.apache.nifi.annotation.lifecycle.OnStopped;
import org.apache.nifi.components.AllowableValue;
+import org.apache.nifi.components.ClassloaderIsolationKeyProvider;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.ValidationContext;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.components.state.Scope;
import org.apache.nifi.components.state.StateMap;
+import org.apache.nifi.context.PropertyContext;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.AbstractProcessor;
import org.apache.nifi.processor.ProcessContext;
@@ -49,6 +52,8 @@ import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.io.OutputStreamCallback;
import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.scheduling.SchedulingStrategy;
+import org.apache.nifi.ssl.SSLContextService;
import java.io.BufferedOutputStream;
import java.io.IOException;
@@ -68,7 +73,6 @@ import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.nifi.scheduling.SchedulingStrategy;
@TriggerSerially
@InputRequirement(InputRequirement.Requirement.INPUT_FORBIDDEN)
@@ -79,11 +83,12 @@ import org.apache.nifi.scheduling.SchedulingStrategy;
@WritesAttribute(attribute="splunk.earliest.time", description = "The value of the earliest time that was used when performing the query."),
@WritesAttribute(attribute="splunk.latest.time", description = "The value of the latest time that was used when performing the query.")
})
+@RequiresInstanceClassLoading(cloneAncestorResources = true)
@Stateful(scopes = Scope.CLUSTER, description = "If using one of the managed Time Range Strategies, this processor will " +
"store the values of the latest and earliest times from the previous execution so that the next execution of the " +
"can pick up where the last execution left off. The state will be cleared and start over if the query is changed.")
@DefaultSchedule(strategy = SchedulingStrategy.TIMER_DRIVEN, period = "1 min")
-public class GetSplunk extends AbstractProcessor {
+public class GetSplunk extends AbstractProcessor implements ClassloaderIsolationKeyProvider {
public static final String HTTP_SCHEME = "http";
public static final String HTTPS_SCHEME = "https";
@@ -247,6 +252,13 @@ public class GetSplunk extends AbstractProcessor {
.defaultValue(TLS_1_2_VALUE.getValue())
.build();
+ public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
+ .name("SSL Context Service")
+ .description("The SSL Context Service used to provide client certificate information for TLS/SSL connections.")
+ .required(false)
+ .identifiesControllerService(SSLContextService.class)
+ .build();
+
public static final Relationship REL_SUCCESS = new Relationship.Builder()
.name("success")
.description("Results retrieved from Splunk are sent out this relationship.")
@@ -289,6 +301,7 @@ public class GetSplunk extends AbstractProcessor {
descriptors.add(PASSWORD);
descriptors.add(SECURITY_PROTOCOL);
descriptors.add(OUTPUT_MODE);
+ descriptors.add(SSL_CONTEXT_SERVICE);
this.descriptors = Collections.unmodifiableList(descriptors);
final Set<Relationship> relationships = new HashSet<>();
@@ -572,6 +585,11 @@ public class GetSplunk extends AbstractProcessor {
serviceArgs.setSSLSecurityProtocol(SSLSecurityProtocol.valueOf(secProtocol));
}
+ final SSLContextService sslContextService = context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class);
+ if (sslContextService != null) {
+ Service.setSSLSocketFactory(sslContextService.createContext().getSocketFactory());
+ }
+
return Service.connect(serviceArgs);
}
@@ -606,6 +624,19 @@ public class GetSplunk extends AbstractProcessor {
}
}
+ @Override
+ public String getClassloaderIsolationKey(PropertyContext context) {
+ final SSLContextService sslContextService = context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class);
+ if (sslContextService != null) {
+ // Class loader isolation is only necessary when SSL is enabled, as Service.setSSLSocketFactory
+ // changes the Socket Factory for all instances.
+ return sslContextService.getIdentifier();
+ } else {
+ // This workaround ensures that instances don't unnecessarily use an isolated classloader.
+ return getClass().getName();
+ }
+ }
+
static class TimeRange {
final String earliestTime;