mirror of https://github.com/apache/nifi.git
NIFI-8178 This closes #4787. Replaced StandardSSLContextService in unit tests with SslContextUtils
- Removed references to StandardSSLContextService from nifi-standard-processors - Removed TestGetHTTPGroovy and TestPostHTTPGroovy since these are testing deprecated processors - Optimized HandleHttpRequest, GetHTTP, PostHTTP to use SSLContextService.createContext() NIFI-8178 Changed TestGetHTTP to ITGetHTTP since GetHTTP is deprecated NIFI-8178 Changed TestPostHTTP to ITPostHTTP since PostHTTP is deprecated Signed-off-by: Joe Witt <joewitt@apache.org>
This commit is contained in:
parent
8c1fe84f62
commit
11e9ff3773
|
@ -30,9 +30,10 @@ public interface TlsConfiguration {
|
|||
|
||||
String TLS_1_0_PROTOCOL = "TLSv1";
|
||||
String TLS_1_1_PROTOCOL = "TLSv1.1";
|
||||
String TLS_1_2_PROTOCOL = "TLSv1.2";
|
||||
String[] LEGACY_TLS_PROTOCOL_VERSIONS = new String[]{TLS_1_0_PROTOCOL, TLS_1_1_PROTOCOL};
|
||||
|
||||
String JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION = "TLSv1.2";
|
||||
String JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION = TLS_1_2_PROTOCOL;
|
||||
String JAVA_11_MAX_SUPPORTED_TLS_PROTOCOL_VERSION = "TLSv1.3";
|
||||
String[] JAVA_8_SUPPORTED_TLS_PROTOCOL_VERSIONS = new String[]{JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION};
|
||||
String[] JAVA_11_SUPPORTED_TLS_PROTOCOL_VERSIONS = new String[]{JAVA_11_MAX_SUPPORTED_TLS_PROTOCOL_VERSION, JAVA_8_MAX_SUPPORTED_TLS_PROTOCOL_VERSION};
|
||||
|
|
|
@ -31,12 +31,10 @@ import org.apache.http.conn.HttpClientConnectionManager;
|
|||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.nifi.annotation.behavior.DynamicProperties;
|
||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
|
@ -70,24 +68,14 @@ import org.apache.nifi.processor.Relationship;
|
|||
import org.apache.nifi.processor.exception.ProcessException;
|
||||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.util.StopWatch;
|
||||
import org.apache.nifi.util.Tuple;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -326,32 +314,6 @@ public class GetHTTP extends AbstractSessionFactoryProcessor {
|
|||
.build();
|
||||
}
|
||||
|
||||
private SSLContext createSSLContext(final SSLContextService service)
|
||||
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException {
|
||||
|
||||
final SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
|
||||
|
||||
if (StringUtils.isNotBlank(service.getTrustStoreFile())) {
|
||||
final KeyStore truststore = KeyStoreUtils.getKeyStore(service.getTrustStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getTrustStoreFile()))) {
|
||||
truststore.load(in, service.getTrustStorePassword().toCharArray());
|
||||
}
|
||||
sslContextBuilder.loadTrustMaterial(truststore, new TrustSelfSignedStrategy());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(service.getKeyStoreFile())) {
|
||||
final KeyStore keystore = KeyStoreUtils.getKeyStore(service.getKeyStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getKeyStoreFile()))) {
|
||||
keystore.load(in, service.getKeyStorePassword().toCharArray());
|
||||
}
|
||||
sslContextBuilder.loadKeyMaterial(keystore, service.getKeyStorePassword().toCharArray());
|
||||
}
|
||||
|
||||
sslContextBuilder.useProtocol(service.getSslAlgorithm());
|
||||
|
||||
return sslContextBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) throws ProcessException {
|
||||
final ComponentLog logger = getLogger();
|
||||
|
@ -384,7 +346,7 @@ public class GetHTTP extends AbstractSessionFactoryProcessor {
|
|||
} else {
|
||||
final SSLContext sslContext;
|
||||
try {
|
||||
sslContext = createSSLContext(sslContextService);
|
||||
sslContext = sslContextService.createContext();
|
||||
} catch (final Exception e) {
|
||||
throw new ProcessException(e);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ import com.google.common.base.Optional;
|
|||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
|
@ -544,25 +545,14 @@ public class HandleHttpRequest extends AbstractProcessor {
|
|||
return containerQueue.size();
|
||||
}
|
||||
|
||||
private SslContextFactory createSslFactory(final SSLContextService sslService, final boolean needClientAuth, final boolean wantClientAuth) {
|
||||
final SslContextFactory sslFactory = new SslContextFactory.Server();
|
||||
private SslContextFactory createSslFactory(final SSLContextService sslContextService, final boolean needClientAuth, final boolean wantClientAuth) {
|
||||
final SslContextFactory.Server sslFactory = new SslContextFactory.Server();
|
||||
|
||||
sslFactory.setNeedClientAuth(needClientAuth);
|
||||
sslFactory.setWantClientAuth(wantClientAuth);
|
||||
|
||||
sslFactory.setProtocol(sslService.getSslAlgorithm());
|
||||
|
||||
if (sslService.isKeyStoreConfigured()) {
|
||||
sslFactory.setKeyStorePath(sslService.getKeyStoreFile());
|
||||
sslFactory.setKeyStorePassword(sslService.getKeyStorePassword());
|
||||
sslFactory.setKeyStoreType(sslService.getKeyStoreType());
|
||||
}
|
||||
|
||||
if (sslService.isTrustStoreConfigured()) {
|
||||
sslFactory.setTrustStorePath(sslService.getTrustStoreFile());
|
||||
sslFactory.setTrustStorePassword(sslService.getTrustStorePassword());
|
||||
sslFactory.setTrustStoreType(sslService.getTrustStoreType());
|
||||
}
|
||||
final SSLContext sslContext = sslContextService.createContext();
|
||||
sslFactory.setSslContext(sslContext);
|
||||
|
||||
return sslFactory;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ import org.apache.nifi.util.StopWatch;
|
|||
@ReadsAttribute(attribute = HTTPUtils.HTTP_LOCAL_NAME, description = "IP address/hostname of the server. Used for provenance event."),
|
||||
@ReadsAttribute(attribute = HTTPUtils.HTTP_PORT, description = "Listening port of the server. Used for provenance event."),
|
||||
@ReadsAttribute(attribute = HTTPUtils.HTTP_SSL_CERT, description = "SSL distinguished name (if any). Used for provenance event.")})
|
||||
@SeeAlso(value = {HandleHttpRequest.class}, classNames = {"org.apache.nifi.http.StandardHttpContextMap", "org.apache.nifi.ssl.StandardSSLContextService"})
|
||||
@SeeAlso(value = {HandleHttpRequest.class}, classNames = {"org.apache.nifi.http.StandardHttpContextMap", "org.apache.nifi.ssl.SSLContextService"})
|
||||
public class HandleHttpResponse extends AbstractProcessor {
|
||||
|
||||
public static final PropertyDescriptor STATUS_CODE = new PropertyDescriptor.Builder()
|
||||
|
|
|
@ -61,7 +61,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
+ "E.g.: file.txt is uploaded to /Folder1/SubFolder, then the value of the path attribute will be \"/Folder1/SubFolder/\" "
|
||||
+ "(note that it ends with a separator character).")
|
||||
})
|
||||
@SeeAlso(classNames = {"org.apache.nifi.ssl.StandardRestrictedSSLContextService","org.apache.nifi.ssl.StandardSSLContextService"})
|
||||
@SeeAlso(classNames = {"org.apache.nifi.ssl.RestrictedSSLContextService","org.apache.nifi.ssl.SSLContextService"})
|
||||
public class ListenFTP extends AbstractSessionFactoryProcessor {
|
||||
|
||||
public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
|
||||
|
|
|
@ -21,8 +21,6 @@ import static org.apache.nifi.processors.standard.util.HTTPUtils.PROXY_PORT;
|
|||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -30,11 +28,6 @@ import java.net.InetAddress;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.Principal;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
@ -81,7 +74,6 @@ import org.apache.http.conn.ManagedHttpClientConnection;
|
|||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.entity.ContentProducer;
|
||||
import org.apache.http.entity.EntityTemplate;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
|
@ -90,8 +82,6 @@ import org.apache.http.impl.client.HttpClientBuilder;
|
|||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.protocol.HttpCoreContext;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.http.util.VersionInfo;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
|
@ -122,7 +112,6 @@ import org.apache.nifi.processor.io.InputStreamCallback;
|
|||
import org.apache.nifi.processor.util.StandardValidators;
|
||||
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
||||
import org.apache.nifi.security.util.CertificateUtils;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.stream.io.GZIPOutputStream;
|
||||
import org.apache.nifi.stream.io.LeakyBucketStreamThrottler;
|
||||
|
@ -389,8 +378,7 @@ public class PostHTTP extends AbstractProcessor {
|
|||
} else {
|
||||
final SSLContext sslContext;
|
||||
try {
|
||||
sslContext = createSSLContext(sslContextService);
|
||||
getLogger().info("PostHTTP supports protocol: " + sslContext.getProtocol());
|
||||
sslContext = sslContextService.createContext();
|
||||
} catch (final Exception e) {
|
||||
throw new ProcessException(e);
|
||||
}
|
||||
|
@ -509,38 +497,6 @@ public class PostHTTP extends AbstractProcessor {
|
|||
return url.substring(0, index);
|
||||
}
|
||||
|
||||
private SSLContext createSSLContext(final SSLContextService service)
|
||||
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, KeyManagementException, UnrecoverableKeyException {
|
||||
SSLContextBuilder builder = SSLContexts.custom();
|
||||
final String trustFilename = service.getTrustStoreFile();
|
||||
if (trustFilename != null) {
|
||||
final KeyStore truststore = KeyStoreUtils.getKeyStore(service.getTrustStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getTrustStoreFile()))) {
|
||||
truststore.load(in, service.getTrustStorePassword().toCharArray());
|
||||
}
|
||||
builder = builder.loadTrustMaterial(truststore, new TrustSelfSignedStrategy());
|
||||
}
|
||||
|
||||
final String keyFilename = service.getKeyStoreFile();
|
||||
if (keyFilename != null) {
|
||||
final KeyStore keystore = KeyStoreUtils.getKeyStore(service.getKeyStoreType());
|
||||
try (final InputStream in = new FileInputStream(new File(service.getKeyStoreFile()))) {
|
||||
keystore.load(in, service.getKeyStorePassword().toCharArray());
|
||||
}
|
||||
builder = builder.loadKeyMaterial(keystore, service.getKeyStorePassword().toCharArray());
|
||||
final String alias = keystore.aliases().nextElement();
|
||||
final Certificate cert = keystore.getCertificate(alias);
|
||||
if (cert instanceof X509Certificate) {
|
||||
principal = ((X509Certificate) cert).getSubjectDN();
|
||||
}
|
||||
}
|
||||
|
||||
builder = builder.setProtocol(service.getSslAlgorithm());
|
||||
|
||||
final SSLContext sslContext = builder.build();
|
||||
return sslContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrigger(final ProcessContext context, final ProcessSession session) {
|
||||
FlowFile firstFlowFile = session.get();
|
||||
|
|
|
@ -1,488 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.nifi.processors.standard
|
||||
|
||||
import groovy.servlet.GroovyServlet
|
||||
import groovy.test.GroovyAssert
|
||||
import org.apache.nifi.ssl.SSLContextService
|
||||
import org.apache.nifi.ssl.StandardSSLContextService
|
||||
import org.apache.nifi.util.StandardProcessorTestRunner
|
||||
import org.apache.nifi.util.TestRunner
|
||||
import org.apache.nifi.util.TestRunners
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import org.eclipse.jetty.server.HttpConfiguration
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory
|
||||
import org.eclipse.jetty.server.SecureRequestCustomizer
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.server.ServerConnector
|
||||
import org.eclipse.jetty.server.SslConnectionFactory
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory
|
||||
import org.junit.After
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import javax.crypto.Cipher
|
||||
import javax.net.SocketFactory
|
||||
import javax.net.ssl.HostnameVerifier
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLEngine
|
||||
import javax.net.ssl.SSLHandshakeException
|
||||
import javax.net.ssl.SSLSocket
|
||||
import javax.net.ssl.TrustManager
|
||||
import javax.net.ssl.X509TrustManager
|
||||
import java.security.Security
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@RunWith(JUnit4.class)
|
||||
class TestGetHTTPGroovy extends GroovyTestCase {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TestGetHTTPGroovy.class)
|
||||
|
||||
static private final String KEYSTORE_TYPE = "JKS"
|
||||
|
||||
private static final String TLSv1 = "TLSv1"
|
||||
private static final String TLSv1_1 = "TLSv1.1"
|
||||
private static final String TLSv1_2 = "TLSv1.2"
|
||||
private static final List DEFAULT_PROTOCOLS = [TLSv1, TLSv1_1, TLSv1_2]
|
||||
|
||||
private static final String TLSv1_1_CIPHER_SUITE = "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"
|
||||
private static final SSLContext SSL_CONTEXT = SSLContext.default
|
||||
private static final SSLEngine SSL_ENGINE = SSL_CONTEXT.createSSLEngine()
|
||||
private static
|
||||
final List DEFAULT_CIPHER_SUITES = SSL_ENGINE.supportedCipherSuites as List
|
||||
|
||||
private static final String DEFAULT_HOSTNAME = "localhost"
|
||||
private static final int DEFAULT_TLS_PORT = 8456
|
||||
private static final String HTTPS_URL = "https://${DEFAULT_HOSTNAME}:${DEFAULT_TLS_PORT}"
|
||||
private static final String GET_URL = "${HTTPS_URL}/GetHandler.groovy"
|
||||
|
||||
private static final String MOZILLA_INTERMEDIATE_URL = "https://mozilla-intermediate.badssl.com/"
|
||||
private static final String TLS_1_URL = "https://nifi.apache.org/"
|
||||
private static final String TLS_1_1_URL = "https://nifi.apache.org/"
|
||||
|
||||
private static final String KEYSTORE_PATH = "src/test/resources/keystore.jks"
|
||||
private static final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks"
|
||||
private static final String CACERTS_PATH = "/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/security/cacerts"
|
||||
|
||||
private static final String KEYSTORE_PASSWORD = "passwordpassword"
|
||||
private static final String TRUSTSTORE_PASSWORD = "passwordpassword"
|
||||
private static final String CACERTS_PASSWORD = "changeit"
|
||||
|
||||
private static Server server
|
||||
private static X509TrustManager nullTrustManager
|
||||
private static HostnameVerifier nullHostnameVerifier
|
||||
|
||||
private static TestRunner runner
|
||||
|
||||
private
|
||||
static Server createServer(List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
|
||||
// Create Server
|
||||
Server server = new Server()
|
||||
|
||||
// Add some secure config
|
||||
final HttpConfiguration httpsConfiguration = new HttpConfiguration()
|
||||
httpsConfiguration.setSecureScheme("https")
|
||||
httpsConfiguration.setSecurePort(DEFAULT_TLS_PORT)
|
||||
httpsConfiguration.addCustomizer(new SecureRequestCustomizer())
|
||||
|
||||
// Build the TLS connector
|
||||
final ServerConnector https = createConnector(server, httpsConfiguration, supportedProtocols, supportedCipherSuites)
|
||||
|
||||
// Add this connector
|
||||
server.addConnector(https)
|
||||
logger.info("Created server with supported protocols: ${supportedProtocols}")
|
||||
|
||||
/** Create a simple Groovlet that responds to the incoming request by reversing the string parameter
|
||||
* i.e. localhost:8456/ReverseHandler.groovy?string=Happy%20birthday -> yadhtrib yppaH
|
||||
*/
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS)
|
||||
context.with {
|
||||
contextPath = '/'
|
||||
resourceBase = 'src/test/resources/TestGetHTTP'
|
||||
addServlet(GroovyServlet, '*.groovy')
|
||||
}
|
||||
server.setHandler(context)
|
||||
server
|
||||
}
|
||||
|
||||
private
|
||||
static ServerConnector createConnector(Server server, HttpConfiguration httpsConfiguration, List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
|
||||
ServerConnector https = new ServerConnector(server,
|
||||
new SslConnectionFactory(createSslContextFactory(supportedProtocols, supportedCipherSuites), "http/1.1"),
|
||||
new HttpConnectionFactory(httpsConfiguration))
|
||||
|
||||
// set host and port
|
||||
https.setHost(DEFAULT_HOSTNAME)
|
||||
https.setPort(DEFAULT_TLS_PORT)
|
||||
https
|
||||
}
|
||||
|
||||
private
|
||||
static SslContextFactory createSslContextFactory(List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
|
||||
final SslContextFactory contextFactory = new SslContextFactory.Server()
|
||||
contextFactory.needClientAuth = false
|
||||
contextFactory.wantClientAuth = false
|
||||
|
||||
contextFactory.setKeyStorePath(KEYSTORE_PATH)
|
||||
contextFactory.setKeyStoreType(KEYSTORE_TYPE)
|
||||
contextFactory.setKeyStorePassword(KEYSTORE_PASSWORD)
|
||||
|
||||
contextFactory.setIncludeProtocols(supportedProtocols as String[])
|
||||
if (supportedCipherSuites) {
|
||||
contextFactory.setIncludeCipherSuites(supportedCipherSuites as String[])
|
||||
}
|
||||
contextFactory
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
static void setUpOnce() throws Exception {
|
||||
Security.addProvider(new BouncyCastleProvider())
|
||||
|
||||
logger.metaClass.methodMissing = { String name, args ->
|
||||
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
|
||||
}
|
||||
|
||||
server = createServer()
|
||||
|
||||
runner = configureRunner()
|
||||
|
||||
// Print the default cipher suite list
|
||||
logger.info("Default supported cipher suites: \n\t${DEFAULT_CIPHER_SUITES.join("\n\t")}")
|
||||
}
|
||||
|
||||
private static TestRunner configureRunner() {
|
||||
// Set the default trust manager for the "default" tests (the outgoing Groovy call) to ignore certificate path verification for localhost
|
||||
nullTrustManager = [
|
||||
checkClientTrusted: { chain, authType -> },
|
||||
checkServerTrusted: { chain, authType -> },
|
||||
getAcceptedIssuers: { null }
|
||||
] as X509TrustManager
|
||||
|
||||
nullHostnameVerifier = [
|
||||
verify: { String hostname, session ->
|
||||
// Will always return true if the hostname is "localhost" or the Mozilla intermediate site
|
||||
hostname.equalsIgnoreCase(DEFAULT_HOSTNAME) || hostname.equalsIgnoreCase(new URL(MOZILLA_INTERMEDIATE_URL).host)
|
||||
}
|
||||
] as HostnameVerifier
|
||||
|
||||
// Configure the test runner
|
||||
TestRunner runner = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class)
|
||||
final SSLContextService sslContextService = new StandardSSLContextService()
|
||||
runner.addControllerService("ssl-context", sslContextService)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE_PATH)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, TRUSTSTORE_PASSWORD)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, KEYSTORE_TYPE)
|
||||
runner.enableControllerService(sslContextService)
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.GetHTTP.URL, GET_URL)
|
||||
runner.setProperty(org.apache.nifi.processors.standard.GetHTTP.SSL_CONTEXT_SERVICE, "ssl-context")
|
||||
|
||||
runner
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static void tearDownOnce() {
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
void setUp() throws Exception {
|
||||
// This must be executed before each test, or the connections will be re-used and if a TLSv1.1 connection is re-used against a server that only supports TLSv1.2, it will fail
|
||||
SSLContext sc = SSLContext.getInstance(TLSv1_2)
|
||||
sc.init(null, [nullTrustManager] as TrustManager[], null)
|
||||
SocketFactory socketFactory = sc.getSocketFactory()
|
||||
logger.info("JCE unlimited strength installed: ${Cipher.getMaxAllowedKeyLength("AES") > 128}")
|
||||
logger.info("Supported client cipher suites: ${socketFactory.supportedCipherSuites}")
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory)
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(nullHostnameVerifier)
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.GetHTTP.FILENAME, "mockFlowfile_${System.currentTimeMillis()}")
|
||||
|
||||
(runner as StandardProcessorTestRunner).clearQueue()
|
||||
}
|
||||
|
||||
@After
|
||||
void tearDown() throws Exception {
|
||||
try {
|
||||
server.stop()
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
runner.clearTransferState()
|
||||
runner.clearProvenanceEvents()
|
||||
(runner as StandardProcessorTestRunner).clearQueue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Jetty 9.4.0+ no longer supports TLSv1.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1 is available")
|
||||
void testDefaultShouldSupportTLSv1() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with TLSv1 only
|
||||
server = createServer([TLSv1])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
String response = new URL(url).text
|
||||
logger.info("Response from ${HTTPS_URL}: ${response}")
|
||||
|
||||
// Assert
|
||||
assert response == MSG.reverse()
|
||||
}
|
||||
|
||||
/**
|
||||
* Jetty 9.4.0+ no longer supports TLSv1.1 unless compatible ("vulnerable" according to Jetty documentation, see <a href="https://github.com/eclipse/jetty.project/issues/860">https://github.com/eclipse/jetty.project/issues/860</a>) cipher suites are explicitly provided.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1.1 is available")
|
||||
void testDefaultShouldSupportTLSv1_1() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with TLSv1.1 only
|
||||
server = createServer([TLSv1_1])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
String response = new URL(url).text
|
||||
logger.info("Response from ${HTTPS_URL}: ${response}")
|
||||
|
||||
// Assert
|
||||
assert response == MSG.reverse()
|
||||
}
|
||||
|
||||
/**
|
||||
* Jetty 9.4.0+ no longer supports TLSv1.1 unless compatible ("vulnerable" according to Jetty documentation, see <a href="https://github.com/eclipse/jetty.project/issues/860">https://github.com/eclipse/jetty.project/issues/860</a>) cipher suites are explicitly provided.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1 is available")
|
||||
void testDefaultShouldSupportTLSv1_1WithVulnerableCipherSuites() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with TLSv1.1 only but explicitly provide the legacy cipher suite
|
||||
server = createServer([TLSv1_1], [TLSv1_1_CIPHER_SUITE])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
String response = new URL(url).text
|
||||
logger.info("Response from ${HTTPS_URL}: ${response}")
|
||||
|
||||
// Assert
|
||||
assert response == MSG.reverse()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultShouldSupportTLSv1_2() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with TLSv1.2 only
|
||||
server = createServer([TLSv1_2])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
String response = new URL(url).text
|
||||
logger.info("Response from ${HTTPS_URL}: ${response}")
|
||||
|
||||
// Assert
|
||||
assert response == MSG.reverse()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultShouldPreferTLSv1_2() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with all TLS protocols
|
||||
server = createServer()
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Create a connection that could use TLSv1, TLSv1.1, or TLSv1.2
|
||||
SSLContext sc = SSLContext.getInstance("TLS")
|
||||
sc.init(null, [nullTrustManager] as TrustManager[], null)
|
||||
SocketFactory socketFactory = sc.getSocketFactory()
|
||||
|
||||
URL formedUrl = new URL(url)
|
||||
SSLSocket socket = (SSLSocket) socketFactory.createSocket(formedUrl.host, formedUrl.port)
|
||||
logger.info("Enabled protocols: ${socket.enabledProtocols}")
|
||||
|
||||
// Act
|
||||
socket.startHandshake()
|
||||
String selectedProtocol = socket.getSession().protocol
|
||||
logger.info("Selected protocol: ${selectedProtocol}")
|
||||
|
||||
// Assert
|
||||
assert selectedProtocol == TLSv1_2
|
||||
}
|
||||
|
||||
private static void enableContextServiceProtocol(TestRunner runner, String protocol, String truststorePath = TRUSTSTORE_PATH, String truststorePassword = TRUSTSTORE_PASSWORD) {
|
||||
final SSLContextService sslContextService = new StandardSSLContextService()
|
||||
runner.addControllerService("ssl-context", sslContextService)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, truststorePath)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, truststorePassword)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, KEYSTORE_TYPE)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.SSL_ALGORITHM, protocol)
|
||||
runner.enableControllerService(sslContextService)
|
||||
def sslContext = sslContextService.createContext();
|
||||
logger.info("GetHTTP supported protocols: ${sslContext.protocol}")
|
||||
logger.info("GetHTTP supported cipher suites: ${sslContext.supportedSSLParameters.cipherSuites}")
|
||||
}
|
||||
|
||||
/**
|
||||
* This test connects to a server running TLSv1/1.1/1.2. It iterates over an {@link SSLContextService} with TLSv1, TLSv1.1, and TLSv1.2 support. All three context services should be able to communicate successfully.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1 is available")
|
||||
void testGetHTTPShouldConnectToServerWithTLSv1() {
|
||||
// Arrange
|
||||
|
||||
// Connect to a server that still runs TLSv1/1.1/1.2
|
||||
runner.setProperty(org.apache.nifi.processors.standard.GetHTTP.URL, TLS_1_URL)
|
||||
|
||||
// Act
|
||||
[TLSv1, TLSv1_1, TLSv1_2].each { String tlsVersion ->
|
||||
logger.info("Set context service protocol to ${tlsVersion}")
|
||||
enableContextServiceProtocol(runner, tlsVersion, CACERTS_PATH, CACERTS_PASSWORD)
|
||||
runner.assertQueueEmpty()
|
||||
logger.info("Queue size (before run): ${runner.queueSize}")
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
logger.info("Queue size (after run): ${runner.queueSize}")
|
||||
runner.assertAllFlowFilesTransferred(REL_SUCCESS, 1)
|
||||
runner.clearTransferState()
|
||||
logger.info("Ran successfully")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test creates a server that supports TLSv1.1. It iterates over an {@link SSLContextService} with TLSv1, TLSv1.1, and TLSv1.2 support. The context service with TLSv1 should not be able to communicate with a server that does not support it, but TLSv1.1 and TLSv1.2 should be able to communicate successfully.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that only supports TLSv1.1 is available")
|
||||
void testGetHTTPShouldConnectToServerWithTLSv1_1() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
|
||||
// Configure server with TLSv1.1 only
|
||||
server = createServer([TLSv1_1])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
logger.info("Set context service protocol to ${TLSv1}")
|
||||
enableContextServiceProtocol(runner, TLSv1)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
|
||||
def ae = GroovyAssert.shouldFail(AssertionError) {
|
||||
runner.run()
|
||||
}
|
||||
logger.expected(ae.getMessage())
|
||||
logger.expected("Cause: ${ae.cause?.class?.name}")
|
||||
logger.expected("Original cause: ${ae.cause?.cause?.class?.name}")
|
||||
|
||||
// Assert
|
||||
assert ae.cause.cause instanceof SSLHandshakeException
|
||||
runner.clearTransferState()
|
||||
logger.expected("Unable to connect")
|
||||
|
||||
[TLSv1_1, TLSv1_2].each { String tlsVersion ->
|
||||
logger.info("Set context service protocol to ${tlsVersion}")
|
||||
enableContextServiceProtocol(runner, tlsVersion)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
runner.assertAllFlowFilesTransferred(REL_SUCCESS)
|
||||
runner.clearTransferState()
|
||||
logger.info("Ran successfully")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test creates a server that supports TLSv1.2. It iterates over an {@link SSLContextService} with TLSv1, TLSv1.1, and TLSv1.2 support. The context services with TLSv1 and TLSv1.1 should not be able to communicate with a server that does not support it, but TLSv1.2 should be able to communicate successfully.
|
||||
*/
|
||||
@Test
|
||||
void testGetHTTPShouldConnectToServerWithTLSv1_2() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
|
||||
// Configure server with TLSv1.2 only
|
||||
server = createServer([TLSv1_2])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
[TLSv1, TLSv1_1].each { String tlsVersion ->
|
||||
logger.info("Set context service protocol to ${tlsVersion}")
|
||||
enableContextServiceProtocol(runner, tlsVersion)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
def ae = GroovyAssert.shouldFail(AssertionError) {
|
||||
runner.run()
|
||||
}
|
||||
logger.expected(ae.getMessage())
|
||||
logger.expected("Cause: ${ae.cause?.class?.name}")
|
||||
logger.expected("Original cause: ${ae.cause?.cause?.class?.name}")
|
||||
|
||||
// Assert
|
||||
assert ae.cause.cause instanceof SSLHandshakeException
|
||||
runner.clearTransferState()
|
||||
logger.expected("Unable to connect")
|
||||
}
|
||||
|
||||
logger.info("Set context service protocol to ${TLSv1_2}")
|
||||
enableContextServiceProtocol(runner, TLSv1_2)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.GetHTTP.REL_SUCCESS)
|
||||
runner.clearTransferState()
|
||||
logger.info("Ran successfully")
|
||||
}
|
||||
}
|
|
@ -1,443 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.nifi.processors.standard
|
||||
|
||||
import groovy.servlet.GroovyServlet
|
||||
import org.apache.nifi.security.util.TlsPlatform
|
||||
import org.apache.nifi.ssl.SSLContextService
|
||||
import org.apache.nifi.ssl.StandardSSLContextService
|
||||
import org.apache.nifi.util.TestRunner
|
||||
import org.apache.nifi.util.TestRunners
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import org.eclipse.jetty.server.HttpConfiguration
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory
|
||||
import org.eclipse.jetty.server.SecureRequestCustomizer
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.server.ServerConnector
|
||||
import org.eclipse.jetty.server.SslConnectionFactory
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory
|
||||
import org.junit.After
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Before
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import javax.crypto.Cipher
|
||||
import javax.net.SocketFactory
|
||||
import javax.net.ssl.HostnameVerifier
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.SSLEngine
|
||||
import javax.net.ssl.SSLSocket
|
||||
import javax.net.ssl.TrustManager
|
||||
import javax.net.ssl.X509TrustManager
|
||||
import java.security.Security
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@RunWith(JUnit4.class)
|
||||
class TestPostHTTPGroovy extends GroovyTestCase {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TestPostHTTPGroovy.class)
|
||||
|
||||
|
||||
static private final String KEYSTORE_TYPE = "JKS"
|
||||
|
||||
private static final String TLSv1 = "TLSv1"
|
||||
private static final String TLSv1_1 = "TLSv1.1"
|
||||
private static final String TLSv1_2 = "TLSv1.2"
|
||||
private static final List DEFAULT_PROTOCOLS = new ArrayList(TlsPlatform.supportedProtocols)
|
||||
|
||||
private static final SSLContext SSL_CONTEXT = SSLContext.default
|
||||
private static final SSLEngine SSL_ENGINE = SSL_CONTEXT.createSSLEngine()
|
||||
private static
|
||||
final List DEFAULT_CIPHER_SUITES = SSL_ENGINE.supportedCipherSuites as List
|
||||
|
||||
private static final String DEFAULT_HOSTNAME = "localhost"
|
||||
private static final int DEFAULT_TLS_PORT = 8456
|
||||
private static final String HTTPS_URL = "https://${DEFAULT_HOSTNAME}:${DEFAULT_TLS_PORT}"
|
||||
private static final String POST_URL = "${HTTPS_URL}/PostHandler.groovy"
|
||||
|
||||
private static final String KEYSTORE_PATH = "src/test/resources/keystore.jks"
|
||||
private static final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks"
|
||||
|
||||
private static final String KEYSTORE_PASSWORD = "passwordpassword"
|
||||
private static final String TRUSTSTORE_PASSWORD = "passwordpassword"
|
||||
|
||||
private static Server server
|
||||
private static X509TrustManager nullTrustManager
|
||||
private static HostnameVerifier nullHostnameVerifier
|
||||
|
||||
private static TestRunner runner
|
||||
|
||||
private
|
||||
static Server createServer(List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
|
||||
// Create Server
|
||||
Server server = new Server()
|
||||
|
||||
// Add some secure config
|
||||
final HttpConfiguration httpsConfiguration = new HttpConfiguration()
|
||||
httpsConfiguration.setSecureScheme("https")
|
||||
httpsConfiguration.setSecurePort(DEFAULT_TLS_PORT)
|
||||
httpsConfiguration.addCustomizer(new SecureRequestCustomizer())
|
||||
|
||||
// Build the TLS connector
|
||||
final ServerConnector https = createConnector(server, httpsConfiguration, supportedProtocols, supportedCipherSuites)
|
||||
|
||||
// Add this connector
|
||||
server.addConnector(https)
|
||||
logger.info("Created server with supported protocols: ${supportedProtocols}")
|
||||
|
||||
/** Create a simple Groovlet that responds to the incoming request by reversing the string parameter
|
||||
* i.e. localhost:8456/ReverseHandler.groovy?string=Happy%20birthday -> yadhtrib yppaH
|
||||
*/
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS)
|
||||
context.with {
|
||||
contextPath = '/'
|
||||
resourceBase = 'src/test/resources/TestPostHTTP'
|
||||
addServlet(GroovyServlet, '*.groovy')
|
||||
}
|
||||
server.setHandler(context)
|
||||
server
|
||||
}
|
||||
|
||||
private
|
||||
static ServerConnector createConnector(Server server, HttpConfiguration httpsConfiguration, List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
|
||||
ServerConnector https = new ServerConnector(server,
|
||||
new SslConnectionFactory(createSslContextFactory(supportedProtocols, supportedCipherSuites), "http/1.1"),
|
||||
new HttpConnectionFactory(httpsConfiguration))
|
||||
|
||||
// set host and port
|
||||
https.setHost(DEFAULT_HOSTNAME)
|
||||
https.setPort(DEFAULT_TLS_PORT)
|
||||
https
|
||||
}
|
||||
|
||||
private
|
||||
static SslContextFactory createSslContextFactory(List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
|
||||
final SslContextFactory contextFactory = new SslContextFactory.Server()
|
||||
contextFactory.needClientAuth = false
|
||||
contextFactory.wantClientAuth = false
|
||||
|
||||
contextFactory.setKeyStorePath(KEYSTORE_PATH)
|
||||
contextFactory.setKeyStoreType(KEYSTORE_TYPE)
|
||||
contextFactory.setKeyStorePassword(KEYSTORE_PASSWORD)
|
||||
|
||||
contextFactory.setIncludeProtocols(supportedProtocols as String[])
|
||||
if (supportedCipherSuites) {
|
||||
contextFactory.setIncludeCipherSuites(supportedCipherSuites as String[])
|
||||
}
|
||||
contextFactory
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
static void setUpOnce() throws Exception {
|
||||
Security.addProvider(new BouncyCastleProvider())
|
||||
|
||||
logger.metaClass.methodMissing = { String name, args ->
|
||||
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
|
||||
}
|
||||
|
||||
server = createServer()
|
||||
|
||||
runner = configureRunner()
|
||||
|
||||
// Print the default cipher suite list
|
||||
logger.info("Default supported cipher suites: \n\t${DEFAULT_CIPHER_SUITES.join("\n\t")}")
|
||||
}
|
||||
|
||||
private static TestRunner configureRunner() {
|
||||
// Set the default trust manager for the "default" tests (the outgoing Groovy call) to ignore certificate path verification for localhost
|
||||
nullTrustManager = [
|
||||
checkClientTrusted: { chain, authType -> },
|
||||
checkServerTrusted: { chain, authType -> },
|
||||
getAcceptedIssuers: { null }
|
||||
] as X509TrustManager
|
||||
|
||||
nullHostnameVerifier = [
|
||||
verify: { String hostname, session ->
|
||||
// Will always return true if the hostname is "localhost"
|
||||
hostname.equalsIgnoreCase(DEFAULT_HOSTNAME)
|
||||
}
|
||||
] as HostnameVerifier
|
||||
|
||||
// Configure the test runner
|
||||
TestRunner runner = TestRunners.newTestRunner(org.apache.nifi.processors.standard.PostHTTP.class)
|
||||
final SSLContextService sslContextService = new StandardSSLContextService()
|
||||
runner.addControllerService("ssl-context", sslContextService)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE_PATH)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, TRUSTSTORE_PASSWORD)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, KEYSTORE_TYPE)
|
||||
runner.enableControllerService(sslContextService)
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, POST_URL)
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context")
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false")
|
||||
|
||||
runner
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
static void tearDownOnce() {
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
void setUp() throws Exception {
|
||||
// This must be executed before each test, or the connections will be re-used and if a TLSv1.1 connection is re-used against a server that only supports TLSv1.2, it will fail
|
||||
SSLContext sc = SSLContext.getInstance(TLSv1_2)
|
||||
sc.init(null, [nullTrustManager] as TrustManager[], null)
|
||||
SocketFactory socketFactory = sc.getSocketFactory()
|
||||
logger.info("JCE unlimited strength installed: ${Cipher.getMaxAllowedKeyLength("AES") > 128}")
|
||||
logger.info("Supported client cipher suites: ${socketFactory.supportedCipherSuites}")
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory)
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(nullHostnameVerifier)
|
||||
}
|
||||
|
||||
@After
|
||||
void tearDown() throws Exception {
|
||||
try {
|
||||
server.stop()
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
runner.clearTransferState()
|
||||
runner.clearProvenanceEvents()
|
||||
}
|
||||
|
||||
/**
|
||||
* Jetty 9.4.0+ no longer supports TLSv1.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1 is available")
|
||||
void testDefaultShouldSupportTLSv1() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with TLSv1 only
|
||||
server = createServer([TLSv1])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
String response = new URL(url).text
|
||||
logger.info("Response from ${HTTPS_URL}: ${response}")
|
||||
|
||||
// Assert
|
||||
assert response == MSG.reverse()
|
||||
}
|
||||
|
||||
/**
|
||||
* Jetty 9.4.0+ no longer supports TLSv1.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1.1 is available")
|
||||
void testDefaultShouldSupportTLSv1_1() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with TLSv1.1 only
|
||||
server = createServer([TLSv1_1])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
String response = new URL(url).text
|
||||
logger.info("Response from ${HTTPS_URL}: ${response}")
|
||||
|
||||
// Assert
|
||||
assert response == MSG.reverse()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultShouldSupportTLSv1_2() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with TLSv1.2 only
|
||||
server = createServer([TLSv1_2])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
String response = new URL(url).text
|
||||
logger.info("Response from ${HTTPS_URL}: ${response}")
|
||||
|
||||
// Assert
|
||||
assert response == MSG.reverse()
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultShouldPreferHighestSupportedVersion() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
final String url = "${HTTPS_URL}/ReverseHandler.groovy?string=${URLEncoder.encode(MSG, "UTF-8")}"
|
||||
|
||||
// Configure server with all TLS protocols
|
||||
server = createServer()
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Create a connection that could use TLSv1, TLSv1.1, or TLSv1.2
|
||||
SSLContext sc = SSLContext.getInstance("TLS")
|
||||
sc.init(null, [nullTrustManager] as TrustManager[], null)
|
||||
SocketFactory socketFactory = sc.getSocketFactory()
|
||||
|
||||
URL formedUrl = new URL(url)
|
||||
SSLSocket socket = (SSLSocket) socketFactory.createSocket(formedUrl.host, formedUrl.port)
|
||||
logger.info("Enabled protocols: ${socket.enabledProtocols}")
|
||||
|
||||
// Act
|
||||
socket.startHandshake()
|
||||
String selectedProtocol = socket.getSession().protocol
|
||||
logger.info("Selected protocol: ${selectedProtocol}")
|
||||
|
||||
// Assert
|
||||
assert selectedProtocol == TlsPlatform.latestProtocol
|
||||
}
|
||||
|
||||
private static void enableContextServiceProtocol(TestRunner runner, String protocol) {
|
||||
final SSLContextService sslContextService = new StandardSSLContextService()
|
||||
runner.addControllerService("ssl-context", sslContextService)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE_PATH)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, TRUSTSTORE_PASSWORD)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, KEYSTORE_TYPE)
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.SSL_ALGORITHM, protocol)
|
||||
runner.enableControllerService(sslContextService)
|
||||
def sslContext = sslContextService.createContext();
|
||||
logger.info("PostHTTP supported protocols: ${sslContext.protocol}")
|
||||
logger.info("PostHTTP supported cipher suites: ${sslContext.supportedSSLParameters.cipherSuites}")
|
||||
}
|
||||
|
||||
/**
|
||||
* This test creates a server that supports TLSv1. It iterates over an {@link SSLContextService} with TLSv1, TLSv1.1, and TLSv1.2 support. All three context services should be able to communicate successfully.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1 is available")
|
||||
void testPostHTTPShouldConnectToServerWithTLSv1() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
|
||||
// Configure server with TLSv1 only
|
||||
server = createServer([TLSv1])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
[TLSv1, TLSv1_1, TLSv1_2].each { String tlsVersion ->
|
||||
logger.info("Set context service protocol to ${tlsVersion}")
|
||||
enableContextServiceProtocol(runner, tlsVersion)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1)
|
||||
runner.clearTransferState()
|
||||
logger.info("Ran successfully")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test creates a server that supports TLSv1.1. It iterates over an {@link SSLContextService} with TLSv1, TLSv1.1, and TLSv1.2 support. The context service with TLSv1 should not be able to communicate with a server that does not support it, but TLSv1.1 and TLSv1.2 should be able to communicate successfully.
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Ignore until embeddable test HTTPS server that supports TLSv1.1 is available")
|
||||
void testPostHTTPShouldConnectToServerWithTLSv1_1() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
|
||||
// Configure server with TLSv1.1 only
|
||||
server = createServer([TLSv1_1])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
logger.info("Set context service protocol to ${TLSv1}")
|
||||
enableContextServiceProtocol(runner, TLSv1)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_FAILURE, 1)
|
||||
runner.clearTransferState()
|
||||
logger.expected("Unable to connect")
|
||||
|
||||
[TLSv1_1, TLSv1_2].each { String tlsVersion ->
|
||||
logger.info("Set context service protocol to ${tlsVersion}")
|
||||
enableContextServiceProtocol(runner, tlsVersion)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1)
|
||||
runner.clearTransferState()
|
||||
logger.info("Ran successfully")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test creates a server that supports TLSv1.2. It iterates over an {@link SSLContextService} with TLSv1, TLSv1.1, and TLSv1.2 support. The context services with TLSv1 and TLSv1.1 should not be able to communicate with a server that does not support it, but TLSv1.2 should be able to communicate successfully.
|
||||
*/
|
||||
@Test
|
||||
void testPostHTTPShouldConnectToServerWithTLSv1_2() {
|
||||
// Arrange
|
||||
final String MSG = "This is a test message"
|
||||
|
||||
// Configure server with TLSv1.2 only
|
||||
server = createServer([TLSv1_2])
|
||||
|
||||
// Start server
|
||||
server.start()
|
||||
|
||||
// Act
|
||||
[TLSv1, TLSv1_1].each { String tlsVersion ->
|
||||
logger.info("Set context service protocol to ${tlsVersion}")
|
||||
enableContextServiceProtocol(runner, tlsVersion)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_FAILURE, 1)
|
||||
runner.clearTransferState()
|
||||
logger.expected("Unable to connect")
|
||||
}
|
||||
|
||||
logger.info("Set context service protocol to ${TLSv1_2}")
|
||||
enableContextServiceProtocol(runner, TLSv1_2)
|
||||
runner.enqueue(MSG.getBytes())
|
||||
runner.run()
|
||||
|
||||
// Assert
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1)
|
||||
runner.clearTransferState()
|
||||
logger.info("Ran successfully")
|
||||
}
|
||||
}
|
|
@ -20,37 +20,52 @@ import static org.junit.Assert.assertEquals;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.nifi.components.state.Scope;
|
||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
||||
import org.apache.nifi.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.security.util.ClientAuth;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.apache.nifi.web.util.TestServer;
|
||||
import org.apache.nifi.web.util.JettyServerUtils;
|
||||
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
*
|
||||
* Integration Test for deprecated GetHTTP Processor
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TestGetHTTP {
|
||||
public class ITGetHTTP {
|
||||
private static final String SSL_CONTEXT_IDENTIFIER = SSLContextService.class.getName();
|
||||
|
||||
private static final String HTTP_URL = "http://localhost:%d";
|
||||
|
||||
private static final String HTTPS_URL = "https://localhost:%d";
|
||||
|
||||
private static SSLContext keyStoreSslContext;
|
||||
|
||||
private static SSLContext trustStoreSslContext;
|
||||
|
||||
private TestRunner controller;
|
||||
|
||||
@BeforeClass
|
||||
public static void before() {
|
||||
public static void configureServices() throws TlsException {
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
|
||||
System.setProperty("org.slf4j.simpleLogger.showDateTime", "true");
|
||||
System.setProperty("org.slf4j.simpleLogger.log.nifi.processors.standard.GetHTTP", "debug");
|
||||
System.setProperty("org.slf4j.simpleLogger.log.nifi.processors.standard.TestGetHTTP", "debug");
|
||||
|
||||
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -60,14 +75,15 @@ public class TestGetHTTP {
|
|||
handler.addServletWithMapping(RESTServiceContentModified.class, "/*");
|
||||
|
||||
// create the service
|
||||
TestServer server = new TestServer();
|
||||
server.addHandler(handler);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
final Server server = JettyServerUtils.createServer(port, null, null);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.startServer();
|
||||
JettyServerUtils.startServer(server);
|
||||
|
||||
// this is the base url with the random port
|
||||
String destination = server.getUrl();
|
||||
String destination = String.format(HTTP_URL, port);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
|
@ -139,34 +155,32 @@ public class TestGetHTTP {
|
|||
|
||||
} finally {
|
||||
// shutdown web service
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public final void testContentModifiedTwoServers() throws Exception {
|
||||
// set up web services
|
||||
ServletHandler handler1 = new ServletHandler();
|
||||
final int port1 = NetworkUtils.availablePort();
|
||||
final Server server1 = JettyServerUtils.createServer(port1, null, null);
|
||||
final ServletHandler handler1 = new ServletHandler();
|
||||
handler1.addServletWithMapping(RESTServiceContentModified.class, "/*");
|
||||
JettyServerUtils.addHandler(server1, handler1);
|
||||
|
||||
ServletHandler handler2 = new ServletHandler();
|
||||
final int port2 = NetworkUtils.availablePort();
|
||||
final Server server2 = JettyServerUtils.createServer(port2, null, null);
|
||||
final ServletHandler handler2 = new ServletHandler();
|
||||
handler2.addServletWithMapping(RESTServiceContentModified.class, "/*");
|
||||
|
||||
// create the services
|
||||
TestServer server1 = new TestServer();
|
||||
server1.addHandler(handler1);
|
||||
|
||||
TestServer server2 = new TestServer();
|
||||
server2.addHandler(handler2);
|
||||
JettyServerUtils.addHandler(server2, handler2);
|
||||
|
||||
try {
|
||||
server1.startServer();
|
||||
server2.startServer();
|
||||
JettyServerUtils.startServer(server1);
|
||||
JettyServerUtils.startServer(server2);
|
||||
|
||||
// this is the base urls with the random ports
|
||||
String destination1 = server1.getUrl();
|
||||
String destination2 = server2.getUrl();
|
||||
String destination1 = String.format(HTTP_URL, port1);
|
||||
String destination2 = String.format(HTTP_URL, port2);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
|
@ -205,8 +219,10 @@ public class TestGetHTTP {
|
|||
|
||||
} finally {
|
||||
// shutdown web services
|
||||
server1.shutdownServer();
|
||||
server2.shutdownServer();
|
||||
server1.stop();
|
||||
server1.destroy();
|
||||
server2.stop();
|
||||
server2.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,13 +233,13 @@ public class TestGetHTTP {
|
|||
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
||||
|
||||
// create the service
|
||||
TestServer server = new TestServer();
|
||||
server.addHandler(handler);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
Server server = JettyServerUtils.createServer(port, null, null);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.startServer();
|
||||
|
||||
String destination = server.getUrl();
|
||||
JettyServerUtils.startServer(server);
|
||||
final String destination = String.format(HTTP_URL, port);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
|
@ -241,7 +257,8 @@ public class TestGetHTTP {
|
|||
|
||||
// shutdown web service
|
||||
} finally {
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,13 +269,13 @@ public class TestGetHTTP {
|
|||
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
||||
|
||||
// create the service
|
||||
TestServer server = new TestServer();
|
||||
server.addHandler(handler);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
Server server = JettyServerUtils.createServer(port, null, null);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.startServer();
|
||||
|
||||
String destination = server.getUrl();
|
||||
JettyServerUtils.startServer(server);
|
||||
final String destination = String.format(HTTP_URL, port);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
|
@ -275,7 +292,8 @@ public class TestGetHTTP {
|
|||
|
||||
// shutdown web service
|
||||
} finally {
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,13 +304,13 @@ public class TestGetHTTP {
|
|||
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
||||
|
||||
// create the service
|
||||
TestServer server = new TestServer();
|
||||
server.addHandler(handler);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
Server server = JettyServerUtils.createServer(port, null, null);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.startServer();
|
||||
|
||||
String destination = server.getUrl();
|
||||
JettyServerUtils.startServer(server);
|
||||
final String destination = String.format(HTTP_URL, port);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
|
@ -311,7 +329,8 @@ public class TestGetHTTP {
|
|||
assertTrue(fileName.matches("test_\\d\\d\\d\\d/\\d\\d/\\d\\d_\\d\\d:\\d\\d:\\d\\d"));
|
||||
// shutdown web service
|
||||
} finally {
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,13 +345,14 @@ public class TestGetHTTP {
|
|||
handler.addServletWithMapping(HttpErrorServlet.class, "/*");
|
||||
|
||||
// create the service
|
||||
TestServer server = new TestServer();
|
||||
server.addHandler(handler);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
Server server = JettyServerUtils.createServer(port, null, null);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.startServer();
|
||||
JettyServerUtils.startServer(server);
|
||||
final String destination = String.format(HTTP_URL, port);
|
||||
HttpErrorServlet servlet = (HttpErrorServlet) handler.getServlets()[0].getServlet();
|
||||
String destination = server.getUrl();
|
||||
|
||||
this.controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
this.controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.CONNECTION_TIMEOUT, "5 secs");
|
||||
|
@ -357,31 +377,30 @@ public class TestGetHTTP {
|
|||
this.controller.assertTransferCount(org.apache.nifi.processors.standard.GetHTTP.REL_SUCCESS, 0);
|
||||
} finally {
|
||||
// shutdown web service
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testSecure_oneWaySsl() throws Exception {
|
||||
public final void testTlsClientAuthenticationNone() throws Exception {
|
||||
// set up web service
|
||||
final ServletHandler handler = new ServletHandler();
|
||||
handler.addServletWithMapping(HelloWorldServlet.class, "/*");
|
||||
|
||||
// create the service, disabling the need for client auth
|
||||
final Map<String, String> serverSslProperties = getKeystoreProperties();
|
||||
serverSslProperties.put(TestServer.NEED_CLIENT_AUTH, Boolean.toString(false));
|
||||
final TestServer server = new TestServer(serverSslProperties);
|
||||
server.addHandler(handler);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
final Server server = JettyServerUtils.createServer(port, keyStoreSslContext, ClientAuth.NONE);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.startServer();
|
||||
|
||||
final String destination = server.getSecureUrl();
|
||||
JettyServerUtils.startServer(server);
|
||||
final String destination = String.format(HTTPS_URL, port);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
// Use context service with only a truststore
|
||||
useSSLContextService(getTruststoreProperties());
|
||||
enableSslContextService(trustStoreSslContext);
|
||||
|
||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.CONNECTION_TIMEOUT, "5 secs");
|
||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.URL, destination);
|
||||
|
@ -393,31 +412,30 @@ public class TestGetHTTP {
|
|||
final MockFlowFile mff = controller.getFlowFilesForRelationship(org.apache.nifi.processors.standard.GetHTTP.REL_SUCCESS).get(0);
|
||||
mff.assertContentEquals("Hello, World!");
|
||||
} finally {
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testSecure_twoWaySsl() throws Exception {
|
||||
public final void testTlsClientAuthenticationRequired() throws Exception {
|
||||
// set up web service
|
||||
final ServletHandler handler = new ServletHandler();
|
||||
handler.addServletWithMapping(HelloWorldServlet.class, "/*");
|
||||
|
||||
// create the service, providing both truststore and keystore properties, requiring client auth (default)
|
||||
final Map<String, String> twoWaySslProperties = getKeystoreProperties();
|
||||
twoWaySslProperties.putAll(getTruststoreProperties());
|
||||
final TestServer server = new TestServer(twoWaySslProperties);
|
||||
server.addHandler(handler);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
final Server server = JettyServerUtils.createServer(port, keyStoreSslContext, ClientAuth.REQUIRED);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.startServer();
|
||||
|
||||
final String destination = server.getSecureUrl();
|
||||
JettyServerUtils.startServer(server);
|
||||
final String destination = String.format(HTTPS_URL, port);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
// Use context service with a keystore and a truststore
|
||||
useSSLContextService(twoWaySslProperties);
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.CONNECTION_TIMEOUT, "10 secs");
|
||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.URL, destination);
|
||||
|
@ -429,33 +447,32 @@ public class TestGetHTTP {
|
|||
final MockFlowFile mff = controller.getFlowFilesForRelationship(org.apache.nifi.processors.standard.GetHTTP.REL_SUCCESS).get(0);
|
||||
mff.assertContentEquals("Hello, World!");
|
||||
} finally {
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void testCookiePolicy() throws Exception {
|
||||
// set up web services
|
||||
ServletHandler handler1 = new ServletHandler();
|
||||
final int port1 = NetworkUtils.availablePort();
|
||||
final Server server1 = JettyServerUtils.createServer(port1, null, null);
|
||||
final ServletHandler handler1 = new ServletHandler();
|
||||
handler1.addServletWithMapping(CookieTestingServlet.class, "/*");
|
||||
JettyServerUtils.addHandler(server1, handler1);
|
||||
|
||||
ServletHandler handler2 = new ServletHandler();
|
||||
final int port2 = NetworkUtils.availablePort();
|
||||
final Server server2 = JettyServerUtils.createServer(port2, null, null);
|
||||
final ServletHandler handler2 = new ServletHandler();
|
||||
handler2.addServletWithMapping(CookieVerificationTestingServlet.class, "/*");
|
||||
|
||||
// create the services
|
||||
TestServer server1 = new TestServer();
|
||||
server1.addHandler(handler1);
|
||||
|
||||
TestServer server2 = new TestServer();
|
||||
server2.addHandler(handler2);
|
||||
JettyServerUtils.addHandler(server2, handler2);
|
||||
|
||||
try {
|
||||
server1.startServer();
|
||||
server2.startServer();
|
||||
JettyServerUtils.startServer(server1);
|
||||
JettyServerUtils.startServer(server2);
|
||||
|
||||
// this is the base urls with the random ports
|
||||
String destination1 = server1.getUrl();
|
||||
String destination2 = server2.getUrl();
|
||||
String destination1 = String.format(HTTP_URL, port1);
|
||||
String destination2 = String.format(HTTP_URL, port2);
|
||||
|
||||
// set up NiFi mock controller
|
||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||
|
@ -498,38 +515,19 @@ public class TestGetHTTP {
|
|||
|
||||
} finally {
|
||||
// shutdown web services
|
||||
server1.shutdownServer();
|
||||
server2.shutdownServer();
|
||||
server1.stop();
|
||||
server1.destroy();
|
||||
server2.stop();
|
||||
server2.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String> getTruststoreProperties() {
|
||||
final Map<String, String> props = new HashMap<>();
|
||||
props.put(StandardSSLContextService.TRUSTSTORE.getName(), "src/test/resources/truststore.jks");
|
||||
props.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), "passwordpassword");
|
||||
props.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), "JKS");
|
||||
return props;
|
||||
private void enableSslContextService(final SSLContext configuredSslContext) throws InitializationException {
|
||||
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_IDENTIFIER);
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(configuredSslContext);
|
||||
controller.addControllerService(SSL_CONTEXT_IDENTIFIER, sslContextService);
|
||||
controller.enableControllerService(sslContextService);
|
||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.SSL_CONTEXT_SERVICE, SSL_CONTEXT_IDENTIFIER);
|
||||
}
|
||||
|
||||
private static Map<String, String> getKeystoreProperties() {
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
properties.put(StandardSSLContextService.KEYSTORE.getName(), "src/test/resources/keystore.jks");
|
||||
properties.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), "passwordpassword");
|
||||
properties.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), "JKS");
|
||||
return properties;
|
||||
}
|
||||
|
||||
private void useSSLContextService(final Map<String, String> sslProperties) {
|
||||
final SSLContextService service = new StandardSSLContextService();
|
||||
try {
|
||||
controller.addControllerService("ssl-service", service, sslProperties);
|
||||
controller.enableControllerService(service);
|
||||
} catch (InitializationException ex) {
|
||||
ex.printStackTrace();
|
||||
Assert.fail("Could not create SSL Context Service");
|
||||
}
|
||||
|
||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.SSL_CONTEXT_SERVICE, "ssl-service");
|
||||
}
|
||||
|
||||
}
|
|
@ -21,28 +21,34 @@ import java.nio.charset.StandardCharsets;
|
|||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
/**
|
||||
* Tests PutSyslog sending messages to ListenSyslog to simulate a syslog server forwarding
|
||||
* to ListenSyslog, or PutSyslog sending to a syslog server.
|
||||
*/
|
||||
public class ITListenAndPutSyslog {
|
||||
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(ITListenAndPutSyslog.class);
|
||||
private static final String SSL_SERVICE_IDENTIFIER = SSLContextService.class.getName();
|
||||
|
||||
// TODO: The NiFi SSL classes don't yet support TLSv1.3, so set the CS version explicitly
|
||||
private static final String TLS_PROTOCOL_VERSION = "TLSv1.2";
|
||||
private static SSLContext keyStoreSslContext;
|
||||
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(ITListenAndPutSyslog.class);
|
||||
|
||||
private ListenSyslog listenSyslog;
|
||||
private TestRunner listenSyslogRunner;
|
||||
|
@ -50,6 +56,11 @@ public class ITListenAndPutSyslog {
|
|||
private PutSyslog putSyslog;
|
||||
private TestRunner putSyslogRunner;
|
||||
|
||||
@BeforeClass
|
||||
public static void configureServices() throws TlsException {
|
||||
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.listenSyslog = new ListenSyslog();
|
||||
|
@ -86,10 +97,10 @@ public class ITListenAndPutSyslog {
|
|||
@Test
|
||||
public void testTLS() throws InitializationException, IOException, InterruptedException {
|
||||
configureSSLContextService(listenSyslogRunner);
|
||||
listenSyslogRunner.setProperty(ListenSyslog.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
listenSyslogRunner.setProperty(ListenSyslog.SSL_CONTEXT_SERVICE, SSL_SERVICE_IDENTIFIER);
|
||||
|
||||
configureSSLContextService(putSyslogRunner);
|
||||
putSyslogRunner.setProperty(PutSyslog.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
putSyslogRunner.setProperty(PutSyslog.SSL_CONTEXT_SERVICE, SSL_SERVICE_IDENTIFIER);
|
||||
|
||||
run(ListenSyslog.TCP_VALUE.getValue(), 7, 7);
|
||||
}
|
||||
|
@ -97,24 +108,19 @@ public class ITListenAndPutSyslog {
|
|||
@Test
|
||||
public void testTLSListenerNoTLSPut() throws InitializationException, IOException, InterruptedException {
|
||||
configureSSLContextService(listenSyslogRunner);
|
||||
listenSyslogRunner.setProperty(ListenSyslog.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
listenSyslogRunner.setProperty(ListenSyslog.SSL_CONTEXT_SERVICE, SSL_SERVICE_IDENTIFIER);
|
||||
|
||||
// send 7 but expect 0 because sender didn't use TLS
|
||||
run(ListenSyslog.TCP_VALUE.getValue(), 7, 0);
|
||||
}
|
||||
|
||||
private SSLContextService configureSSLContextService(TestRunner runner) throws InitializationException {
|
||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, "src/test/resources/truststore.jks");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, "passwordpassword");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, "JKS");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, "src/test/resources/keystore.jks");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, "passwordpassword");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_TYPE, "JKS");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.SSL_ALGORITHM, TLS_PROTOCOL_VERSION);
|
||||
private void configureSSLContextService(TestRunner runner) throws InitializationException {
|
||||
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_SERVICE_IDENTIFIER);
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(keyStoreSslContext);
|
||||
|
||||
runner.addControllerService(SSL_SERVICE_IDENTIFIER, sslContextService);
|
||||
runner.enableControllerService(sslContextService);
|
||||
return sslContextService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.junit.Assert.fail;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -30,133 +31,115 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
||||
import org.apache.nifi.remote.io.socket.NetworkUtils;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.security.util.ClientAuth;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.util.FlowFileUnpackagerV3;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.apache.nifi.web.util.TestServer;
|
||||
import org.apache.nifi.web.util.JettyServerUtils;
|
||||
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
/**
|
||||
* Integration Test for deprecated PostHTTP Processor
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TestPostHTTP {
|
||||
private TestServer server;
|
||||
public class ITPostHTTP {
|
||||
private Server server;
|
||||
private TestRunner runner;
|
||||
private CaptureServlet servlet;
|
||||
|
||||
private final String KEYSTORE_PATH = "src/test/resources/keystore.jks";
|
||||
private final String KEYSTORE_AND_TRUSTSTORE_PASSWORD = "passwordpassword";
|
||||
private final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks";
|
||||
private final String JKS_TYPE = "JKS";
|
||||
private static final String SSL_CONTEXT_IDENTIFIER = SSLContextService.class.getName();
|
||||
|
||||
private static final String TEST_MESSAGE = String.class.getName();
|
||||
|
||||
private static SSLContext keyStoreSslContext;
|
||||
|
||||
private static SSLContext trustStoreSslContext;
|
||||
|
||||
@BeforeClass
|
||||
public static void configureServices() throws TlsException {
|
||||
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||
}
|
||||
|
||||
private static String getUrl(final SSLContext sslContext, final int port) {
|
||||
final String protocol = sslContext == null ? "http" : "https";
|
||||
return String.format("%s://localhost:%d", protocol, port);
|
||||
}
|
||||
|
||||
private void setup(final SSLContext serverSslContext, final ClientAuth clientAuth) throws Exception {
|
||||
runner = TestRunners.newTestRunner(org.apache.nifi.processors.standard.PostHTTP.class);
|
||||
final int port = NetworkUtils.availablePort();
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, getUrl(serverSslContext, port));
|
||||
|
||||
private void setup(final Map<String, String> sslProperties) throws Exception {
|
||||
// set up web service
|
||||
ServletHandler handler = new ServletHandler();
|
||||
handler.addServletWithMapping(CaptureServlet.class, "/*");
|
||||
|
||||
// create the service
|
||||
server = new TestServer(sslProperties);
|
||||
server.addHandler(handler);
|
||||
server.startServer();
|
||||
final Server configuredServer = JettyServerUtils.createServer(port, serverSslContext, clientAuth);
|
||||
configuredServer.setHandler(handler);
|
||||
final ServerConnector connector = new ServerConnector(configuredServer);
|
||||
connector.setPort(port);
|
||||
|
||||
JettyServerUtils.startServer(configuredServer);
|
||||
|
||||
servlet = (CaptureServlet) handler.getServlets()[0].getServlet();
|
||||
runner = TestRunners.newTestRunner(org.apache.nifi.processors.standard.PostHTTP.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() throws Exception {
|
||||
if (server != null) {
|
||||
server.shutdownServer();
|
||||
server.stop();
|
||||
server.destroy();
|
||||
server = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTruststoreSSLOnly() throws Exception {
|
||||
final Map<String, String> sslProps = new HashMap<>();
|
||||
sslProps.put(TestServer.NEED_CLIENT_AUTH, "false");
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE_PATH);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), JKS_TYPE);
|
||||
setup(sslProps);
|
||||
public void testUnauthenticatedTls() throws Exception {
|
||||
setup(keyStoreSslContext, ClientAuth.NONE);
|
||||
enableSslContextService(trustStoreSslContext);
|
||||
|
||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE_PATH);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, JKS_TYPE);
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getSecureUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
|
||||
runner.enqueue("Hello world".getBytes());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||
runner.enqueue(TEST_MESSAGE);
|
||||
runner.run();
|
||||
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoWaySSL() throws Exception {
|
||||
final Map<String, String> sslProps = new HashMap<>();
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE_PATH);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), JKS_TYPE);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE.getName(), TRUSTSTORE_PATH);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), JKS_TYPE);
|
||||
sslProps.put(TestServer.NEED_CLIENT_AUTH, "true");
|
||||
setup(sslProps);
|
||||
public void testMutualTls() throws Exception {
|
||||
setup(keyStoreSslContext, ClientAuth.REQUIRED);
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE_PATH);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, JKS_TYPE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, KEYSTORE_PATH);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_TYPE, JKS_TYPE);
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getSecureUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
|
||||
runner.enqueue("Hello world".getBytes());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||
runner.enqueue(TEST_MESSAGE);
|
||||
runner.run();
|
||||
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneWaySSLWhenServerConfiguredForTwoWay() throws Exception {
|
||||
final Map<String, String> sslProps = new HashMap<>();
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE_PATH);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), JKS_TYPE);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE.getName(), TRUSTSTORE_PATH);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), JKS_TYPE);
|
||||
sslProps.put(TestServer.NEED_CLIENT_AUTH, "true");
|
||||
setup(sslProps);
|
||||
public void testMutualTlsClientCertificateMissing() throws Exception {
|
||||
setup(keyStoreSslContext, ClientAuth.REQUIRED);
|
||||
enableSslContextService(trustStoreSslContext);
|
||||
|
||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, "src/test/resources/truststore.jks");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, "passwordpassword");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, JKS_TYPE);
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getSecureUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
|
||||
runner.enqueue("Hello world".getBytes());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||
runner.enqueue(TEST_MESSAGE);
|
||||
runner.run();
|
||||
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_FAILURE, 1);
|
||||
|
@ -164,14 +147,14 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendAsFlowFile() throws Exception {
|
||||
setup(null);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
setup( null, null);
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SEND_AS_FLOWFILE, "true");
|
||||
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
attrs.put("abc", "cba");
|
||||
|
||||
runner.enqueue("Hello".getBytes(), attrs);
|
||||
runner.enqueue(TEST_MESSAGE, attrs);
|
||||
attrs.put("abc", "abc");
|
||||
attrs.put("filename", "xyz.txt");
|
||||
runner.enqueue("World".getBytes(), attrs);
|
||||
|
@ -188,7 +171,7 @@ public class TestPostHTTP {
|
|||
// unpack first flowfile received
|
||||
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
||||
byte[] contentReceived = baos.toByteArray();
|
||||
assertEquals("Hello", new String(contentReceived));
|
||||
assertEquals(TEST_MESSAGE, new String(contentReceived));
|
||||
assertEquals("cba", receivedAttrs.get("abc"));
|
||||
|
||||
assertTrue(unpacker.hasMoreData());
|
||||
|
@ -204,35 +187,16 @@ public class TestPostHTTP {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSendAsFlowFileSecure() throws Exception {
|
||||
final Map<String, String> sslProps = new HashMap<>();
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE_PATH);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
sslProps.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), JKS_TYPE);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE.getName(), TRUSTSTORE_PATH);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
sslProps.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), JKS_TYPE);
|
||||
sslProps.put(TestServer.NEED_CLIENT_AUTH, "true");
|
||||
setup(sslProps);
|
||||
public void testMutualTlsSendFlowFile() throws Exception {
|
||||
setup(keyStoreSslContext, ClientAuth.REQUIRED);
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE_PATH);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, JKS_TYPE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, KEYSTORE_PATH);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, KEYSTORE_AND_TRUSTSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_TYPE, JKS_TYPE);
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getSecureUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SEND_AS_FLOWFILE, "true");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
attrs.put("abc", "cba");
|
||||
|
||||
runner.enqueue("Hello".getBytes(), attrs);
|
||||
runner.enqueue(TEST_MESSAGE, attrs);
|
||||
attrs.put("abc", "abc");
|
||||
attrs.put("filename", "xyz.txt");
|
||||
runner.enqueue("World".getBytes(), attrs);
|
||||
|
@ -249,7 +213,7 @@ public class TestPostHTTP {
|
|||
// unpack first flowfile received
|
||||
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
||||
byte[] contentReceived = baos.toByteArray();
|
||||
assertEquals("Hello", new String(contentReceived));
|
||||
assertEquals(TEST_MESSAGE, new String(contentReceived));
|
||||
assertEquals("cba", receivedAttrs.get("abc"));
|
||||
|
||||
assertTrue(unpacker.hasMoreData());
|
||||
|
@ -265,15 +229,14 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendWithMimeType() throws Exception {
|
||||
setup(null);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
setup(null, null);
|
||||
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
|
||||
final String suppliedMimeType = "text/plain";
|
||||
attrs.put(CoreAttributes.MIME_TYPE.key(), suppliedMimeType);
|
||||
runner.enqueue("Camping is great!".getBytes(), attrs);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||
|
||||
runner.run(1);
|
||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS);
|
||||
|
@ -285,9 +248,9 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendWithEmptyELExpression() throws Exception {
|
||||
setup(null);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
setup( null, null);
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
attrs.put(CoreAttributes.MIME_TYPE.key(), "");
|
||||
|
@ -302,12 +265,11 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendWithContentTypeProperty() throws Exception {
|
||||
setup(null);
|
||||
setup(null, null);
|
||||
|
||||
final String suppliedMimeType = "text/plain";
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CONTENT_TYPE, suppliedMimeType);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
attrs.put(CoreAttributes.MIME_TYPE.key(), "text/csv");
|
||||
|
@ -322,10 +284,9 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendWithCompressionServerAcceptGzip() throws Exception {
|
||||
setup(null);
|
||||
setup(null, null);
|
||||
|
||||
final String suppliedMimeType = "text/plain";
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CONTENT_TYPE, suppliedMimeType);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "9");
|
||||
|
||||
|
@ -346,10 +307,9 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendWithoutCompressionServerAcceptGzip() throws Exception {
|
||||
setup(null);
|
||||
setup(null, null);
|
||||
|
||||
final String suppliedMimeType = "text/plain";
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CONTENT_TYPE, suppliedMimeType);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "0");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
|
@ -371,11 +331,14 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendWithCompressionServerNotAcceptGzip() throws Exception {
|
||||
setup(null);
|
||||
setup(null, null);
|
||||
|
||||
final String suppliedMimeType = "text/plain";
|
||||
// Specify a property to the URL to have the CaptureServlet specify it doesn't accept gzip
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl()+"?acceptGzip=false");
|
||||
|
||||
final String serverUrl = runner.getProcessContext().getProperty(PostHTTP.URL).getValue();
|
||||
final String url = String.format("%s?acceptGzip=false", serverUrl);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, url);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CONTENT_TYPE, suppliedMimeType);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "9");
|
||||
|
||||
|
@ -395,12 +358,11 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendChunked() throws Exception {
|
||||
setup(null);
|
||||
setup(null, null);
|
||||
|
||||
final String suppliedMimeType = "text/plain";
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CONTENT_TYPE, suppliedMimeType);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "true");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.TRUE.toString());
|
||||
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
attrs.put(CoreAttributes.MIME_TYPE.key(), "text/plain");
|
||||
|
@ -421,10 +383,9 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testSendWithThrottler() throws Exception {
|
||||
setup(null);
|
||||
setup(null, null);
|
||||
|
||||
final String suppliedMimeType = "text/plain";
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CONTENT_TYPE, suppliedMimeType);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.MAX_DATA_RATE, "10kb");
|
||||
|
@ -448,31 +409,28 @@ public class TestPostHTTP {
|
|||
|
||||
@Test
|
||||
public void testDefaultUserAgent() throws Exception {
|
||||
setup(null);
|
||||
setup(null, null);
|
||||
Assert.assertTrue(runner.getProcessContext().getProperty(org.apache.nifi.processors.standard.PostHTTP.USER_AGENT).getValue().startsWith("Apache-HttpClient"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBatchWithMultipleUrls() throws Exception {
|
||||
CaptureServlet servletA, servletB;
|
||||
TestServer serverA, serverB;
|
||||
setup(null,null);
|
||||
final CaptureServlet servletA = servlet;
|
||||
final String urlA = runner.getProcessContext().getProperty(org.apache.nifi.processors.standard.PostHTTP.URL).getValue();
|
||||
|
||||
{ // setup test servers
|
||||
setup(null);
|
||||
servletA = servlet;
|
||||
serverA = server;
|
||||
// set up second web service
|
||||
ServletHandler handler = new ServletHandler();
|
||||
handler.addServletWithMapping(CaptureServlet.class, "/*");
|
||||
|
||||
// set up second web service
|
||||
ServletHandler handler = new ServletHandler();
|
||||
handler.addServletWithMapping(CaptureServlet.class, "/*");
|
||||
// create the second service
|
||||
final int portB = NetworkUtils.availablePort();
|
||||
final String urlB = getUrl(null, portB);
|
||||
final Server serverB = JettyServerUtils.createServer(portB, null, null);
|
||||
serverB.setHandler(handler);
|
||||
JettyServerUtils.startServer(serverB);
|
||||
|
||||
// create the second service
|
||||
serverB = new TestServer(null);
|
||||
serverB.addHandler(handler);
|
||||
serverB.startServer();
|
||||
|
||||
servletB = (CaptureServlet) handler.getServlets()[0].getServlet();
|
||||
}
|
||||
final CaptureServlet servletB = (CaptureServlet) handler.getServlets()[0].getServlet();
|
||||
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, "${url}"); // use EL for the URL
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SEND_AS_FLOWFILE, "true");
|
||||
|
@ -486,8 +444,8 @@ public class TestPostHTTP {
|
|||
|
||||
// enqueue 9 FlowFiles
|
||||
for (int i = 0; i < 9; i++) {
|
||||
enqueueWithURL("a" + i, serverA.getUrl());
|
||||
enqueueWithURL("b" + i, serverB.getUrl());
|
||||
enqueueWithURL("a" + i, urlA);
|
||||
enqueueWithURL("b" + i, urlB);
|
||||
|
||||
expectedContentA.add("a" + i);
|
||||
expectedContentB.add("b" + i);
|
||||
|
@ -503,10 +461,10 @@ public class TestPostHTTP {
|
|||
MockFlowFile mff = successFiles.get(0);
|
||||
final String urlAttr = mff.getAttribute("url");
|
||||
|
||||
if (serverA.getUrl().equals(urlAttr)) {
|
||||
checkBatch(serverA, servletA, actualContentA, (actualContentA.isEmpty() ? 5 : 4));
|
||||
} else if (serverB.getUrl().equals(urlAttr)) {
|
||||
checkBatch(serverB, servletB, actualContentB, (actualContentB.isEmpty() ? 5 : 4));
|
||||
if (urlA.equals(urlAttr)) {
|
||||
checkBatch(urlA, servletA, actualContentA, (actualContentA.isEmpty() ? 5 : 4));
|
||||
} else if (urlB.equals(urlAttr)) {
|
||||
checkBatch(urlB, servletB, actualContentB, (actualContentB.isEmpty() ? 5 : 4));
|
||||
} else {
|
||||
fail("unexpected url attribute");
|
||||
}
|
||||
|
@ -526,7 +484,7 @@ public class TestPostHTTP {
|
|||
runner.enqueue(data.getBytes(), attrs);
|
||||
}
|
||||
|
||||
private void checkBatch(TestServer server, CaptureServlet servlet, Set<String> actualContent, int expectedCount) throws Exception {
|
||||
private void checkBatch(final String url, CaptureServlet servlet, Set<String> actualContent, int expectedCount) throws Exception {
|
||||
FlowFileUnpackagerV3 unpacker = new FlowFileUnpackagerV3();
|
||||
Set<String> actualFFContent = new HashSet<>();
|
||||
Set<String> actualPostContent = new HashSet<>();
|
||||
|
@ -538,7 +496,7 @@ public class TestPostHTTP {
|
|||
final List<MockFlowFile> successFlowFiles = runner.getFlowFilesForRelationship(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS);
|
||||
for (int i = 0; i < expectedCount; i++) {
|
||||
MockFlowFile mff = successFlowFiles.get(i);
|
||||
mff.assertAttributeEquals("url", server.getUrl());
|
||||
mff.assertAttributeEquals("url", url);
|
||||
String content = new String(mff.toByteArray());
|
||||
actualFFContent.add(content);
|
||||
}
|
||||
|
@ -549,9 +507,10 @@ public class TestPostHTTP {
|
|||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
for (int i = 0; i < expectedCount; i++) {
|
||||
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
||||
String receivedContent = new String(baos.toByteArray());
|
||||
final byte[] bytesReceived = baos.toByteArray();
|
||||
String receivedContent = new String(bytesReceived, StandardCharsets.UTF_8);
|
||||
actualPostContent.add(receivedContent);
|
||||
assertEquals(server.getUrl(), receivedAttrs.get("url"));
|
||||
assertEquals(url, receivedAttrs.get("url"));
|
||||
assertTrue(unpacker.hasMoreData() || i == (expectedCount - 1));
|
||||
baos.reset();
|
||||
}
|
||||
|
@ -560,8 +519,17 @@ public class TestPostHTTP {
|
|||
// confirm that the transferred and POSTed content match
|
||||
assertEquals(actualFFContent, actualPostContent);
|
||||
|
||||
// accumulate actial content
|
||||
// accumulate actual content
|
||||
actualContent.addAll(actualPostContent);
|
||||
runner.clearTransferState();
|
||||
}
|
||||
|
||||
private void enableSslContextService(final SSLContext configuredSslContext) throws InitializationException {
|
||||
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_IDENTIFIER);
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(configuredSslContext);
|
||||
runner.addControllerService(SSL_CONTEXT_IDENTIFIER, sslContextService);
|
||||
runner.enableControllerService(sslContextService);
|
||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SSL_CONTEXT_SERVICE, SSL_CONTEXT_IDENTIFIER);
|
||||
}
|
||||
}
|
|
@ -25,9 +25,7 @@ import java.io.InputStream;
|
|||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
@ -60,72 +58,36 @@ import org.apache.nifi.http.HttpContextMap;
|
|||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.StandardTlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsConfiguration;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardRestrictedSSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class ITestHandleHttpRequest {
|
||||
|
||||
private static final String KEYSTORE = "src/test/resources/keystore.jks";
|
||||
private static final String KEYSTORE_PASSWORD = "passwordpassword";
|
||||
private static final String KEYSTORE_TYPE = "JKS";
|
||||
private static final String TRUSTSTORE = "src/test/resources/truststore.jks";
|
||||
private static final String TRUSTSTORE_PASSWORD = "passwordpassword";
|
||||
private static final String TRUSTSTORE_TYPE = "JKS";
|
||||
private static final String CLIENT_KEYSTORE = "src/test/resources/client-keystore.p12";
|
||||
private static final String CLIENT_KEYSTORE_TYPE = "PKCS12";
|
||||
|
||||
private HandleHttpRequest processor;
|
||||
|
||||
private TlsConfiguration clientTlsConfiguration;
|
||||
private TlsConfiguration trustOnlyTlsConfiguration;
|
||||
private static SSLContext keyStoreSslContext;
|
||||
|
||||
private static Map<String, String> getTruststoreProperties() {
|
||||
final Map<String, String> props = new HashMap<>();
|
||||
props.put(StandardSSLContextService.TRUSTSTORE.getName(), TRUSTSTORE);
|
||||
props.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), TRUSTSTORE_PASSWORD);
|
||||
props.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), TRUSTSTORE_TYPE);
|
||||
return props;
|
||||
}
|
||||
private static SSLContext trustStoreSslContext;
|
||||
|
||||
private static Map<String, String> getServerKeystoreProperties() {
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
properties.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE);
|
||||
properties.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), KEYSTORE_PASSWORD);
|
||||
properties.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), KEYSTORE_TYPE);
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static SSLContext useSSLContextService(final TestRunner controller, final Map<String, String> sslProperties) {
|
||||
final SSLContextService service = new StandardRestrictedSSLContextService();
|
||||
try {
|
||||
controller.addControllerService("ssl-service", service, sslProperties);
|
||||
controller.enableControllerService(service);
|
||||
} catch (InitializationException ex) {
|
||||
ex.printStackTrace();
|
||||
Assert.fail("Could not create SSL Context Service");
|
||||
}
|
||||
|
||||
controller.setProperty(HandleHttpRequest.SSL_CONTEXT, "ssl-service");
|
||||
return service.createContext();
|
||||
@BeforeClass
|
||||
public static void configureServices() throws TlsException {
|
||||
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
clientTlsConfiguration = new StandardTlsConfiguration(CLIENT_KEYSTORE, KEYSTORE_PASSWORD, null, CLIENT_KEYSTORE_TYPE,
|
||||
TRUSTSTORE, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion());
|
||||
trustOnlyTlsConfiguration = new StandardTlsConfiguration(null, null, null, null,
|
||||
TRUSTSTORE, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion());
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -136,7 +98,7 @@ public class ITestHandleHttpRequest {
|
|||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testRequestAddedToService() throws InitializationException, IOException, InterruptedException {
|
||||
public void testRequestAddedToService() throws InitializationException {
|
||||
CountDownLatch serverReady = new CountDownLatch(1);
|
||||
CountDownLatch requestSent = new CountDownLatch(1);
|
||||
|
||||
|
@ -191,7 +153,7 @@ public class ITestHandleHttpRequest {
|
|||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testMultipartFormDataRequest() throws InitializationException, IOException, InterruptedException {
|
||||
public void testMultipartFormDataRequest() throws InitializationException {
|
||||
CountDownLatch serverReady = new CountDownLatch(1);
|
||||
CountDownLatch requestSent = new CountDownLatch(1);
|
||||
|
||||
|
@ -304,8 +266,7 @@ public class ITestHandleHttpRequest {
|
|||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testMultipartFormDataRequestCaptureFormAttributes() throws InitializationException, IOException,
|
||||
InterruptedException {
|
||||
public void testMultipartFormDataRequestCaptureFormAttributes() throws InitializationException {
|
||||
CountDownLatch serverReady = new CountDownLatch(1);
|
||||
CountDownLatch requestSent = new CountDownLatch(1);
|
||||
|
||||
|
@ -374,7 +335,7 @@ public class ITestHandleHttpRequest {
|
|||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testMultipartFormDataRequestFailToRegisterContext() throws InitializationException, IOException, InterruptedException {
|
||||
public void testMultipartFormDataRequestFailToRegisterContext() throws InitializationException, InterruptedException {
|
||||
CountDownLatch serverReady = new CountDownLatch(1);
|
||||
CountDownLatch requestSent = new CountDownLatch(1);
|
||||
CountDownLatch resultReady = new CountDownLatch(1);
|
||||
|
@ -427,7 +388,7 @@ public class ITestHandleHttpRequest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
public void onResponse(Call call, Response response) {
|
||||
responseCode.set(response.code());
|
||||
resultReady.countDown();
|
||||
}
|
||||
|
@ -473,7 +434,7 @@ public class ITestHandleHttpRequest {
|
|||
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testFailToRegister() throws InitializationException, IOException, InterruptedException {
|
||||
public void testFailToRegister() throws InitializationException, InterruptedException {
|
||||
CountDownLatch serverReady = new CountDownLatch(1);
|
||||
CountDownLatch requestSent = new CountDownLatch(1);
|
||||
CountDownLatch resultReady = new CountDownLatch(1);
|
||||
|
@ -649,10 +610,13 @@ public class ITestHandleHttpRequest {
|
|||
runner.enableControllerService(contextMap);
|
||||
runner.setProperty(HandleHttpRequest.HTTP_CONTEXT_MAP, "http-context-map");
|
||||
|
||||
final Map<String, String> sslProperties = getServerKeystoreProperties();
|
||||
sslProperties.putAll(getTruststoreProperties());
|
||||
sslProperties.put(StandardSSLContextService.SSL_ALGORITHM.getName(), TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion());
|
||||
useSSLContextService(runner, sslProperties);
|
||||
final RestrictedSSLContextService sslContextService = Mockito.mock(RestrictedSSLContextService.class);
|
||||
final String serviceIdentifier = RestrictedSSLContextService.class.getName();
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(keyStoreSslContext);
|
||||
runner.addControllerService(serviceIdentifier, sslContextService);
|
||||
runner.enableControllerService(sslContextService);
|
||||
runner.setProperty(HandleHttpRequest.SSL_CONTEXT, serviceIdentifier);
|
||||
|
||||
final Thread httpThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
|
@ -667,10 +631,10 @@ public class ITestHandleHttpRequest {
|
|||
SSLContext clientSslContext;
|
||||
if (twoWaySsl) {
|
||||
// Use a client certificate, do not reuse the server's keystore
|
||||
clientSslContext = SslContextFactory.createSslContext(clientTlsConfiguration);
|
||||
clientSslContext = keyStoreSslContext;
|
||||
} else {
|
||||
// With one-way SSL, the client still needs a truststore
|
||||
clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
||||
clientSslContext = trustStoreSslContext;
|
||||
}
|
||||
connection.setSSLSocketFactory(clientSslContext.getSocketFactory());
|
||||
connection.setDoOutput(false);
|
||||
|
|
|
@ -27,12 +27,15 @@ import java.io.PrintWriter;
|
|||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.nifi.processors.standard.util.TestInvokeHttpCommon;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.security.util.KeystoreType;
|
||||
import org.apache.nifi.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.StandardTlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsConfiguration;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
@ -41,12 +44,29 @@ import org.junit.Assert;
|
|||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TestInvokeHTTP extends TestInvokeHttpCommon {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TestInvokeHTTP.class);
|
||||
|
||||
private static final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks";
|
||||
private static final String TRUSTSTORE_PASSWORD = "passwordpassword";
|
||||
private static final KeystoreType TRUSTSTORE_TYPE = KeystoreType.JKS;
|
||||
private static final String KEYSTORE_PATH = "src/test/resources/keystore.jks";
|
||||
private static final String KEYSTORE_PASSWORD = "passwordpassword";
|
||||
private static final KeystoreType KEYSTORE_TYPE = KeystoreType.JKS;
|
||||
|
||||
private static final TlsConfiguration TLS_CONFIGURATION = new StandardTlsConfiguration(
|
||||
KEYSTORE_PATH,
|
||||
KEYSTORE_PASSWORD,
|
||||
KEYSTORE_TYPE,
|
||||
TRUSTSTORE_PATH,
|
||||
TRUSTSTORE_PASSWORD,
|
||||
TRUSTSTORE_TYPE
|
||||
);
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
configureServer(null, null);
|
||||
|
@ -59,20 +79,18 @@ public class TestInvokeHTTP extends TestInvokeHttpCommon {
|
|||
|
||||
@Test
|
||||
public void testSslSetHttpRequest() throws Exception {
|
||||
|
||||
final Map<String, String> sslProperties = new HashMap<>();
|
||||
sslProperties.put(StandardSSLContextService.KEYSTORE.getName(), "src/test/resources/keystore.jks");
|
||||
sslProperties.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), "passwordpassword");
|
||||
sslProperties.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), "JKS");
|
||||
sslProperties.put(StandardSSLContextService.TRUSTSTORE.getName(), "src/test/resources/truststore.jks");
|
||||
sslProperties.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), "passwordpassword");
|
||||
sslProperties.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), "JKS");
|
||||
final String serviceIdentifier = SSLContextService.class.getName();
|
||||
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
|
||||
final SSLContext sslContext = SslContextFactory.createSslContext(TLS_CONFIGURATION);
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
|
||||
Mockito.when(sslContextService.createTlsConfiguration()).thenReturn(TLS_CONFIGURATION);
|
||||
|
||||
runner = TestRunners.newTestRunner(InvokeHTTP.class);
|
||||
final StandardSSLContextService sslService = new StandardSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslService, sslProperties);
|
||||
runner.enableControllerService(sslService);
|
||||
runner.setProperty(InvokeHTTP.PROP_SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
|
||||
runner.addControllerService(serviceIdentifier, sslContextService);
|
||||
runner.enableControllerService(sslContextService);
|
||||
runner.setProperty(InvokeHTTP.PROP_SSL_CONTEXT_SERVICE, serviceIdentifier);
|
||||
|
||||
addHandler(new GetOrHeadHandler());
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ import org.apache.nifi.security.util.TlsConfiguration;
|
|||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
|
@ -314,16 +313,6 @@ public class TestListenHTTP {
|
|||
testPOSTRequestsReceived(HttpServletResponse.SC_NO_CONTENT, true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecureInvalidSSLConfiguration() throws Exception {
|
||||
SSLContextService sslContextService = configureInvalidProcessorSslContextService();
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(ListenHTTP.PORT, HTTP_SERVER_PORT_EL);
|
||||
runner.setProperty(ListenHTTP.BASE_PATH, HTTP_SERVER_BASEPATH_EL);
|
||||
runner.assertNotValid();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecureServerSupportsCurrentTlsProtocolVersion() throws Exception {
|
||||
configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
|
||||
|
@ -539,22 +528,8 @@ public class TestListenHTTP {
|
|||
runner.enableControllerService(sslContextService);
|
||||
}
|
||||
|
||||
private SSLContextService configureInvalidProcessorSslContextService() throws InitializationException {
|
||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
||||
runner.addControllerService(SSL_CONTEXT_SERVICE_IDENTIFIER, sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, TRUSTSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, KeystoreType.JKS.getType());
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, KEYSTORE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, KEYSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_TYPE, KeystoreType.JKS.getType());
|
||||
|
||||
runner.setProperty(ListenHTTP.SSL_CONTEXT_SERVICE, SSL_CONTEXT_SERVICE_IDENTIFIER);
|
||||
return sslContextService;
|
||||
}
|
||||
|
||||
|
||||
@Test(/*timeout=10000*/)
|
||||
@Test
|
||||
public void testMultipartFormDataRequest() throws Exception {
|
||||
|
||||
runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
|
||||
|
|
|
@ -38,11 +38,12 @@ import org.apache.nifi.processors.standard.relp.response.RELPResponse;
|
|||
import org.apache.nifi.provenance.ProvenanceEventRecord;
|
||||
import org.apache.nifi.provenance.ProvenanceEventType;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -50,9 +51,6 @@ import org.mockito.Mockito;
|
|||
|
||||
public class TestListenRELP {
|
||||
|
||||
// TODO: The NiFi SSL classes don't yet support TLSv1.3, so set the CS version explicitly
|
||||
private static final String TLS_PROTOCOL_VERSION = "TLSv1.2";
|
||||
|
||||
public static final String OPEN_FRAME_DATA = "relp_version=0\nrelp_software=librelp,1.2.7,http://librelp.adiscon.com\ncommands=syslog";
|
||||
public static final String SYSLOG_FRAME_DATA = "this is a syslog message here";
|
||||
|
||||
|
@ -151,19 +149,16 @@ public class TestListenRELP {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTLS() throws InitializationException, IOException, InterruptedException {
|
||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.SSL_ALGORITHM, TLS_PROTOCOL_VERSION);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, "src/test/resources/truststore.jks");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, "passwordpassword");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, "JKS");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, "src/test/resources/keystore.jks");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, "passwordpassword");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_TYPE, "JKS");
|
||||
public void testMutualTls() throws IOException, InterruptedException, TlsException, InitializationException {
|
||||
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||
final String serviceIdentifier = SSLContextService.class.getName();
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
|
||||
final SSLContext sslContext = SslContextUtils.createKeyStoreSslContext();
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
|
||||
runner.addControllerService(serviceIdentifier, sslContextService);
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(ListenRELP.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
runner.setProperty(ListenRELP.SSL_CONTEXT_SERVICE, serviceIdentifier);
|
||||
|
||||
final List<RELPFrame> frames = new ArrayList<>();
|
||||
frames.add(OPEN_FRAME);
|
||||
|
@ -174,8 +169,7 @@ public class TestListenRELP {
|
|||
frames.add(SYSLOG_FRAME);
|
||||
frames.add(CLOSE_FRAME);
|
||||
|
||||
// three syslog frames should be transferred and three responses should be sent
|
||||
run(frames, 5, 5, sslContextService);
|
||||
run(frames, 5, 5, sslContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -210,7 +204,7 @@ public class TestListenRELP {
|
|||
}
|
||||
|
||||
|
||||
protected void run(final List<RELPFrame> frames, final int expectedTransferred, final int expectedResponses, final SSLContextService sslContextService)
|
||||
protected void run(final List<RELPFrame> frames, final int expectedTransferred, final int expectedResponses, final SSLContext sslContext)
|
||||
throws IOException, InterruptedException {
|
||||
|
||||
Socket socket = null;
|
||||
|
@ -224,11 +218,10 @@ public class TestListenRELP {
|
|||
final int realPort = proc.getDispatcherPort();
|
||||
|
||||
// create either a regular socket or ssl socket based on context being passed in
|
||||
if (sslContextService != null) {
|
||||
final SSLContext sslContext = sslContextService.createContext();
|
||||
socket = sslContext.getSocketFactory().createSocket("localhost", realPort);
|
||||
} else {
|
||||
if (sslContext == null) {
|
||||
socket = new Socket("localhost", realPort);
|
||||
} else {
|
||||
socket = sslContext.getSocketFactory().createSocket("localhost", realPort);
|
||||
}
|
||||
Thread.sleep(100);
|
||||
|
||||
|
|
|
@ -21,56 +21,51 @@ import java.net.Socket;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.nifi.processor.ProcessContext;
|
||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.security.util.ClientAuth;
|
||||
import org.apache.nifi.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.StandardTlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardRestrictedSSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class TestListenTCP {
|
||||
private static final long RESPONSE_TIMEOUT = 10000;
|
||||
|
||||
private static final String KEYSTORE = "src/test/resources/keystore.jks";
|
||||
private static final String KEYSTORE_PASSWORD = "passwordpassword";
|
||||
private static final String KEYSTORE_TYPE = "JKS";
|
||||
private static final String TRUSTSTORE = "src/test/resources/truststore.jks";
|
||||
private static final String TRUSTSTORE_PASSWORD = "passwordpassword";
|
||||
private static final String TRUSTSTORE_TYPE = "JKS";
|
||||
private static final String CLIENT_KEYSTORE = "src/test/resources/client-keystore.p12";
|
||||
private static final String CLIENT_KEYSTORE_TYPE = "PKCS12";
|
||||
private static final String SSL_CONTEXT_IDENTIFIER = SSLContextService.class.getName();
|
||||
|
||||
// TODO: The NiFi SSL classes don't yet support TLSv1.3, so set the CS version explicitly
|
||||
private static final String TLS_PROTOCOL_VERSION = "TLSv1.2";
|
||||
private static SSLContext keyStoreSslContext;
|
||||
|
||||
private static TlsConfiguration clientTlsConfiguration;
|
||||
private static TlsConfiguration trustOnlyTlsConfiguration;
|
||||
private static SSLContext trustStoreSslContext;
|
||||
|
||||
private ListenTCP proc;
|
||||
private TestRunner runner;
|
||||
|
||||
@BeforeClass
|
||||
public static void configureServices() throws TlsException {
|
||||
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
proc = new ListenTCP();
|
||||
runner = TestRunners.newTestRunner(proc);
|
||||
runner.setProperty(ListenTCP.PORT, "0");
|
||||
|
||||
clientTlsConfiguration = new StandardTlsConfiguration(CLIENT_KEYSTORE, KEYSTORE_PASSWORD, null, CLIENT_KEYSTORE_TYPE,
|
||||
TRUSTSTORE, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, TLS_PROTOCOL_VERSION);
|
||||
trustOnlyTlsConfiguration = new StandardTlsConfiguration(null, null, null, null,
|
||||
TRUSTSTORE, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, TLS_PROTOCOL_VERSION);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -78,7 +73,7 @@ public class TestListenTCP {
|
|||
runner.setProperty(ListenTCP.PORT, "1");
|
||||
runner.assertValid();
|
||||
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
runner.setProperty(ListenTCP.CLIENT_AUTH, "");
|
||||
runner.assertNotValid();
|
||||
|
||||
|
@ -126,11 +121,11 @@ public class TestListenTCP {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTLSClientAuthRequiredAndClientCertProvided() throws InitializationException, IOException, InterruptedException,
|
||||
TlsException {
|
||||
public void testTLSClientAuthRequiredAndClientCertProvided() throws IOException, InterruptedException,
|
||||
InitializationException {
|
||||
|
||||
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
final List<String> messages = new ArrayList<>();
|
||||
messages.add("This is message 1\n");
|
||||
|
@ -140,9 +135,7 @@ public class TestListenTCP {
|
|||
messages.add("This is message 5\n");
|
||||
|
||||
// Make an SSLContext with a key and trust store to send the test messages
|
||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(clientTlsConfiguration);
|
||||
|
||||
runTCP(messages, messages.size(), clientSslContext);
|
||||
runTCP(messages, messages.size(), keyStoreSslContext);
|
||||
|
||||
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS);
|
||||
for (int i = 0; i < mockFlowFiles.size(); i++) {
|
||||
|
@ -151,10 +144,9 @@ public class TestListenTCP {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTLSClientAuthRequiredAndClientCertNotProvided() throws InitializationException, TlsException {
|
||||
|
||||
public void testTLSClientAuthRequiredAndClientCertNotProvided() throws InitializationException {
|
||||
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
final List<String> messages = new ArrayList<>();
|
||||
messages.add("This is message 1\n");
|
||||
|
@ -164,21 +156,15 @@ public class TestListenTCP {
|
|||
messages.add("This is message 5\n");
|
||||
|
||||
// Make an SSLContext that only has the trust store, this should not work since the processor has client auth REQUIRED
|
||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
||||
|
||||
try {
|
||||
runTCP(messages, messages.size(), clientSslContext);
|
||||
Assert.fail("Should have thrown exception");
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
Assert.assertThrows(SSLException.class, () ->
|
||||
runTCP(messages, messages.size(), trustStoreSslContext)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTLSClientAuthNoneAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException, TlsException {
|
||||
|
||||
public void testTLSClientAuthNoneAndClientCertNotProvided() throws IOException, InterruptedException, InitializationException {
|
||||
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.NONE.name());
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
final List<String> messages = new ArrayList<>();
|
||||
messages.add("This is message 1\n");
|
||||
|
@ -188,9 +174,7 @@ public class TestListenTCP {
|
|||
messages.add("This is message 5\n");
|
||||
|
||||
// Make an SSLContext that only has the trust store, this should not work since the processor has client auth REQUIRED
|
||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
||||
|
||||
runTCP(messages, messages.size(), clientSslContext);
|
||||
runTCP(messages, messages.size(), trustStoreSslContext);
|
||||
|
||||
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS);
|
||||
for (int i = 0; i < mockFlowFiles.size(); i++) {
|
||||
|
@ -212,10 +196,11 @@ public class TestListenTCP {
|
|||
final int realPort = proc.getDispatcherPort();
|
||||
|
||||
// create either a regular socket or ssl socket based on context being passed in
|
||||
if (sslContext != null) {
|
||||
socket = sslContext.getSocketFactory().createSocket("localhost", realPort);
|
||||
} else {
|
||||
if (sslContext == null) {
|
||||
socket = new Socket("localhost", realPort);
|
||||
} else {
|
||||
final SocketFactory socketFactory = sslContext.getSocketFactory();
|
||||
socket = socketFactory.createSocket("localhost", realPort);
|
||||
}
|
||||
Thread.sleep(100);
|
||||
|
||||
|
@ -226,14 +211,12 @@ public class TestListenTCP {
|
|||
}
|
||||
socket.getOutputStream().flush();
|
||||
|
||||
long responseTimeout = 10000;
|
||||
|
||||
// this first loop waits until the internal queue of the processor has the expected
|
||||
// number of messages ready before proceeding, we want to guarantee they are all there
|
||||
// before onTrigger gets a chance to run
|
||||
long startTimeQueueSizeCheck = System.currentTimeMillis();
|
||||
while (proc.getQueueSize() < messages.size()
|
||||
&& (System.currentTimeMillis() - startTimeQueueSizeCheck < responseTimeout)) {
|
||||
&& (System.currentTimeMillis() - startTimeQueueSizeCheck < RESPONSE_TIMEOUT)) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
|
@ -243,7 +226,7 @@ public class TestListenTCP {
|
|||
// call onTrigger until we processed all the frames, or a certain amount of time passes
|
||||
int numTransferred = 0;
|
||||
long startTime = System.currentTimeMillis();
|
||||
while (numTransferred < expectedTransferred && (System.currentTimeMillis() - startTime < responseTimeout)) {
|
||||
while (numTransferred < expectedTransferred && (System.currentTimeMillis() - startTime < RESPONSE_TIMEOUT)) {
|
||||
proc.onTrigger(context, processSessionFactory);
|
||||
numTransferred = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS).size();
|
||||
Thread.sleep(100);
|
||||
|
@ -258,20 +241,12 @@ public class TestListenTCP {
|
|||
}
|
||||
}
|
||||
|
||||
private SSLContextService configureProcessorSslContextService() throws InitializationException {
|
||||
final SSLContextService sslContextService = new StandardRestrictedSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, KEYSTORE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, KEYSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_TYPE, KEYSTORE_TYPE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, TRUSTSTORE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, TRUSTSTORE_PASSWORD);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, TRUSTSTORE_TYPE);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.SSL_ALGORITHM, TLS_PROTOCOL_VERSION);
|
||||
private void enableSslContextService(final SSLContext sslContext) throws InitializationException {
|
||||
final RestrictedSSLContextService sslContextService = Mockito.mock(RestrictedSSLContextService.class);
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_IDENTIFIER);
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
|
||||
runner.addControllerService(SSL_CONTEXT_IDENTIFIER, sslContextService);
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(ListenTCP.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
return sslContextService;
|
||||
runner.setProperty(ListenTCP.SSL_CONTEXT_SERVICE, SSL_CONTEXT_IDENTIFIER);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,43 +31,27 @@ import org.apache.nifi.processor.ProcessSessionFactory;
|
|||
import org.apache.nifi.reporting.InitializationException;
|
||||
import org.apache.nifi.schema.access.SchemaAccessUtils;
|
||||
import org.apache.nifi.security.util.ClientAuth;
|
||||
import org.apache.nifi.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.StandardTlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.apache.nifi.serialization.RecordReaderFactory;
|
||||
import org.apache.nifi.serialization.RecordSetWriterFactory;
|
||||
import org.apache.nifi.serialization.record.MockRecordWriter;
|
||||
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||
import org.apache.nifi.ssl.SSLContextService;
|
||||
import org.apache.nifi.ssl.StandardRestrictedSSLContextService;
|
||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
||||
import org.apache.nifi.util.MockFlowFile;
|
||||
import org.apache.nifi.util.TestRunner;
|
||||
import org.apache.nifi.util.TestRunners;
|
||||
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TestListenTCPRecord {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(TestListenTCPRecord.class);
|
||||
|
||||
private static final String KEYSTORE = "src/test/resources/keystore.jks";
|
||||
private static final String KEYSTORE_PASSWORD = "passwordpassword";
|
||||
private static final String KEYSTORE_TYPE = "JKS";
|
||||
private static final String TRUSTSTORE = "src/test/resources/truststore.jks";
|
||||
private static final String TRUSTSTORE_PASSWORD = "passwordpassword";
|
||||
private static final String TRUSTSTORE_TYPE = "JKS";
|
||||
private static final String CLIENT_KEYSTORE = "src/test/resources/client-keystore.p12";
|
||||
private static final String CLIENT_KEYSTORE_TYPE = "PKCS12";
|
||||
|
||||
// TODO: The NiFi SSL classes don't yet support TLSv1.3, so set the CS version explicitly
|
||||
private static final String TLS_PROTOCOL_VERSION = "TLSv1.2";
|
||||
|
||||
private static TlsConfiguration clientTlsConfiguration;
|
||||
private static TlsConfiguration trustOnlyTlsConfiguration;
|
||||
|
||||
static final String SCHEMA_TEXT = "{\n" +
|
||||
" \"name\": \"syslogRecord\",\n" +
|
||||
" \"namespace\": \"nifi\",\n" +
|
||||
|
@ -91,9 +75,21 @@ public class TestListenTCPRecord {
|
|||
DATA = Collections.unmodifiableList(data);
|
||||
}
|
||||
|
||||
private static final String SSL_CONTEXT_IDENTIFIER = SSLContextService.class.getName();
|
||||
|
||||
private static SSLContext keyStoreSslContext;
|
||||
|
||||
private static SSLContext trustStoreSslContext;
|
||||
|
||||
private ListenTCPRecord proc;
|
||||
private TestRunner runner;
|
||||
|
||||
@BeforeClass
|
||||
public static void configureServices() throws TlsException {
|
||||
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws InitializationException {
|
||||
proc = new ListenTCPRecord();
|
||||
|
@ -115,10 +111,6 @@ public class TestListenTCPRecord {
|
|||
runner.setProperty(ListenTCPRecord.RECORD_READER, readerId);
|
||||
runner.setProperty(ListenTCPRecord.RECORD_WRITER, writerId);
|
||||
|
||||
clientTlsConfiguration = new StandardTlsConfiguration(CLIENT_KEYSTORE, KEYSTORE_PASSWORD, null, CLIENT_KEYSTORE_TYPE,
|
||||
TRUSTSTORE, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, TLS_PROTOCOL_VERSION);
|
||||
trustOnlyTlsConfiguration = new StandardTlsConfiguration(null, null, null, null,
|
||||
TRUSTSTORE, TRUSTSTORE_PASSWORD, TRUSTSTORE_TYPE, TLS_PROTOCOL_VERSION);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -126,7 +118,7 @@ public class TestListenTCPRecord {
|
|||
runner.setProperty(ListenTCPRecord.PORT, "1");
|
||||
runner.assertValid();
|
||||
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, "");
|
||||
runner.assertNotValid();
|
||||
|
||||
|
@ -171,15 +163,11 @@ public class TestListenTCPRecord {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTLSClientAuthRequiredAndClientCertProvided() throws InitializationException, IOException, InterruptedException, TlsException {
|
||||
|
||||
public void testTLSClientAuthRequiredAndClientCertProvided() throws InitializationException, IOException, InterruptedException {
|
||||
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
// Make an SSLContext with a key and trust store to send the test messages
|
||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(clientTlsConfiguration);
|
||||
|
||||
runTCP(DATA, 1, clientSslContext);
|
||||
runTCP(DATA, 1, keyStoreSslContext);
|
||||
|
||||
final List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCPRecord.REL_SUCCESS);
|
||||
Assert.assertEquals(1, mockFlowFiles.size());
|
||||
|
@ -192,28 +180,21 @@ public class TestListenTCPRecord {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testTLSClientAuthRequiredAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException, TlsException {
|
||||
|
||||
public void testTLSClientAuthRequiredAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException {
|
||||
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
||||
runner.setProperty(ListenTCPRecord.READ_TIMEOUT, "5 seconds");
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
// Make an SSLContext that only has the trust store, this should not work since the processor has client auth REQUIRED
|
||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
||||
|
||||
runTCP(DATA, 0, clientSslContext);
|
||||
runTCP(DATA, 0, trustStoreSslContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTLSClientAuthNoneAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException, TlsException {
|
||||
public void testTLSClientAuthNoneAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException {
|
||||
|
||||
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, ClientAuth.NONE.name());
|
||||
configureProcessorSslContextService();
|
||||
enableSslContextService(keyStoreSslContext);
|
||||
|
||||
// Make an SSLContext that only has the trust store, this should work since the processor has client auth NONE
|
||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
||||
|
||||
runTCP(DATA, 1, clientSslContext);
|
||||
runTCP(DATA, 1, trustStoreSslContext);
|
||||
|
||||
final List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCPRecord.REL_SUCCESS);
|
||||
Assert.assertEquals(1, mockFlowFiles.size());
|
||||
|
@ -262,21 +243,6 @@ public class TestListenTCPRecord {
|
|||
}
|
||||
}
|
||||
|
||||
private SSLContextService configureProcessorSslContextService() throws InitializationException {
|
||||
final SSLContextService sslContextService = new StandardRestrictedSSLContextService();
|
||||
runner.addControllerService("ssl-context", sslContextService);
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, "src/test/resources/truststore.jks");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, "passwordpassword");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, "JKS");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, "src/test/resources/keystore.jks");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, "passwordpassword");
|
||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_TYPE, "JKS");
|
||||
runner.enableControllerService(sslContextService);
|
||||
|
||||
runner.setProperty(ListenTCPRecord.SSL_CONTEXT_SERVICE, "ssl-context");
|
||||
return sslContextService;
|
||||
}
|
||||
|
||||
private static class SocketSender implements Runnable, Closeable {
|
||||
|
||||
private final int port;
|
||||
|
@ -324,4 +290,12 @@ public class TestListenTCPRecord {
|
|||
}
|
||||
}
|
||||
|
||||
private void enableSslContextService(final SSLContext sslContext) throws InitializationException {
|
||||
final RestrictedSSLContextService sslContextService = Mockito.mock(RestrictedSSLContextService.class);
|
||||
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_IDENTIFIER);
|
||||
Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
|
||||
runner.addControllerService(SSL_CONTEXT_IDENTIFIER, sslContextService);
|
||||
runner.enableControllerService(sslContextService);
|
||||
runner.setProperty(ListenTCPRecord.SSL_CONTEXT_SERVICE, SSL_CONTEXT_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.nifi.web.util.ssl;
|
||||
|
||||
import org.apache.nifi.security.util.KeystoreType;
|
||||
import org.apache.nifi.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.StandardTlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
public class SslContextUtils {
|
||||
private static final String KEYSTORE_PATH = "src/test/resources/keystore.jks";
|
||||
|
||||
private static final String KEYSTORE_AND_TRUSTSTORE_PASSWORD = "passwordpassword";
|
||||
|
||||
private static final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks";
|
||||
|
||||
private static final TlsConfiguration KEYSTORE_TLS_CONFIGURATION = new StandardTlsConfiguration(
|
||||
KEYSTORE_PATH,
|
||||
KEYSTORE_AND_TRUSTSTORE_PASSWORD,
|
||||
KEYSTORE_AND_TRUSTSTORE_PASSWORD,
|
||||
KeystoreType.JKS,
|
||||
TRUSTSTORE_PATH,
|
||||
KEYSTORE_AND_TRUSTSTORE_PASSWORD,
|
||||
KeystoreType.JKS,
|
||||
TlsConfiguration.TLS_1_2_PROTOCOL
|
||||
);
|
||||
|
||||
private static final TlsConfiguration TRUSTSTORE_TLS_CONFIGURATION = new StandardTlsConfiguration(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
TRUSTSTORE_PATH,
|
||||
KEYSTORE_AND_TRUSTSTORE_PASSWORD,
|
||||
KeystoreType.JKS,
|
||||
TlsConfiguration.TLS_1_2_PROTOCOL
|
||||
);
|
||||
|
||||
/**
|
||||
* Create SSLContext with Key Store and Trust Store configured
|
||||
*
|
||||
* @return SSLContext configured with Key Store and Trust Store
|
||||
* @throws TlsException Thrown on SslContextFactory.createSslContext()
|
||||
*/
|
||||
public static SSLContext createKeyStoreSslContext() throws TlsException {
|
||||
return SslContextFactory.createSslContext(KEYSTORE_TLS_CONFIGURATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create SSLContext with Trust Store configured
|
||||
*
|
||||
* @return SSLContext configured with Trust Store
|
||||
* @throws TlsException Thrown on SslContextFactory.createSslContext()
|
||||
*/
|
||||
public static SSLContext createTrustStoreSslContext() throws TlsException {
|
||||
return SslContextFactory.createSslContext(TRUSTSTORE_TLS_CONFIGURATION);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue