blob: 3abf23ac4034790142a235338d8e0a88a066c987 [file] [log] [blame]
/*
* 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.controller.state.server;
import org.apache.commons.io.FileUtils;
import org.apache.nifi.security.util.TemporaryKeyStoreBuilder;
import org.apache.nifi.security.util.TlsConfiguration;
import org.apache.nifi.util.NiFiProperties;
import org.apache.zookeeper.server.ServerCnxnFactory;
import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
// This class tests the behaviors involved with the ZooKeeperStateServer::create method. The servers are not started,
// and TLS connections are not used.
public class TestZooKeeperStateServerConfigurations {
private static final String INSECURE_ZOOKEEPER_PROPS = getPath("insecure.zookeeper.properties");
private static final String SECURE_ZOOKEEPER_PROPS = getPath("secure.zookeeper.properties");
private static final String ZOOKEEPER_PROPERTIES_FILE_KEY = "nifi.state.management.embedded.zookeeper.properties";
private static final String ZOOKEEPER_CNXN_FACTORY = "org.apache.zookeeper.server.NettyServerCnxnFactory";
private static final Map<String, String> INSECURE_PROPS = new HashMap<String, String>() {{
put(ZOOKEEPER_PROPERTIES_FILE_KEY, INSECURE_ZOOKEEPER_PROPS);
}};
private static final Map<String, String> SECURE_NIFI_PROPS = new HashMap<>();
private static final Map<String, String> INSECURE_NIFI_PROPS = new HashMap<String, String>() {{
putAll(INSECURE_PROPS);
put(NiFiProperties.WEB_HTTP_PORT, "8080");
put(NiFiProperties.ZOOKEEPER_CLIENT_SECURE, "false");
}};
private NiFiProperties secureNiFiProps;
private NiFiProperties insecureNiFiProps;
private QuorumPeerConfig secureQuorumPeerConfig;
private QuorumPeerConfig insecureQuorumPeerConfig;
private Properties secureZooKeeperProps;
private Properties insecureZooKeeperProps;
private static TlsConfiguration tlsConfiguration;
@BeforeClass
public static void setTlsConfiguration() {
tlsConfiguration = new TemporaryKeyStoreBuilder().build();
SECURE_NIFI_PROPS.put(NiFiProperties.STATE_MANAGEMENT_ZOOKEEPER_PROPERTIES, SECURE_ZOOKEEPER_PROPS);
SECURE_NIFI_PROPS.put(NiFiProperties.WEB_HTTPS_PORT, "8443");
SECURE_NIFI_PROPS.put(NiFiProperties.SECURITY_KEYSTORE, tlsConfiguration.getKeystorePath());
SECURE_NIFI_PROPS.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, tlsConfiguration.getKeystoreType().getType());
SECURE_NIFI_PROPS.put(NiFiProperties.SECURITY_KEYSTORE_PASSWD, tlsConfiguration.getKeystorePassword());
SECURE_NIFI_PROPS.put(NiFiProperties.SECURITY_TRUSTSTORE, tlsConfiguration.getTruststorePath());
SECURE_NIFI_PROPS.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, tlsConfiguration.getTruststoreType().getType());
SECURE_NIFI_PROPS.put(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD, tlsConfiguration.getTruststorePassword());
SECURE_NIFI_PROPS.put(NiFiProperties.ZOOKEEPER_CLIENT_SECURE, "true");
}
@Before
public void setupWithValidProperties() throws IOException, QuorumPeerConfig.ConfigException {
// Secure properties setup
secureNiFiProps = NiFiProperties.createBasicNiFiProperties(null, SECURE_NIFI_PROPS);
Assert.assertNotNull(secureNiFiProps);
// This shows that a ZooKeeper server is created from valid NiFi properties:
final ZooKeeperStateServer secureZooKeeperStateServer = ZooKeeperStateServer.create(secureNiFiProps);
Assert.assertNotNull(secureZooKeeperStateServer);
secureQuorumPeerConfig = secureZooKeeperStateServer.getQuorumPeerConfig();
Assert.assertNotNull(secureQuorumPeerConfig);
secureZooKeeperProps = new Properties();
secureZooKeeperProps.load( FileUtils.openInputStream(new File(SECURE_ZOOKEEPER_PROPS)));
Assert.assertNotNull(secureZooKeeperProps);
// Insecure properties setup
insecureNiFiProps = NiFiProperties.createBasicNiFiProperties(null, INSECURE_NIFI_PROPS);
Assert.assertNotNull(insecureNiFiProps);
// This shows that a ZooKeeper server is created from valid NiFi properties:
final ZooKeeperStateServer insecureZooKeeperStateServer = ZooKeeperStateServer.create(insecureNiFiProps);
Assert.assertNotNull(insecureZooKeeperStateServer);
insecureQuorumPeerConfig = insecureZooKeeperStateServer.getQuorumPeerConfig();
Assert.assertNotNull(insecureQuorumPeerConfig);
insecureZooKeeperProps = new Properties();
insecureZooKeeperProps.load(FileUtils.openInputStream(new File(INSECURE_ZOOKEEPER_PROPS)));
Assert.assertNotNull(insecureZooKeeperProps);
}
@After
public void clearConnectionProperties() {
Collections.unmodifiableSet(System.getProperties().stringPropertyNames()).stream()
.filter(name -> name.startsWith("zookeeper."))
.forEach(System::clearProperty);
}
// This test shows that a ZooKeeperStateServer cannot be created from empty NiFi properties.
@Test
public void testCreateFromEmptyNiFiProperties() throws IOException, QuorumPeerConfig.ConfigException {
final NiFiProperties emptyProps = NiFiProperties.createBasicNiFiProperties(null, new HashMap<>());
Assert.assertNotNull(emptyProps);
Assert.assertNull(ZooKeeperStateServer.create(emptyProps));
}
// This test shows that a ZooKeeperStateServer can be created from insecure NiFi properties.
@Test
public void testCreateFromValidInsecureNiFiProperties() throws IOException, QuorumPeerConfig.ConfigException {
final NiFiProperties insecureProps = NiFiProperties.createBasicNiFiProperties(null, INSECURE_PROPS);
final ZooKeeperStateServer server = ZooKeeperStateServer.create(insecureProps);
Assert.assertNotNull(server);
Assert.assertNotNull(server.getQuorumPeerConfig().getClientPortAddress());
}
// This test shows that the client can specify a secure port and that port is used:
@Test
public void testCreateWithSpecifiedSecureClientPort() throws IOException, QuorumPeerConfig.ConfigException {
final NiFiProperties secureProps = NiFiProperties.createBasicNiFiProperties(null, new HashMap<String, String>() {{
putAll(SECURE_NIFI_PROPS);
put(ZOOKEEPER_PROPERTIES_FILE_KEY, SECURE_ZOOKEEPER_PROPS);
}});
final ZooKeeperStateServer server = ZooKeeperStateServer.create(secureProps);
Assert.assertNotNull(server);
final QuorumPeerConfig config = server.getQuorumPeerConfig();
Assert.assertEquals(secureZooKeeperProps.getProperty("secureClientPort"), String.valueOf(config.getSecureClientPortAddress().getPort()));
}
// This shows that a secure NiFi with an secure ZooKeeper will not have an insecure client address or port:
@Test
public void testCreateRemovesInsecureClientPort() {
Assert.assertNotNull(secureZooKeeperProps.getProperty("secureClientPort"));
Assert.assertNotEquals(secureZooKeeperProps.getProperty("clientPort"), "");
Assert.assertNull(secureQuorumPeerConfig.getClientPortAddress());
}
// This test shows that a connection class is set when none is specified (QuorumPeerConfig::parseProperties sets the System property):
@Test
public void testCreateWithUnspecifiedConnectionClass() {
Assert.assertEquals(org.apache.zookeeper.server.NettyServerCnxnFactory.class.getName(), System.getProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY));
}
// This test shows that a specified connection class is honored (QuorumPeerConfig::parseProperties sets the System property):
@Test
public void testCreateWithSpecifiedConnectionClass() throws IOException, QuorumPeerConfig.ConfigException {
final NiFiProperties secureProps = NiFiProperties.createBasicNiFiProperties(null, new HashMap<String, String>() {{
putAll(SECURE_NIFI_PROPS);
put(ZOOKEEPER_PROPERTIES_FILE_KEY, SECURE_ZOOKEEPER_PROPS);
}});
Assert.assertNotNull(ZooKeeperStateServer.create(secureProps));
Assert.assertEquals(ZOOKEEPER_CNXN_FACTORY, System.getProperty(ServerCnxnFactory.ZOOKEEPER_SERVER_CNXN_FACTORY));
}
private static String getPath(String path) {
return new File("src/test/resources/TestZooKeeperStateServerConfigurations/" + path).getAbsolutePath();
}
}