Repository: nifi Updated Branches: refs/heads/master b710420f0 -> 970ddf8f7
NIFI-3794 - Expose the control of ListenRELP's CLIENT_AUTH property to DFM This closes #1746. Signed-off-by: Bryan Bende <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/970ddf8f Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/970ddf8f Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/970ddf8f Branch: refs/heads/master Commit: 970ddf8f7e471f02835b3b2e3cf46cfabcc801e0 Parents: b710420 Author: Andre F de Miranda <[email protected]> Authored: Thu May 4 08:00:14 2017 +1000 Committer: Bryan Bende <[email protected]> Committed: Thu May 4 10:50:22 2017 -0400 ---------------------------------------------------------------------- .../nifi/processors/standard/ListenRELP.java | 42 ++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/970ddf8f/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenRELP.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenRELP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenRELP.java index 51173ec..7400862 100644 --- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenRELP.java +++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenRELP.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.processors.standard; +import org.apache.commons.lang3.StringUtils; import org.apache.nifi.annotation.behavior.InputRequirement; import org.apache.nifi.annotation.behavior.WritesAttribute; import org.apache.nifi.annotation.behavior.WritesAttributes; @@ -24,6 +25,8 @@ import org.apache.nifi.annotation.documentation.SeeAlso; import org.apache.nifi.annotation.documentation.Tags; import org.apache.nifi.annotation.lifecycle.OnScheduled; import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.components.ValidationContext; +import org.apache.nifi.components.ValidationResult; import org.apache.nifi.flowfile.attributes.CoreAttributes; import org.apache.nifi.flowfile.attributes.FlowFileAttributeKey; import org.apache.nifi.processor.DataUnit; @@ -43,13 +46,16 @@ import org.apache.nifi.processors.standard.relp.frame.RELPEncoder; import org.apache.nifi.processors.standard.relp.handler.RELPSocketChannelHandlerFactory; import org.apache.nifi.processors.standard.relp.response.RELPChannelResponse; import org.apache.nifi.processors.standard.relp.response.RELPResponse; +import org.apache.nifi.security.util.SslContextFactory; import org.apache.nifi.ssl.SSLContextService; import javax.net.ssl.SSLContext; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -73,17 +79,26 @@ public class ListenRELP extends AbstractListenEventBatchingProcessor<RELPEvent> public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder() .name("SSL Context Service") + .displayName("SSL Context Service") .description("The Controller Service to use in order to obtain an SSL Context. If this property is set, " + "messages will be received over a secure connection.") .required(false) .identifiesControllerService(SSLContextService.class) .build(); + public static final PropertyDescriptor CLIENT_AUTH = new PropertyDescriptor.Builder() + .name("Client Auth") + .displayName("Client Auth") + .description("The client authentication policy to use for the SSL Context. Only used if an SSL Context Service is provided.") + .required(false) + .allowableValues(SSLContextService.ClientAuth.values()) + .defaultValue(SSLContextService.ClientAuth.REQUIRED.name()) + .build(); private volatile RELPEncoder relpEncoder; @Override protected List<PropertyDescriptor> getAdditionalProperties() { - return Arrays.asList(MAX_CONNECTIONS, SSL_CONTEXT_SERVICE); + return Arrays.asList(MAX_CONNECTIONS, SSL_CONTEXT_SERVICE, CLIENT_AUTH); } @Override @@ -95,6 +110,22 @@ public class ListenRELP extends AbstractListenEventBatchingProcessor<RELPEvent> } @Override + protected Collection<ValidationResult> customValidate(final ValidationContext validationContext) { + final List<ValidationResult> results = new ArrayList<>(); + final SSLContextService sslContextService = validationContext.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class); + + // Validate CLIENT_AUTH + final String clientAuth = validationContext.getProperty(CLIENT_AUTH).getValue(); + if (sslContextService != null && StringUtils.isBlank(clientAuth)) { + results.add(new ValidationResult.Builder() + .explanation("Client Auth must be provided when using TLS/SSL") + .valid(false).subject("Client Auth").build()); + } + + return results; + } + + @Override protected ChannelDispatcher createDispatcher(final ProcessContext context, final BlockingQueue<RELPEvent> events) throws IOException { final EventFactory<RELPEvent> eventFactory = new RELPEventFactory(); final ChannelHandlerFactory<RELPEvent,AsyncChannelDispatcher> handlerFactory = new RELPSocketChannelHandlerFactory<>(); @@ -108,14 +139,19 @@ public class ListenRELP extends AbstractListenEventBatchingProcessor<RELPEvent> // if an SSLContextService was provided then create an SSLContext to pass down to the dispatcher SSLContext sslContext = null; + SslContextFactory.ClientAuth clientAuth = null; + final SSLContextService sslContextService = context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class); if (sslContextService != null) { - sslContext = sslContextService.createSSLContext(SSLContextService.ClientAuth.REQUIRED); + final String clientAuthValue = context.getProperty(CLIENT_AUTH).getValue(); + sslContext = sslContextService.createSSLContext(SSLContextService.ClientAuth.valueOf(clientAuthValue)); + clientAuth = SslContextFactory.ClientAuth.valueOf(clientAuthValue); + } // if we decide to support SSL then get the context and pass it in here return new SocketChannelDispatcher<>(eventFactory, handlerFactory, bufferPool, events, - getLogger(), maxConnections, sslContext, charSet); + getLogger(), maxConnections, sslContext, clientAuth, charSet); } @Override
