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_0_PROTOCOL = "TLSv1";
|
||||||
String TLS_1_1_PROTOCOL = "TLSv1.1";
|
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[] 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_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_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};
|
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.ConnectionSocketFactory;
|
||||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
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.BasicCredentialsProvider;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
|
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.DynamicProperties;
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
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.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
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.ssl.SSLContextService;
|
||||||
import org.apache.nifi.util.StopWatch;
|
import org.apache.nifi.util.StopWatch;
|
||||||
import org.apache.nifi.util.Tuple;
|
import org.apache.nifi.util.Tuple;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
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.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -326,32 +314,6 @@ public class GetHTTP extends AbstractSessionFactoryProcessor {
|
||||||
.build();
|
.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
|
@Override
|
||||||
public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) throws ProcessException {
|
public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) throws ProcessException {
|
||||||
final ComponentLog logger = getLogger();
|
final ComponentLog logger = getLogger();
|
||||||
|
@ -384,7 +346,7 @@ public class GetHTTP extends AbstractSessionFactoryProcessor {
|
||||||
} else {
|
} else {
|
||||||
final SSLContext sslContext;
|
final SSLContext sslContext;
|
||||||
try {
|
try {
|
||||||
sslContext = createSSLContext(sslContextService);
|
sslContext = sslContextService.createContext();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new ProcessException(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.base.Strings;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.servlet.AsyncContext;
|
import javax.servlet.AsyncContext;
|
||||||
import javax.servlet.DispatcherType;
|
import javax.servlet.DispatcherType;
|
||||||
import javax.servlet.MultipartConfigElement;
|
import javax.servlet.MultipartConfigElement;
|
||||||
|
@ -544,25 +545,14 @@ public class HandleHttpRequest extends AbstractProcessor {
|
||||||
return containerQueue.size();
|
return containerQueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SslContextFactory createSslFactory(final SSLContextService sslService, final boolean needClientAuth, final boolean wantClientAuth) {
|
private SslContextFactory createSslFactory(final SSLContextService sslContextService, final boolean needClientAuth, final boolean wantClientAuth) {
|
||||||
final SslContextFactory sslFactory = new SslContextFactory.Server();
|
final SslContextFactory.Server sslFactory = new SslContextFactory.Server();
|
||||||
|
|
||||||
sslFactory.setNeedClientAuth(needClientAuth);
|
sslFactory.setNeedClientAuth(needClientAuth);
|
||||||
sslFactory.setWantClientAuth(wantClientAuth);
|
sslFactory.setWantClientAuth(wantClientAuth);
|
||||||
|
|
||||||
sslFactory.setProtocol(sslService.getSslAlgorithm());
|
final SSLContext sslContext = sslContextService.createContext();
|
||||||
|
sslFactory.setSslContext(sslContext);
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
return sslFactory;
|
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_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_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.")})
|
@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 class HandleHttpResponse extends AbstractProcessor {
|
||||||
|
|
||||||
public static final PropertyDescriptor STATUS_CODE = new PropertyDescriptor.Builder()
|
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/\" "
|
+ "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).")
|
+ "(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 class ListenFTP extends AbstractSessionFactoryProcessor {
|
||||||
|
|
||||||
public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
|
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.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -30,11 +28,6 @@ import java.net.InetAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.security.Principal;
|
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.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
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.ConnectionSocketFactory;
|
||||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
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.ContentProducer;
|
||||||
import org.apache.http.entity.EntityTemplate;
|
import org.apache.http.entity.EntityTemplate;
|
||||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
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.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
import org.apache.http.protocol.HttpContext;
|
import org.apache.http.protocol.HttpContext;
|
||||||
import org.apache.http.protocol.HttpCoreContext;
|
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.EntityUtils;
|
||||||
import org.apache.http.util.VersionInfo;
|
import org.apache.http.util.VersionInfo;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
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.processor.util.StandardValidators;
|
||||||
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
||||||
import org.apache.nifi.security.util.CertificateUtils;
|
import org.apache.nifi.security.util.CertificateUtils;
|
||||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
import org.apache.nifi.ssl.SSLContextService;
|
||||||
import org.apache.nifi.stream.io.GZIPOutputStream;
|
import org.apache.nifi.stream.io.GZIPOutputStream;
|
||||||
import org.apache.nifi.stream.io.LeakyBucketStreamThrottler;
|
import org.apache.nifi.stream.io.LeakyBucketStreamThrottler;
|
||||||
|
@ -389,8 +378,7 @@ public class PostHTTP extends AbstractProcessor {
|
||||||
} else {
|
} else {
|
||||||
final SSLContext sslContext;
|
final SSLContext sslContext;
|
||||||
try {
|
try {
|
||||||
sslContext = createSSLContext(sslContextService);
|
sslContext = sslContextService.createContext();
|
||||||
getLogger().info("PostHTTP supports protocol: " + sslContext.getProtocol());
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new ProcessException(e);
|
throw new ProcessException(e);
|
||||||
}
|
}
|
||||||
|
@ -509,38 +497,6 @@ public class PostHTTP extends AbstractProcessor {
|
||||||
return url.substring(0, index);
|
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
|
@Override
|
||||||
public void onTrigger(final ProcessContext context, final ProcessSession session) {
|
public void onTrigger(final ProcessContext context, final ProcessSession session) {
|
||||||
FlowFile firstFlowFile = session.get();
|
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 static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.HashMap;
|
import javax.net.ssl.SSLContext;
|
||||||
import java.util.Map;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.apache.nifi.components.state.Scope;
|
import org.apache.nifi.components.state.Scope;
|
||||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
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.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.SSLContextService;
|
||||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
|
||||||
import org.apache.nifi.util.MockFlowFile;
|
import org.apache.nifi.util.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
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.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Integration Test for deprecated GetHTTP Processor
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@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;
|
private TestRunner controller;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void before() {
|
public static void configureServices() throws TlsException {
|
||||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
|
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info");
|
||||||
System.setProperty("org.slf4j.simpleLogger.showDateTime", "true");
|
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.GetHTTP", "debug");
|
||||||
System.setProperty("org.slf4j.simpleLogger.log.nifi.processors.standard.TestGetHTTP", "debug");
|
System.setProperty("org.slf4j.simpleLogger.log.nifi.processors.standard.TestGetHTTP", "debug");
|
||||||
|
|
||||||
|
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||||
|
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -60,14 +75,15 @@ public class TestGetHTTP {
|
||||||
handler.addServletWithMapping(RESTServiceContentModified.class, "/*");
|
handler.addServletWithMapping(RESTServiceContentModified.class, "/*");
|
||||||
|
|
||||||
// create the service
|
// create the service
|
||||||
TestServer server = new TestServer();
|
final int port = NetworkUtils.availablePort();
|
||||||
server.addHandler(handler);
|
final Server server = JettyServerUtils.createServer(port, null, null);
|
||||||
|
server.setHandler(handler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server.startServer();
|
JettyServerUtils.startServer(server);
|
||||||
|
|
||||||
// this is the base url with the random port
|
// 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
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
|
@ -139,34 +155,32 @@ public class TestGetHTTP {
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
// shutdown web service
|
// shutdown web service
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void testContentModifiedTwoServers() throws Exception {
|
public final void testContentModifiedTwoServers() throws Exception {
|
||||||
// set up web services
|
final int port1 = NetworkUtils.availablePort();
|
||||||
ServletHandler handler1 = new ServletHandler();
|
final Server server1 = JettyServerUtils.createServer(port1, null, null);
|
||||||
|
final ServletHandler handler1 = new ServletHandler();
|
||||||
handler1.addServletWithMapping(RESTServiceContentModified.class, "/*");
|
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, "/*");
|
handler2.addServletWithMapping(RESTServiceContentModified.class, "/*");
|
||||||
|
JettyServerUtils.addHandler(server2, handler2);
|
||||||
// create the services
|
|
||||||
TestServer server1 = new TestServer();
|
|
||||||
server1.addHandler(handler1);
|
|
||||||
|
|
||||||
TestServer server2 = new TestServer();
|
|
||||||
server2.addHandler(handler2);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server1.startServer();
|
JettyServerUtils.startServer(server1);
|
||||||
server2.startServer();
|
JettyServerUtils.startServer(server2);
|
||||||
|
|
||||||
// this is the base urls with the random ports
|
// this is the base urls with the random ports
|
||||||
String destination1 = server1.getUrl();
|
String destination1 = String.format(HTTP_URL, port1);
|
||||||
String destination2 = server2.getUrl();
|
String destination2 = String.format(HTTP_URL, port2);
|
||||||
|
|
||||||
// set up NiFi mock controller
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
|
@ -205,8 +219,10 @@ public class TestGetHTTP {
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
// shutdown web services
|
// shutdown web services
|
||||||
server1.shutdownServer();
|
server1.stop();
|
||||||
server2.shutdownServer();
|
server1.destroy();
|
||||||
|
server2.stop();
|
||||||
|
server2.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,13 +233,13 @@ public class TestGetHTTP {
|
||||||
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
||||||
|
|
||||||
// create the service
|
// create the service
|
||||||
TestServer server = new TestServer();
|
final int port = NetworkUtils.availablePort();
|
||||||
server.addHandler(handler);
|
Server server = JettyServerUtils.createServer(port, null, null);
|
||||||
|
server.setHandler(handler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server.startServer();
|
JettyServerUtils.startServer(server);
|
||||||
|
final String destination = String.format(HTTP_URL, port);
|
||||||
String destination = server.getUrl();
|
|
||||||
|
|
||||||
// set up NiFi mock controller
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
|
@ -241,7 +257,8 @@ public class TestGetHTTP {
|
||||||
|
|
||||||
// shutdown web service
|
// shutdown web service
|
||||||
} finally {
|
} finally {
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,13 +269,13 @@ public class TestGetHTTP {
|
||||||
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
||||||
|
|
||||||
// create the service
|
// create the service
|
||||||
TestServer server = new TestServer();
|
final int port = NetworkUtils.availablePort();
|
||||||
server.addHandler(handler);
|
Server server = JettyServerUtils.createServer(port, null, null);
|
||||||
|
server.setHandler(handler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server.startServer();
|
JettyServerUtils.startServer(server);
|
||||||
|
final String destination = String.format(HTTP_URL, port);
|
||||||
String destination = server.getUrl();
|
|
||||||
|
|
||||||
// set up NiFi mock controller
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
|
@ -275,7 +292,8 @@ public class TestGetHTTP {
|
||||||
|
|
||||||
// shutdown web service
|
// shutdown web service
|
||||||
} finally {
|
} finally {
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,13 +304,13 @@ public class TestGetHTTP {
|
||||||
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
handler.addServletWithMapping(UserAgentTestingServlet.class, "/*");
|
||||||
|
|
||||||
// create the service
|
// create the service
|
||||||
TestServer server = new TestServer();
|
final int port = NetworkUtils.availablePort();
|
||||||
server.addHandler(handler);
|
Server server = JettyServerUtils.createServer(port, null, null);
|
||||||
|
server.setHandler(handler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server.startServer();
|
JettyServerUtils.startServer(server);
|
||||||
|
final String destination = String.format(HTTP_URL, port);
|
||||||
String destination = server.getUrl();
|
|
||||||
|
|
||||||
// set up NiFi mock controller
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
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"));
|
assertTrue(fileName.matches("test_\\d\\d\\d\\d/\\d\\d/\\d\\d_\\d\\d:\\d\\d:\\d\\d"));
|
||||||
// shutdown web service
|
// shutdown web service
|
||||||
} finally {
|
} finally {
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,13 +345,14 @@ public class TestGetHTTP {
|
||||||
handler.addServletWithMapping(HttpErrorServlet.class, "/*");
|
handler.addServletWithMapping(HttpErrorServlet.class, "/*");
|
||||||
|
|
||||||
// create the service
|
// create the service
|
||||||
TestServer server = new TestServer();
|
final int port = NetworkUtils.availablePort();
|
||||||
server.addHandler(handler);
|
Server server = JettyServerUtils.createServer(port, null, null);
|
||||||
|
server.setHandler(handler);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server.startServer();
|
JettyServerUtils.startServer(server);
|
||||||
|
final String destination = String.format(HTTP_URL, port);
|
||||||
HttpErrorServlet servlet = (HttpErrorServlet) handler.getServlets()[0].getServlet();
|
HttpErrorServlet servlet = (HttpErrorServlet) handler.getServlets()[0].getServlet();
|
||||||
String destination = server.getUrl();
|
|
||||||
|
|
||||||
this.controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
this.controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
this.controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.CONNECTION_TIMEOUT, "5 secs");
|
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);
|
this.controller.assertTransferCount(org.apache.nifi.processors.standard.GetHTTP.REL_SUCCESS, 0);
|
||||||
} finally {
|
} finally {
|
||||||
// shutdown web service
|
// shutdown web service
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void testSecure_oneWaySsl() throws Exception {
|
public final void testTlsClientAuthenticationNone() throws Exception {
|
||||||
// set up web service
|
// set up web service
|
||||||
final ServletHandler handler = new ServletHandler();
|
final ServletHandler handler = new ServletHandler();
|
||||||
handler.addServletWithMapping(HelloWorldServlet.class, "/*");
|
handler.addServletWithMapping(HelloWorldServlet.class, "/*");
|
||||||
|
|
||||||
// create the service, disabling the need for client auth
|
// create the service, disabling the need for client auth
|
||||||
final Map<String, String> serverSslProperties = getKeystoreProperties();
|
final int port = NetworkUtils.availablePort();
|
||||||
serverSslProperties.put(TestServer.NEED_CLIENT_AUTH, Boolean.toString(false));
|
final Server server = JettyServerUtils.createServer(port, keyStoreSslContext, ClientAuth.NONE);
|
||||||
final TestServer server = new TestServer(serverSslProperties);
|
server.setHandler(handler);
|
||||||
server.addHandler(handler);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server.startServer();
|
JettyServerUtils.startServer(server);
|
||||||
|
final String destination = String.format(HTTPS_URL, port);
|
||||||
final String destination = server.getSecureUrl();
|
|
||||||
|
|
||||||
// set up NiFi mock controller
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
// Use context service with only a truststore
|
// 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.CONNECTION_TIMEOUT, "5 secs");
|
||||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.URL, destination);
|
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);
|
final MockFlowFile mff = controller.getFlowFilesForRelationship(org.apache.nifi.processors.standard.GetHTTP.REL_SUCCESS).get(0);
|
||||||
mff.assertContentEquals("Hello, World!");
|
mff.assertContentEquals("Hello, World!");
|
||||||
} finally {
|
} finally {
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void testSecure_twoWaySsl() throws Exception {
|
public final void testTlsClientAuthenticationRequired() throws Exception {
|
||||||
// set up web service
|
// set up web service
|
||||||
final ServletHandler handler = new ServletHandler();
|
final ServletHandler handler = new ServletHandler();
|
||||||
handler.addServletWithMapping(HelloWorldServlet.class, "/*");
|
handler.addServletWithMapping(HelloWorldServlet.class, "/*");
|
||||||
|
|
||||||
// create the service, providing both truststore and keystore properties, requiring client auth (default)
|
// create the service, providing both truststore and keystore properties, requiring client auth (default)
|
||||||
final Map<String, String> twoWaySslProperties = getKeystoreProperties();
|
final int port = NetworkUtils.availablePort();
|
||||||
twoWaySslProperties.putAll(getTruststoreProperties());
|
final Server server = JettyServerUtils.createServer(port, keyStoreSslContext, ClientAuth.REQUIRED);
|
||||||
final TestServer server = new TestServer(twoWaySslProperties);
|
server.setHandler(handler);
|
||||||
server.addHandler(handler);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server.startServer();
|
JettyServerUtils.startServer(server);
|
||||||
|
final String destination = String.format(HTTPS_URL, port);
|
||||||
final String destination = server.getSecureUrl();
|
|
||||||
|
|
||||||
// set up NiFi mock controller
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
// Use context service with a keystore and a truststore
|
// 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.CONNECTION_TIMEOUT, "10 secs");
|
||||||
controller.setProperty(org.apache.nifi.processors.standard.GetHTTP.URL, destination);
|
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);
|
final MockFlowFile mff = controller.getFlowFilesForRelationship(org.apache.nifi.processors.standard.GetHTTP.REL_SUCCESS).get(0);
|
||||||
mff.assertContentEquals("Hello, World!");
|
mff.assertContentEquals("Hello, World!");
|
||||||
} finally {
|
} finally {
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void testCookiePolicy() throws Exception {
|
public final void testCookiePolicy() throws Exception {
|
||||||
// set up web services
|
final int port1 = NetworkUtils.availablePort();
|
||||||
ServletHandler handler1 = new ServletHandler();
|
final Server server1 = JettyServerUtils.createServer(port1, null, null);
|
||||||
|
final ServletHandler handler1 = new ServletHandler();
|
||||||
handler1.addServletWithMapping(CookieTestingServlet.class, "/*");
|
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, "/*");
|
handler2.addServletWithMapping(CookieVerificationTestingServlet.class, "/*");
|
||||||
|
JettyServerUtils.addHandler(server2, handler2);
|
||||||
// create the services
|
|
||||||
TestServer server1 = new TestServer();
|
|
||||||
server1.addHandler(handler1);
|
|
||||||
|
|
||||||
TestServer server2 = new TestServer();
|
|
||||||
server2.addHandler(handler2);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
server1.startServer();
|
JettyServerUtils.startServer(server1);
|
||||||
server2.startServer();
|
JettyServerUtils.startServer(server2);
|
||||||
|
|
||||||
// this is the base urls with the random ports
|
// this is the base urls with the random ports
|
||||||
String destination1 = server1.getUrl();
|
String destination1 = String.format(HTTP_URL, port1);
|
||||||
String destination2 = server2.getUrl();
|
String destination2 = String.format(HTTP_URL, port2);
|
||||||
|
|
||||||
// set up NiFi mock controller
|
// set up NiFi mock controller
|
||||||
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
controller = TestRunners.newTestRunner(org.apache.nifi.processors.standard.GetHTTP.class);
|
||||||
|
@ -498,38 +515,19 @@ public class TestGetHTTP {
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
// shutdown web services
|
// shutdown web services
|
||||||
server1.shutdownServer();
|
server1.stop();
|
||||||
server2.shutdownServer();
|
server1.destroy();
|
||||||
|
server2.stop();
|
||||||
|
server2.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> getTruststoreProperties() {
|
private void enableSslContextService(final SSLContext configuredSslContext) throws InitializationException {
|
||||||
final Map<String, String> props = new HashMap<>();
|
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||||
props.put(StandardSSLContextService.TRUSTSTORE.getName(), "src/test/resources/truststore.jks");
|
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_IDENTIFIER);
|
||||||
props.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), "passwordpassword");
|
Mockito.when(sslContextService.createContext()).thenReturn(configuredSslContext);
|
||||||
props.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), "JKS");
|
controller.addControllerService(SSL_CONTEXT_IDENTIFIER, sslContextService);
|
||||||
return props;
|
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.ProcessContext;
|
||||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||||
import org.apache.nifi.reporting.InitializationException;
|
import org.apache.nifi.reporting.InitializationException;
|
||||||
|
import org.apache.nifi.security.util.TlsException;
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
import org.apache.nifi.ssl.SSLContextService;
|
||||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
|
||||||
import org.apache.nifi.util.MockFlowFile;
|
import org.apache.nifi.util.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
import org.apache.nifi.util.TestRunners;
|
||||||
|
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests PutSyslog sending messages to ListenSyslog to simulate a syslog server forwarding
|
* Tests PutSyslog sending messages to ListenSyslog to simulate a syslog server forwarding
|
||||||
* to ListenSyslog, or PutSyslog sending to a syslog server.
|
* to ListenSyslog, or PutSyslog sending to a syslog server.
|
||||||
*/
|
*/
|
||||||
public class ITListenAndPutSyslog {
|
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 SSLContext keyStoreSslContext;
|
||||||
private static final String TLS_PROTOCOL_VERSION = "TLSv1.2";
|
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(ITListenAndPutSyslog.class);
|
||||||
|
|
||||||
private ListenSyslog listenSyslog;
|
private ListenSyslog listenSyslog;
|
||||||
private TestRunner listenSyslogRunner;
|
private TestRunner listenSyslogRunner;
|
||||||
|
@ -50,6 +56,11 @@ public class ITListenAndPutSyslog {
|
||||||
private PutSyslog putSyslog;
|
private PutSyslog putSyslog;
|
||||||
private TestRunner putSyslogRunner;
|
private TestRunner putSyslogRunner;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void configureServices() throws TlsException {
|
||||||
|
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
this.listenSyslog = new ListenSyslog();
|
this.listenSyslog = new ListenSyslog();
|
||||||
|
@ -86,10 +97,10 @@ public class ITListenAndPutSyslog {
|
||||||
@Test
|
@Test
|
||||||
public void testTLS() throws InitializationException, IOException, InterruptedException {
|
public void testTLS() throws InitializationException, IOException, InterruptedException {
|
||||||
configureSSLContextService(listenSyslogRunner);
|
configureSSLContextService(listenSyslogRunner);
|
||||||
listenSyslogRunner.setProperty(ListenSyslog.SSL_CONTEXT_SERVICE, "ssl-context");
|
listenSyslogRunner.setProperty(ListenSyslog.SSL_CONTEXT_SERVICE, SSL_SERVICE_IDENTIFIER);
|
||||||
|
|
||||||
configureSSLContextService(putSyslogRunner);
|
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);
|
run(ListenSyslog.TCP_VALUE.getValue(), 7, 7);
|
||||||
}
|
}
|
||||||
|
@ -97,24 +108,19 @@ public class ITListenAndPutSyslog {
|
||||||
@Test
|
@Test
|
||||||
public void testTLSListenerNoTLSPut() throws InitializationException, IOException, InterruptedException {
|
public void testTLSListenerNoTLSPut() throws InitializationException, IOException, InterruptedException {
|
||||||
configureSSLContextService(listenSyslogRunner);
|
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
|
// send 7 but expect 0 because sender didn't use TLS
|
||||||
run(ListenSyslog.TCP_VALUE.getValue(), 7, 0);
|
run(ListenSyslog.TCP_VALUE.getValue(), 7, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SSLContextService configureSSLContextService(TestRunner runner) throws InitializationException {
|
private void configureSSLContextService(TestRunner runner) throws InitializationException {
|
||||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||||
runner.addControllerService("ssl-context", sslContextService);
|
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_SERVICE_IDENTIFIER);
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, "src/test/resources/truststore.jks");
|
Mockito.when(sslContextService.createContext()).thenReturn(keyStoreSslContext);
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, "passwordpassword");
|
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, "JKS");
|
runner.addControllerService(SSL_SERVICE_IDENTIFIER, sslContextService);
|
||||||
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);
|
|
||||||
runner.enableControllerService(sslContextService);
|
runner.enableControllerService(sslContextService);
|
||||||
return sslContextService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,6 +23,7 @@ import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -30,133 +31,115 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
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.SSLContextService;
|
||||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
|
||||||
import org.apache.nifi.util.FlowFileUnpackagerV3;
|
import org.apache.nifi.util.FlowFileUnpackagerV3;
|
||||||
import org.apache.nifi.util.MockFlowFile;
|
import org.apache.nifi.util.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
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.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration Test for deprecated PostHTTP Processor
|
||||||
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class TestPostHTTP {
|
public class ITPostHTTP {
|
||||||
private TestServer server;
|
private Server server;
|
||||||
private TestRunner runner;
|
private TestRunner runner;
|
||||||
private CaptureServlet servlet;
|
private CaptureServlet servlet;
|
||||||
|
|
||||||
private final String KEYSTORE_PATH = "src/test/resources/keystore.jks";
|
private static final String SSL_CONTEXT_IDENTIFIER = SSLContextService.class.getName();
|
||||||
private final String KEYSTORE_AND_TRUSTSTORE_PASSWORD = "passwordpassword";
|
|
||||||
private final String TRUSTSTORE_PATH = "src/test/resources/truststore.jks";
|
private static final String TEST_MESSAGE = String.class.getName();
|
||||||
private final String JKS_TYPE = "JKS";
|
|
||||||
|
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
|
// set up web service
|
||||||
ServletHandler handler = new ServletHandler();
|
ServletHandler handler = new ServletHandler();
|
||||||
handler.addServletWithMapping(CaptureServlet.class, "/*");
|
handler.addServletWithMapping(CaptureServlet.class, "/*");
|
||||||
|
|
||||||
// create the service
|
final Server configuredServer = JettyServerUtils.createServer(port, serverSslContext, clientAuth);
|
||||||
server = new TestServer(sslProperties);
|
configuredServer.setHandler(handler);
|
||||||
server.addHandler(handler);
|
final ServerConnector connector = new ServerConnector(configuredServer);
|
||||||
server.startServer();
|
connector.setPort(port);
|
||||||
|
|
||||||
|
JettyServerUtils.startServer(configuredServer);
|
||||||
|
|
||||||
servlet = (CaptureServlet) handler.getServlets()[0].getServlet();
|
servlet = (CaptureServlet) handler.getServlets()[0].getServlet();
|
||||||
runner = TestRunners.newTestRunner(org.apache.nifi.processors.standard.PostHTTP.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void cleanup() throws Exception {
|
public void cleanup() throws Exception {
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
server.shutdownServer();
|
server.stop();
|
||||||
|
server.destroy();
|
||||||
server = null;
|
server = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTruststoreSSLOnly() throws Exception {
|
public void testUnauthenticatedTls() throws Exception {
|
||||||
final Map<String, String> sslProps = new HashMap<>();
|
setup(keyStoreSslContext, ClientAuth.NONE);
|
||||||
sslProps.put(TestServer.NEED_CLIENT_AUTH, "false");
|
enableSslContextService(trustStoreSslContext);
|
||||||
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);
|
|
||||||
|
|
||||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||||
runner.addControllerService("ssl-context", sslContextService);
|
runner.enqueue(TEST_MESSAGE);
|
||||||
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.run();
|
runner.run();
|
||||||
|
|
||||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1);
|
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTwoWaySSL() throws Exception {
|
public void testMutualTls() throws Exception {
|
||||||
final Map<String, String> sslProps = new HashMap<>();
|
setup(keyStoreSslContext, ClientAuth.REQUIRED);
|
||||||
sslProps.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE_PATH);
|
enableSslContextService(keyStoreSslContext);
|
||||||
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);
|
|
||||||
|
|
||||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||||
runner.addControllerService("ssl-context", sslContextService);
|
runner.enqueue(TEST_MESSAGE);
|
||||||
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.run();
|
runner.run();
|
||||||
|
|
||||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1);
|
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOneWaySSLWhenServerConfiguredForTwoWay() throws Exception {
|
public void testMutualTlsClientCertificateMissing() throws Exception {
|
||||||
final Map<String, String> sslProps = new HashMap<>();
|
setup(keyStoreSslContext, ClientAuth.REQUIRED);
|
||||||
sslProps.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE_PATH);
|
enableSslContextService(trustStoreSslContext);
|
||||||
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);
|
|
||||||
|
|
||||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, Boolean.FALSE.toString());
|
||||||
runner.addControllerService("ssl-context", sslContextService);
|
runner.enqueue(TEST_MESSAGE);
|
||||||
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.run();
|
runner.run();
|
||||||
|
|
||||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_FAILURE, 1);
|
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_FAILURE, 1);
|
||||||
|
@ -164,14 +147,14 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendAsFlowFile() throws Exception {
|
public void testSendAsFlowFile() throws Exception {
|
||||||
setup(null);
|
setup( null, null);
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SEND_AS_FLOWFILE, "true");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SEND_AS_FLOWFILE, "true");
|
||||||
|
|
||||||
final Map<String, String> attrs = new HashMap<>();
|
final Map<String, String> attrs = new HashMap<>();
|
||||||
attrs.put("abc", "cba");
|
attrs.put("abc", "cba");
|
||||||
|
|
||||||
runner.enqueue("Hello".getBytes(), attrs);
|
runner.enqueue(TEST_MESSAGE, attrs);
|
||||||
attrs.put("abc", "abc");
|
attrs.put("abc", "abc");
|
||||||
attrs.put("filename", "xyz.txt");
|
attrs.put("filename", "xyz.txt");
|
||||||
runner.enqueue("World".getBytes(), attrs);
|
runner.enqueue("World".getBytes(), attrs);
|
||||||
|
@ -188,7 +171,7 @@ public class TestPostHTTP {
|
||||||
// unpack first flowfile received
|
// unpack first flowfile received
|
||||||
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
||||||
byte[] contentReceived = baos.toByteArray();
|
byte[] contentReceived = baos.toByteArray();
|
||||||
assertEquals("Hello", new String(contentReceived));
|
assertEquals(TEST_MESSAGE, new String(contentReceived));
|
||||||
assertEquals("cba", receivedAttrs.get("abc"));
|
assertEquals("cba", receivedAttrs.get("abc"));
|
||||||
|
|
||||||
assertTrue(unpacker.hasMoreData());
|
assertTrue(unpacker.hasMoreData());
|
||||||
|
@ -204,35 +187,16 @@ public class TestPostHTTP {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendAsFlowFileSecure() throws Exception {
|
public void testMutualTlsSendFlowFile() throws Exception {
|
||||||
final Map<String, String> sslProps = new HashMap<>();
|
setup(keyStoreSslContext, ClientAuth.REQUIRED);
|
||||||
sslProps.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE_PATH);
|
enableSslContextService(keyStoreSslContext);
|
||||||
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);
|
|
||||||
|
|
||||||
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.SEND_AS_FLOWFILE, "true");
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SSL_CONTEXT_SERVICE, "ssl-context");
|
|
||||||
|
|
||||||
final Map<String, String> attrs = new HashMap<>();
|
final Map<String, String> attrs = new HashMap<>();
|
||||||
attrs.put("abc", "cba");
|
attrs.put("abc", "cba");
|
||||||
|
|
||||||
runner.enqueue("Hello".getBytes(), attrs);
|
runner.enqueue(TEST_MESSAGE, attrs);
|
||||||
attrs.put("abc", "abc");
|
attrs.put("abc", "abc");
|
||||||
attrs.put("filename", "xyz.txt");
|
attrs.put("filename", "xyz.txt");
|
||||||
runner.enqueue("World".getBytes(), attrs);
|
runner.enqueue("World".getBytes(), attrs);
|
||||||
|
@ -249,7 +213,7 @@ public class TestPostHTTP {
|
||||||
// unpack first flowfile received
|
// unpack first flowfile received
|
||||||
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
||||||
byte[] contentReceived = baos.toByteArray();
|
byte[] contentReceived = baos.toByteArray();
|
||||||
assertEquals("Hello", new String(contentReceived));
|
assertEquals(TEST_MESSAGE, new String(contentReceived));
|
||||||
assertEquals("cba", receivedAttrs.get("abc"));
|
assertEquals("cba", receivedAttrs.get("abc"));
|
||||||
|
|
||||||
assertTrue(unpacker.hasMoreData());
|
assertTrue(unpacker.hasMoreData());
|
||||||
|
@ -265,15 +229,14 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendWithMimeType() throws Exception {
|
public void testSendWithMimeType() throws Exception {
|
||||||
setup(null);
|
setup(null, null);
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
|
||||||
|
|
||||||
final Map<String, String> attrs = new HashMap<>();
|
final Map<String, String> attrs = new HashMap<>();
|
||||||
|
|
||||||
final String suppliedMimeType = "text/plain";
|
final String suppliedMimeType = "text/plain";
|
||||||
attrs.put(CoreAttributes.MIME_TYPE.key(), suppliedMimeType);
|
attrs.put(CoreAttributes.MIME_TYPE.key(), suppliedMimeType);
|
||||||
runner.enqueue("Camping is great!".getBytes(), attrs);
|
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.run(1);
|
||||||
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS);
|
runner.assertAllFlowFilesTransferred(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS);
|
||||||
|
@ -285,9 +248,9 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendWithEmptyELExpression() throws Exception {
|
public void testSendWithEmptyELExpression() throws Exception {
|
||||||
setup(null);
|
setup( null, null);
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.URL, server.getUrl());
|
|
||||||
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<>();
|
final Map<String, String> attrs = new HashMap<>();
|
||||||
attrs.put(CoreAttributes.MIME_TYPE.key(), "");
|
attrs.put(CoreAttributes.MIME_TYPE.key(), "");
|
||||||
|
@ -302,12 +265,11 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendWithContentTypeProperty() throws Exception {
|
public void testSendWithContentTypeProperty() throws Exception {
|
||||||
setup(null);
|
setup(null, null);
|
||||||
|
|
||||||
final String suppliedMimeType = "text/plain";
|
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.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<>();
|
final Map<String, String> attrs = new HashMap<>();
|
||||||
attrs.put(CoreAttributes.MIME_TYPE.key(), "text/csv");
|
attrs.put(CoreAttributes.MIME_TYPE.key(), "text/csv");
|
||||||
|
@ -322,10 +284,9 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendWithCompressionServerAcceptGzip() throws Exception {
|
public void testSendWithCompressionServerAcceptGzip() throws Exception {
|
||||||
setup(null);
|
setup(null, null);
|
||||||
|
|
||||||
final String suppliedMimeType = "text/plain";
|
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.CONTENT_TYPE, suppliedMimeType);
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "9");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "9");
|
||||||
|
|
||||||
|
@ -346,10 +307,9 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendWithoutCompressionServerAcceptGzip() throws Exception {
|
public void testSendWithoutCompressionServerAcceptGzip() throws Exception {
|
||||||
setup(null);
|
setup(null, null);
|
||||||
|
|
||||||
final String suppliedMimeType = "text/plain";
|
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.CONTENT_TYPE, suppliedMimeType);
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "0");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "0");
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||||
|
@ -371,11 +331,14 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendWithCompressionServerNotAcceptGzip() throws Exception {
|
public void testSendWithCompressionServerNotAcceptGzip() throws Exception {
|
||||||
setup(null);
|
setup(null, null);
|
||||||
|
|
||||||
final String suppliedMimeType = "text/plain";
|
final String suppliedMimeType = "text/plain";
|
||||||
// Specify a property to the URL to have the CaptureServlet specify it doesn't accept gzip
|
// 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.CONTENT_TYPE, suppliedMimeType);
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "9");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.COMPRESSION_LEVEL, "9");
|
||||||
|
|
||||||
|
@ -395,12 +358,11 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendChunked() throws Exception {
|
public void testSendChunked() throws Exception {
|
||||||
setup(null);
|
setup(null, null);
|
||||||
|
|
||||||
final String suppliedMimeType = "text/plain";
|
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.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<>();
|
final Map<String, String> attrs = new HashMap<>();
|
||||||
attrs.put(CoreAttributes.MIME_TYPE.key(), "text/plain");
|
attrs.put(CoreAttributes.MIME_TYPE.key(), "text/plain");
|
||||||
|
@ -421,10 +383,9 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendWithThrottler() throws Exception {
|
public void testSendWithThrottler() throws Exception {
|
||||||
setup(null);
|
setup(null, null);
|
||||||
|
|
||||||
final String suppliedMimeType = "text/plain";
|
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.CONTENT_TYPE, suppliedMimeType);
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.CHUNKED_ENCODING, "false");
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.MAX_DATA_RATE, "10kb");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.MAX_DATA_RATE, "10kb");
|
||||||
|
@ -448,31 +409,28 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultUserAgent() throws Exception {
|
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"));
|
Assert.assertTrue(runner.getProcessContext().getProperty(org.apache.nifi.processors.standard.PostHTTP.USER_AGENT).getValue().startsWith("Apache-HttpClient"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithMultipleUrls() throws Exception {
|
public void testBatchWithMultipleUrls() throws Exception {
|
||||||
CaptureServlet servletA, servletB;
|
setup(null,null);
|
||||||
TestServer serverA, serverB;
|
final CaptureServlet servletA = servlet;
|
||||||
|
final String urlA = runner.getProcessContext().getProperty(org.apache.nifi.processors.standard.PostHTTP.URL).getValue();
|
||||||
|
|
||||||
{ // setup test servers
|
// set up second web service
|
||||||
setup(null);
|
ServletHandler handler = new ServletHandler();
|
||||||
servletA = servlet;
|
handler.addServletWithMapping(CaptureServlet.class, "/*");
|
||||||
serverA = server;
|
|
||||||
|
|
||||||
// set up second web service
|
// create the second service
|
||||||
ServletHandler handler = new ServletHandler();
|
final int portB = NetworkUtils.availablePort();
|
||||||
handler.addServletWithMapping(CaptureServlet.class, "/*");
|
final String urlB = getUrl(null, portB);
|
||||||
|
final Server serverB = JettyServerUtils.createServer(portB, null, null);
|
||||||
|
serverB.setHandler(handler);
|
||||||
|
JettyServerUtils.startServer(serverB);
|
||||||
|
|
||||||
// create the second service
|
final CaptureServlet servletB = (CaptureServlet) handler.getServlets()[0].getServlet();
|
||||||
serverB = new TestServer(null);
|
|
||||||
serverB.addHandler(handler);
|
|
||||||
serverB.startServer();
|
|
||||||
|
|
||||||
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.URL, "${url}"); // use EL for the URL
|
||||||
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SEND_AS_FLOWFILE, "true");
|
runner.setProperty(org.apache.nifi.processors.standard.PostHTTP.SEND_AS_FLOWFILE, "true");
|
||||||
|
@ -486,8 +444,8 @@ public class TestPostHTTP {
|
||||||
|
|
||||||
// enqueue 9 FlowFiles
|
// enqueue 9 FlowFiles
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
enqueueWithURL("a" + i, serverA.getUrl());
|
enqueueWithURL("a" + i, urlA);
|
||||||
enqueueWithURL("b" + i, serverB.getUrl());
|
enqueueWithURL("b" + i, urlB);
|
||||||
|
|
||||||
expectedContentA.add("a" + i);
|
expectedContentA.add("a" + i);
|
||||||
expectedContentB.add("b" + i);
|
expectedContentB.add("b" + i);
|
||||||
|
@ -503,10 +461,10 @@ public class TestPostHTTP {
|
||||||
MockFlowFile mff = successFiles.get(0);
|
MockFlowFile mff = successFiles.get(0);
|
||||||
final String urlAttr = mff.getAttribute("url");
|
final String urlAttr = mff.getAttribute("url");
|
||||||
|
|
||||||
if (serverA.getUrl().equals(urlAttr)) {
|
if (urlA.equals(urlAttr)) {
|
||||||
checkBatch(serverA, servletA, actualContentA, (actualContentA.isEmpty() ? 5 : 4));
|
checkBatch(urlA, servletA, actualContentA, (actualContentA.isEmpty() ? 5 : 4));
|
||||||
} else if (serverB.getUrl().equals(urlAttr)) {
|
} else if (urlB.equals(urlAttr)) {
|
||||||
checkBatch(serverB, servletB, actualContentB, (actualContentB.isEmpty() ? 5 : 4));
|
checkBatch(urlB, servletB, actualContentB, (actualContentB.isEmpty() ? 5 : 4));
|
||||||
} else {
|
} else {
|
||||||
fail("unexpected url attribute");
|
fail("unexpected url attribute");
|
||||||
}
|
}
|
||||||
|
@ -526,7 +484,7 @@ public class TestPostHTTP {
|
||||||
runner.enqueue(data.getBytes(), attrs);
|
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();
|
FlowFileUnpackagerV3 unpacker = new FlowFileUnpackagerV3();
|
||||||
Set<String> actualFFContent = new HashSet<>();
|
Set<String> actualFFContent = new HashSet<>();
|
||||||
Set<String> actualPostContent = 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);
|
final List<MockFlowFile> successFlowFiles = runner.getFlowFilesForRelationship(org.apache.nifi.processors.standard.PostHTTP.REL_SUCCESS);
|
||||||
for (int i = 0; i < expectedCount; i++) {
|
for (int i = 0; i < expectedCount; i++) {
|
||||||
MockFlowFile mff = successFlowFiles.get(i);
|
MockFlowFile mff = successFlowFiles.get(i);
|
||||||
mff.assertAttributeEquals("url", server.getUrl());
|
mff.assertAttributeEquals("url", url);
|
||||||
String content = new String(mff.toByteArray());
|
String content = new String(mff.toByteArray());
|
||||||
actualFFContent.add(content);
|
actualFFContent.add(content);
|
||||||
}
|
}
|
||||||
|
@ -549,9 +507,10 @@ public class TestPostHTTP {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
for (int i = 0; i < expectedCount; i++) {
|
for (int i = 0; i < expectedCount; i++) {
|
||||||
Map<String, String> receivedAttrs = unpacker.unpackageFlowFile(bais, baos);
|
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);
|
actualPostContent.add(receivedContent);
|
||||||
assertEquals(server.getUrl(), receivedAttrs.get("url"));
|
assertEquals(url, receivedAttrs.get("url"));
|
||||||
assertTrue(unpacker.hasMoreData() || i == (expectedCount - 1));
|
assertTrue(unpacker.hasMoreData() || i == (expectedCount - 1));
|
||||||
baos.reset();
|
baos.reset();
|
||||||
}
|
}
|
||||||
|
@ -560,8 +519,17 @@ public class TestPostHTTP {
|
||||||
// confirm that the transferred and POSTed content match
|
// confirm that the transferred and POSTed content match
|
||||||
assertEquals(actualFFContent, actualPostContent);
|
assertEquals(actualFFContent, actualPostContent);
|
||||||
|
|
||||||
// accumulate actial content
|
// accumulate actual content
|
||||||
actualContent.addAll(actualPostContent);
|
actualContent.addAll(actualPostContent);
|
||||||
runner.clearTransferState();
|
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.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
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.processor.ProcessContext;
|
||||||
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
import org.apache.nifi.processors.standard.util.HTTPUtils;
|
||||||
import org.apache.nifi.reporting.InitializationException;
|
import org.apache.nifi.reporting.InitializationException;
|
||||||
import org.apache.nifi.security.util.SslContextFactory;
|
import org.apache.nifi.security.util.TlsException;
|
||||||
import org.apache.nifi.security.util.StandardTlsConfiguration;
|
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||||
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.util.MockFlowFile;
|
import org.apache.nifi.util.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
import org.apache.nifi.util.TestRunners;
|
||||||
|
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public class ITestHandleHttpRequest {
|
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 HandleHttpRequest processor;
|
||||||
|
|
||||||
private TlsConfiguration clientTlsConfiguration;
|
private static SSLContext keyStoreSslContext;
|
||||||
private TlsConfiguration trustOnlyTlsConfiguration;
|
|
||||||
|
|
||||||
private static Map<String, String> getTruststoreProperties() {
|
private static SSLContext trustStoreSslContext;
|
||||||
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 Map<String, String> getServerKeystoreProperties() {
|
@BeforeClass
|
||||||
final Map<String, String> properties = new HashMap<>();
|
public static void configureServices() throws TlsException {
|
||||||
properties.put(StandardSSLContextService.KEYSTORE.getName(), KEYSTORE);
|
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||||
properties.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), KEYSTORE_PASSWORD);
|
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
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
|
@After
|
||||||
|
@ -136,7 +98,7 @@ public class ITestHandleHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 30000)
|
@Test(timeout = 30000)
|
||||||
public void testRequestAddedToService() throws InitializationException, IOException, InterruptedException {
|
public void testRequestAddedToService() throws InitializationException {
|
||||||
CountDownLatch serverReady = new CountDownLatch(1);
|
CountDownLatch serverReady = new CountDownLatch(1);
|
||||||
CountDownLatch requestSent = new CountDownLatch(1);
|
CountDownLatch requestSent = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@ -191,7 +153,7 @@ public class ITestHandleHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 30000)
|
@Test(timeout = 30000)
|
||||||
public void testMultipartFormDataRequest() throws InitializationException, IOException, InterruptedException {
|
public void testMultipartFormDataRequest() throws InitializationException {
|
||||||
CountDownLatch serverReady = new CountDownLatch(1);
|
CountDownLatch serverReady = new CountDownLatch(1);
|
||||||
CountDownLatch requestSent = new CountDownLatch(1);
|
CountDownLatch requestSent = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@ -304,8 +266,7 @@ public class ITestHandleHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 30000)
|
@Test(timeout = 30000)
|
||||||
public void testMultipartFormDataRequestCaptureFormAttributes() throws InitializationException, IOException,
|
public void testMultipartFormDataRequestCaptureFormAttributes() throws InitializationException {
|
||||||
InterruptedException {
|
|
||||||
CountDownLatch serverReady = new CountDownLatch(1);
|
CountDownLatch serverReady = new CountDownLatch(1);
|
||||||
CountDownLatch requestSent = new CountDownLatch(1);
|
CountDownLatch requestSent = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@ -374,7 +335,7 @@ public class ITestHandleHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 30000)
|
@Test(timeout = 30000)
|
||||||
public void testMultipartFormDataRequestFailToRegisterContext() throws InitializationException, IOException, InterruptedException {
|
public void testMultipartFormDataRequestFailToRegisterContext() throws InitializationException, InterruptedException {
|
||||||
CountDownLatch serverReady = new CountDownLatch(1);
|
CountDownLatch serverReady = new CountDownLatch(1);
|
||||||
CountDownLatch requestSent = new CountDownLatch(1);
|
CountDownLatch requestSent = new CountDownLatch(1);
|
||||||
CountDownLatch resultReady = new CountDownLatch(1);
|
CountDownLatch resultReady = new CountDownLatch(1);
|
||||||
|
@ -427,7 +388,7 @@ public class ITestHandleHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call call, Response response) throws IOException {
|
public void onResponse(Call call, Response response) {
|
||||||
responseCode.set(response.code());
|
responseCode.set(response.code());
|
||||||
resultReady.countDown();
|
resultReady.countDown();
|
||||||
}
|
}
|
||||||
|
@ -473,7 +434,7 @@ public class ITestHandleHttpRequest {
|
||||||
|
|
||||||
|
|
||||||
@Test(timeout = 30000)
|
@Test(timeout = 30000)
|
||||||
public void testFailToRegister() throws InitializationException, IOException, InterruptedException {
|
public void testFailToRegister() throws InitializationException, InterruptedException {
|
||||||
CountDownLatch serverReady = new CountDownLatch(1);
|
CountDownLatch serverReady = new CountDownLatch(1);
|
||||||
CountDownLatch requestSent = new CountDownLatch(1);
|
CountDownLatch requestSent = new CountDownLatch(1);
|
||||||
CountDownLatch resultReady = new CountDownLatch(1);
|
CountDownLatch resultReady = new CountDownLatch(1);
|
||||||
|
@ -649,10 +610,13 @@ public class ITestHandleHttpRequest {
|
||||||
runner.enableControllerService(contextMap);
|
runner.enableControllerService(contextMap);
|
||||||
runner.setProperty(HandleHttpRequest.HTTP_CONTEXT_MAP, "http-context-map");
|
runner.setProperty(HandleHttpRequest.HTTP_CONTEXT_MAP, "http-context-map");
|
||||||
|
|
||||||
final Map<String, String> sslProperties = getServerKeystoreProperties();
|
final RestrictedSSLContextService sslContextService = Mockito.mock(RestrictedSSLContextService.class);
|
||||||
sslProperties.putAll(getTruststoreProperties());
|
final String serviceIdentifier = RestrictedSSLContextService.class.getName();
|
||||||
sslProperties.put(StandardSSLContextService.SSL_ALGORITHM.getName(), TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion());
|
Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
|
||||||
useSSLContextService(runner, sslProperties);
|
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() {
|
final Thread httpThread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -667,10 +631,10 @@ public class ITestHandleHttpRequest {
|
||||||
SSLContext clientSslContext;
|
SSLContext clientSslContext;
|
||||||
if (twoWaySsl) {
|
if (twoWaySsl) {
|
||||||
// Use a client certificate, do not reuse the server's keystore
|
// Use a client certificate, do not reuse the server's keystore
|
||||||
clientSslContext = SslContextFactory.createSslContext(clientTlsConfiguration);
|
clientSslContext = keyStoreSslContext;
|
||||||
} else {
|
} else {
|
||||||
// With one-way SSL, the client still needs a truststore
|
// With one-way SSL, the client still needs a truststore
|
||||||
clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
clientSslContext = trustStoreSslContext;
|
||||||
}
|
}
|
||||||
connection.setSSLSocketFactory(clientSslContext.getSocketFactory());
|
connection.setSSLSocketFactory(clientSslContext.getSocketFactory());
|
||||||
connection.setDoOutput(false);
|
connection.setDoOutput(false);
|
||||||
|
|
|
@ -27,12 +27,15 @@ import java.io.PrintWriter;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import javax.net.ssl.SSLContext;
|
||||||
import java.util.Map;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import org.apache.nifi.processors.standard.util.TestInvokeHttpCommon;
|
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.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunners;
|
import org.apache.nifi.util.TestRunners;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
|
@ -41,12 +44,29 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class TestInvokeHTTP extends TestInvokeHttpCommon {
|
public class TestInvokeHTTP extends TestInvokeHttpCommon {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TestInvokeHTTP.class);
|
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
|
@BeforeClass
|
||||||
public static void beforeClass() throws Exception {
|
public static void beforeClass() throws Exception {
|
||||||
configureServer(null, null);
|
configureServer(null, null);
|
||||||
|
@ -59,20 +79,18 @@ public class TestInvokeHTTP extends TestInvokeHttpCommon {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSslSetHttpRequest() throws Exception {
|
public void testSslSetHttpRequest() throws Exception {
|
||||||
|
final String serviceIdentifier = SSLContextService.class.getName();
|
||||||
final Map<String, String> sslProperties = new HashMap<>();
|
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||||
sslProperties.put(StandardSSLContextService.KEYSTORE.getName(), "src/test/resources/keystore.jks");
|
Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
|
||||||
sslProperties.put(StandardSSLContextService.KEYSTORE_PASSWORD.getName(), "passwordpassword");
|
final SSLContext sslContext = SslContextFactory.createSslContext(TLS_CONFIGURATION);
|
||||||
sslProperties.put(StandardSSLContextService.KEYSTORE_TYPE.getName(), "JKS");
|
Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
|
||||||
sslProperties.put(StandardSSLContextService.TRUSTSTORE.getName(), "src/test/resources/truststore.jks");
|
Mockito.when(sslContextService.createTlsConfiguration()).thenReturn(TLS_CONFIGURATION);
|
||||||
sslProperties.put(StandardSSLContextService.TRUSTSTORE_PASSWORD.getName(), "passwordpassword");
|
|
||||||
sslProperties.put(StandardSSLContextService.TRUSTSTORE_TYPE.getName(), "JKS");
|
|
||||||
|
|
||||||
runner = TestRunners.newTestRunner(InvokeHTTP.class);
|
runner = TestRunners.newTestRunner(InvokeHTTP.class);
|
||||||
final StandardSSLContextService sslService = new StandardSSLContextService();
|
|
||||||
runner.addControllerService("ssl-context", sslService, sslProperties);
|
runner.addControllerService(serviceIdentifier, sslContextService);
|
||||||
runner.enableControllerService(sslService);
|
runner.enableControllerService(sslContextService);
|
||||||
runner.setProperty(InvokeHTTP.PROP_SSL_CONTEXT_SERVICE, "ssl-context");
|
runner.setProperty(InvokeHTTP.PROP_SSL_CONTEXT_SERVICE, serviceIdentifier);
|
||||||
|
|
||||||
addHandler(new GetOrHeadHandler());
|
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.security.util.TlsException;
|
||||||
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
import org.apache.nifi.ssl.SSLContextService;
|
||||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
|
||||||
import org.apache.nifi.util.MockFlowFile;
|
import org.apache.nifi.util.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
import org.apache.nifi.util.TestRunners;
|
||||||
|
@ -314,16 +313,6 @@ public class TestListenHTTP {
|
||||||
testPOSTRequestsReceived(HttpServletResponse.SC_NO_CONTENT, true, true);
|
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
|
@Test
|
||||||
public void testSecureServerSupportsCurrentTlsProtocolVersion() throws Exception {
|
public void testSecureServerSupportsCurrentTlsProtocolVersion() throws Exception {
|
||||||
configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
|
configureProcessorSslContextService(ListenHTTP.ClientAuthentication.AUTO, SERVER_NO_TRUSTSTORE_CONFIGURATION);
|
||||||
|
@ -539,22 +528,8 @@ public class TestListenHTTP {
|
||||||
runner.enableControllerService(sslContextService);
|
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);
|
@Test
|
||||||
return sslContextService;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test(/*timeout=10000*/)
|
|
||||||
public void testMultipartFormDataRequest() throws Exception {
|
public void testMultipartFormDataRequest() throws Exception {
|
||||||
|
|
||||||
runner.setProperty(ListenHTTP.PORT, Integer.toString(availablePort));
|
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.ProvenanceEventRecord;
|
||||||
import org.apache.nifi.provenance.ProvenanceEventType;
|
import org.apache.nifi.provenance.ProvenanceEventType;
|
||||||
import org.apache.nifi.reporting.InitializationException;
|
import org.apache.nifi.reporting.InitializationException;
|
||||||
|
import org.apache.nifi.security.util.TlsException;
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
import org.apache.nifi.ssl.SSLContextService;
|
||||||
import org.apache.nifi.ssl.StandardSSLContextService;
|
|
||||||
import org.apache.nifi.util.MockFlowFile;
|
import org.apache.nifi.util.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
import org.apache.nifi.util.TestRunners;
|
||||||
|
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -50,9 +51,6 @@ import org.mockito.Mockito;
|
||||||
|
|
||||||
public class TestListenRELP {
|
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 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";
|
public static final String SYSLOG_FRAME_DATA = "this is a syslog message here";
|
||||||
|
|
||||||
|
@ -151,19 +149,16 @@ public class TestListenRELP {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTLS() throws InitializationException, IOException, InterruptedException {
|
public void testMutualTls() throws IOException, InterruptedException, TlsException, InitializationException {
|
||||||
final SSLContextService sslContextService = new StandardSSLContextService();
|
final SSLContextService sslContextService = Mockito.mock(SSLContextService.class);
|
||||||
runner.addControllerService("ssl-context", sslContextService);
|
final String serviceIdentifier = SSLContextService.class.getName();
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.SSL_ALGORITHM, TLS_PROTOCOL_VERSION);
|
Mockito.when(sslContextService.getIdentifier()).thenReturn(serviceIdentifier);
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE, "src/test/resources/truststore.jks");
|
final SSLContext sslContext = SslContextUtils.createKeyStoreSslContext();
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_PASSWORD, "passwordpassword");
|
Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.TRUSTSTORE_TYPE, "JKS");
|
runner.addControllerService(serviceIdentifier, sslContextService);
|
||||||
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.enableControllerService(sslContextService);
|
||||||
|
|
||||||
runner.setProperty(ListenRELP.SSL_CONTEXT_SERVICE, "ssl-context");
|
runner.setProperty(ListenRELP.SSL_CONTEXT_SERVICE, serviceIdentifier);
|
||||||
|
|
||||||
final List<RELPFrame> frames = new ArrayList<>();
|
final List<RELPFrame> frames = new ArrayList<>();
|
||||||
frames.add(OPEN_FRAME);
|
frames.add(OPEN_FRAME);
|
||||||
|
@ -174,8 +169,7 @@ public class TestListenRELP {
|
||||||
frames.add(SYSLOG_FRAME);
|
frames.add(SYSLOG_FRAME);
|
||||||
frames.add(CLOSE_FRAME);
|
frames.add(CLOSE_FRAME);
|
||||||
|
|
||||||
// three syslog frames should be transferred and three responses should be sent
|
run(frames, 5, 5, sslContext);
|
||||||
run(frames, 5, 5, sslContextService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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 {
|
throws IOException, InterruptedException {
|
||||||
|
|
||||||
Socket socket = null;
|
Socket socket = null;
|
||||||
|
@ -224,11 +218,10 @@ public class TestListenRELP {
|
||||||
final int realPort = proc.getDispatcherPort();
|
final int realPort = proc.getDispatcherPort();
|
||||||
|
|
||||||
// create either a regular socket or ssl socket based on context being passed in
|
// create either a regular socket or ssl socket based on context being passed in
|
||||||
if (sslContextService != null) {
|
if (sslContext == null) {
|
||||||
final SSLContext sslContext = sslContextService.createContext();
|
|
||||||
socket = sslContext.getSocketFactory().createSocket("localhost", realPort);
|
|
||||||
} else {
|
|
||||||
socket = new Socket("localhost", realPort);
|
socket = new Socket("localhost", realPort);
|
||||||
|
} else {
|
||||||
|
socket = sslContext.getSocketFactory().createSocket("localhost", realPort);
|
||||||
}
|
}
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|
||||||
|
|
|
@ -21,56 +21,51 @@ import java.net.Socket;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.net.SocketFactory;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||||
import org.apache.nifi.reporting.InitializationException;
|
import org.apache.nifi.reporting.InitializationException;
|
||||||
import org.apache.nifi.security.util.ClientAuth;
|
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.security.util.TlsException;
|
||||||
|
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
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.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
import org.apache.nifi.util.TestRunners;
|
||||||
|
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
public class TestListenTCP {
|
public class TestListenTCP {
|
||||||
|
private static final long RESPONSE_TIMEOUT = 10000;
|
||||||
|
|
||||||
private static final String KEYSTORE = "src/test/resources/keystore.jks";
|
private static final String SSL_CONTEXT_IDENTIFIER = SSLContextService.class.getName();
|
||||||
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 SSLContext keyStoreSslContext;
|
||||||
private static final String TLS_PROTOCOL_VERSION = "TLSv1.2";
|
|
||||||
|
|
||||||
private static TlsConfiguration clientTlsConfiguration;
|
private static SSLContext trustStoreSslContext;
|
||||||
private static TlsConfiguration trustOnlyTlsConfiguration;
|
|
||||||
|
|
||||||
private ListenTCP proc;
|
private ListenTCP proc;
|
||||||
private TestRunner runner;
|
private TestRunner runner;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void configureServices() throws TlsException {
|
||||||
|
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||||
|
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
proc = new ListenTCP();
|
proc = new ListenTCP();
|
||||||
runner = TestRunners.newTestRunner(proc);
|
runner = TestRunners.newTestRunner(proc);
|
||||||
runner.setProperty(ListenTCP.PORT, "0");
|
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
|
@Test
|
||||||
|
@ -78,7 +73,7 @@ public class TestListenTCP {
|
||||||
runner.setProperty(ListenTCP.PORT, "1");
|
runner.setProperty(ListenTCP.PORT, "1");
|
||||||
runner.assertValid();
|
runner.assertValid();
|
||||||
|
|
||||||
configureProcessorSslContextService();
|
enableSslContextService(keyStoreSslContext);
|
||||||
runner.setProperty(ListenTCP.CLIENT_AUTH, "");
|
runner.setProperty(ListenTCP.CLIENT_AUTH, "");
|
||||||
runner.assertNotValid();
|
runner.assertNotValid();
|
||||||
|
|
||||||
|
@ -126,11 +121,11 @@ public class TestListenTCP {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTLSClientAuthRequiredAndClientCertProvided() throws InitializationException, IOException, InterruptedException,
|
public void testTLSClientAuthRequiredAndClientCertProvided() throws IOException, InterruptedException,
|
||||||
TlsException {
|
InitializationException {
|
||||||
|
|
||||||
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
||||||
configureProcessorSslContextService();
|
enableSslContextService(keyStoreSslContext);
|
||||||
|
|
||||||
final List<String> messages = new ArrayList<>();
|
final List<String> messages = new ArrayList<>();
|
||||||
messages.add("This is message 1\n");
|
messages.add("This is message 1\n");
|
||||||
|
@ -140,9 +135,7 @@ public class TestListenTCP {
|
||||||
messages.add("This is message 5\n");
|
messages.add("This is message 5\n");
|
||||||
|
|
||||||
// Make an SSLContext with a key and trust store to send the test messages
|
// Make an SSLContext with a key and trust store to send the test messages
|
||||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(clientTlsConfiguration);
|
runTCP(messages, messages.size(), keyStoreSslContext);
|
||||||
|
|
||||||
runTCP(messages, messages.size(), clientSslContext);
|
|
||||||
|
|
||||||
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS);
|
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS);
|
||||||
for (int i = 0; i < mockFlowFiles.size(); i++) {
|
for (int i = 0; i < mockFlowFiles.size(); i++) {
|
||||||
|
@ -151,10 +144,9 @@ public class TestListenTCP {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTLSClientAuthRequiredAndClientCertNotProvided() throws InitializationException, TlsException {
|
public void testTLSClientAuthRequiredAndClientCertNotProvided() throws InitializationException {
|
||||||
|
|
||||||
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
||||||
configureProcessorSslContextService();
|
enableSslContextService(keyStoreSslContext);
|
||||||
|
|
||||||
final List<String> messages = new ArrayList<>();
|
final List<String> messages = new ArrayList<>();
|
||||||
messages.add("This is message 1\n");
|
messages.add("This is message 1\n");
|
||||||
|
@ -164,21 +156,15 @@ public class TestListenTCP {
|
||||||
messages.add("This is message 5\n");
|
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
|
// 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);
|
Assert.assertThrows(SSLException.class, () ->
|
||||||
|
runTCP(messages, messages.size(), trustStoreSslContext)
|
||||||
try {
|
);
|
||||||
runTCP(messages, messages.size(), clientSslContext);
|
|
||||||
Assert.fail("Should have thrown exception");
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTLSClientAuthNoneAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException, TlsException {
|
public void testTLSClientAuthNoneAndClientCertNotProvided() throws IOException, InterruptedException, InitializationException {
|
||||||
|
|
||||||
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.NONE.name());
|
runner.setProperty(ListenTCP.CLIENT_AUTH, ClientAuth.NONE.name());
|
||||||
configureProcessorSslContextService();
|
enableSslContextService(keyStoreSslContext);
|
||||||
|
|
||||||
final List<String> messages = new ArrayList<>();
|
final List<String> messages = new ArrayList<>();
|
||||||
messages.add("This is message 1\n");
|
messages.add("This is message 1\n");
|
||||||
|
@ -188,9 +174,7 @@ public class TestListenTCP {
|
||||||
messages.add("This is message 5\n");
|
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
|
// 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(), trustStoreSslContext);
|
||||||
|
|
||||||
runTCP(messages, messages.size(), clientSslContext);
|
|
||||||
|
|
||||||
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS);
|
List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS);
|
||||||
for (int i = 0; i < mockFlowFiles.size(); i++) {
|
for (int i = 0; i < mockFlowFiles.size(); i++) {
|
||||||
|
@ -212,10 +196,11 @@ public class TestListenTCP {
|
||||||
final int realPort = proc.getDispatcherPort();
|
final int realPort = proc.getDispatcherPort();
|
||||||
|
|
||||||
// create either a regular socket or ssl socket based on context being passed in
|
// create either a regular socket or ssl socket based on context being passed in
|
||||||
if (sslContext != null) {
|
if (sslContext == null) {
|
||||||
socket = sslContext.getSocketFactory().createSocket("localhost", realPort);
|
|
||||||
} else {
|
|
||||||
socket = new Socket("localhost", realPort);
|
socket = new Socket("localhost", realPort);
|
||||||
|
} else {
|
||||||
|
final SocketFactory socketFactory = sslContext.getSocketFactory();
|
||||||
|
socket = socketFactory.createSocket("localhost", realPort);
|
||||||
}
|
}
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|
||||||
|
@ -226,14 +211,12 @@ public class TestListenTCP {
|
||||||
}
|
}
|
||||||
socket.getOutputStream().flush();
|
socket.getOutputStream().flush();
|
||||||
|
|
||||||
long responseTimeout = 10000;
|
|
||||||
|
|
||||||
// this first loop waits until the internal queue of the processor has the expected
|
// 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
|
// number of messages ready before proceeding, we want to guarantee they are all there
|
||||||
// before onTrigger gets a chance to run
|
// before onTrigger gets a chance to run
|
||||||
long startTimeQueueSizeCheck = System.currentTimeMillis();
|
long startTimeQueueSizeCheck = System.currentTimeMillis();
|
||||||
while (proc.getQueueSize() < messages.size()
|
while (proc.getQueueSize() < messages.size()
|
||||||
&& (System.currentTimeMillis() - startTimeQueueSizeCheck < responseTimeout)) {
|
&& (System.currentTimeMillis() - startTimeQueueSizeCheck < RESPONSE_TIMEOUT)) {
|
||||||
Thread.sleep(100);
|
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
|
// call onTrigger until we processed all the frames, or a certain amount of time passes
|
||||||
int numTransferred = 0;
|
int numTransferred = 0;
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
while (numTransferred < expectedTransferred && (System.currentTimeMillis() - startTime < responseTimeout)) {
|
while (numTransferred < expectedTransferred && (System.currentTimeMillis() - startTime < RESPONSE_TIMEOUT)) {
|
||||||
proc.onTrigger(context, processSessionFactory);
|
proc.onTrigger(context, processSessionFactory);
|
||||||
numTransferred = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS).size();
|
numTransferred = runner.getFlowFilesForRelationship(ListenTCP.REL_SUCCESS).size();
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
@ -258,20 +241,12 @@ public class TestListenTCP {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SSLContextService configureProcessorSslContextService() throws InitializationException {
|
private void enableSslContextService(final SSLContext sslContext) throws InitializationException {
|
||||||
final SSLContextService sslContextService = new StandardRestrictedSSLContextService();
|
final RestrictedSSLContextService sslContextService = Mockito.mock(RestrictedSSLContextService.class);
|
||||||
runner.addControllerService("ssl-context", sslContextService);
|
Mockito.when(sslContextService.getIdentifier()).thenReturn(SSL_CONTEXT_IDENTIFIER);
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE, KEYSTORE);
|
Mockito.when(sslContextService.createContext()).thenReturn(sslContext);
|
||||||
runner.setProperty(sslContextService, StandardSSLContextService.KEYSTORE_PASSWORD, KEYSTORE_PASSWORD);
|
runner.addControllerService(SSL_CONTEXT_IDENTIFIER, sslContextService);
|
||||||
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);
|
|
||||||
runner.enableControllerService(sslContextService);
|
runner.enableControllerService(sslContextService);
|
||||||
|
runner.setProperty(ListenTCP.SSL_CONTEXT_SERVICE, SSL_CONTEXT_IDENTIFIER);
|
||||||
runner.setProperty(ListenTCP.SSL_CONTEXT_SERVICE, "ssl-context");
|
|
||||||
return sslContextService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,43 +31,27 @@ import org.apache.nifi.processor.ProcessSessionFactory;
|
||||||
import org.apache.nifi.reporting.InitializationException;
|
import org.apache.nifi.reporting.InitializationException;
|
||||||
import org.apache.nifi.schema.access.SchemaAccessUtils;
|
import org.apache.nifi.schema.access.SchemaAccessUtils;
|
||||||
import org.apache.nifi.security.util.ClientAuth;
|
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.security.util.TlsException;
|
||||||
import org.apache.nifi.serialization.RecordReaderFactory;
|
import org.apache.nifi.serialization.RecordReaderFactory;
|
||||||
import org.apache.nifi.serialization.RecordSetWriterFactory;
|
import org.apache.nifi.serialization.RecordSetWriterFactory;
|
||||||
import org.apache.nifi.serialization.record.MockRecordWriter;
|
import org.apache.nifi.serialization.record.MockRecordWriter;
|
||||||
|
import org.apache.nifi.ssl.RestrictedSSLContextService;
|
||||||
import org.apache.nifi.ssl.SSLContextService;
|
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.MockFlowFile;
|
||||||
import org.apache.nifi.util.TestRunner;
|
import org.apache.nifi.util.TestRunner;
|
||||||
import org.apache.nifi.util.TestRunners;
|
import org.apache.nifi.util.TestRunners;
|
||||||
|
import org.apache.nifi.web.util.ssl.SslContextUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class TestListenTCPRecord {
|
public class TestListenTCPRecord {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(TestListenTCPRecord.class);
|
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" +
|
static final String SCHEMA_TEXT = "{\n" +
|
||||||
" \"name\": \"syslogRecord\",\n" +
|
" \"name\": \"syslogRecord\",\n" +
|
||||||
" \"namespace\": \"nifi\",\n" +
|
" \"namespace\": \"nifi\",\n" +
|
||||||
|
@ -91,9 +75,21 @@ public class TestListenTCPRecord {
|
||||||
DATA = Collections.unmodifiableList(data);
|
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 ListenTCPRecord proc;
|
||||||
private TestRunner runner;
|
private TestRunner runner;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void configureServices() throws TlsException {
|
||||||
|
keyStoreSslContext = SslContextUtils.createKeyStoreSslContext();
|
||||||
|
trustStoreSslContext = SslContextUtils.createTrustStoreSslContext();
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws InitializationException {
|
public void setup() throws InitializationException {
|
||||||
proc = new ListenTCPRecord();
|
proc = new ListenTCPRecord();
|
||||||
|
@ -115,10 +111,6 @@ public class TestListenTCPRecord {
|
||||||
runner.setProperty(ListenTCPRecord.RECORD_READER, readerId);
|
runner.setProperty(ListenTCPRecord.RECORD_READER, readerId);
|
||||||
runner.setProperty(ListenTCPRecord.RECORD_WRITER, writerId);
|
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
|
@Test
|
||||||
|
@ -126,7 +118,7 @@ public class TestListenTCPRecord {
|
||||||
runner.setProperty(ListenTCPRecord.PORT, "1");
|
runner.setProperty(ListenTCPRecord.PORT, "1");
|
||||||
runner.assertValid();
|
runner.assertValid();
|
||||||
|
|
||||||
configureProcessorSslContextService();
|
enableSslContextService(keyStoreSslContext);
|
||||||
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, "");
|
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, "");
|
||||||
runner.assertNotValid();
|
runner.assertNotValid();
|
||||||
|
|
||||||
|
@ -171,15 +163,11 @@ public class TestListenTCPRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTLSClientAuthRequiredAndClientCertProvided() throws InitializationException, IOException, InterruptedException, TlsException {
|
public void testTLSClientAuthRequiredAndClientCertProvided() throws InitializationException, IOException, InterruptedException {
|
||||||
|
|
||||||
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
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
|
runTCP(DATA, 1, keyStoreSslContext);
|
||||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(clientTlsConfiguration);
|
|
||||||
|
|
||||||
runTCP(DATA, 1, clientSslContext);
|
|
||||||
|
|
||||||
final List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCPRecord.REL_SUCCESS);
|
final List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCPRecord.REL_SUCCESS);
|
||||||
Assert.assertEquals(1, mockFlowFiles.size());
|
Assert.assertEquals(1, mockFlowFiles.size());
|
||||||
|
@ -192,28 +180,21 @@ public class TestListenTCPRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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.CLIENT_AUTH, ClientAuth.REQUIRED.name());
|
||||||
runner.setProperty(ListenTCPRecord.READ_TIMEOUT, "5 seconds");
|
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
|
runTCP(DATA, 0, trustStoreSslContext);
|
||||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
|
||||||
|
|
||||||
runTCP(DATA, 0, clientSslContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTLSClientAuthNoneAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException, TlsException {
|
public void testTLSClientAuthNoneAndClientCertNotProvided() throws InitializationException, IOException, InterruptedException {
|
||||||
|
|
||||||
runner.setProperty(ListenTCPRecord.CLIENT_AUTH, ClientAuth.NONE.name());
|
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
|
runTCP(DATA, 1, trustStoreSslContext);
|
||||||
final SSLContext clientSslContext = SslContextFactory.createSslContext(trustOnlyTlsConfiguration);
|
|
||||||
|
|
||||||
runTCP(DATA, 1, clientSslContext);
|
|
||||||
|
|
||||||
final List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCPRecord.REL_SUCCESS);
|
final List<MockFlowFile> mockFlowFiles = runner.getFlowFilesForRelationship(ListenTCPRecord.REL_SUCCESS);
|
||||||
Assert.assertEquals(1, mockFlowFiles.size());
|
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 static class SocketSender implements Runnable, Closeable {
|
||||||
|
|
||||||
private final int port;
|
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