| /* |
| * 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.cassandra.db.virtual; |
| |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Modifier; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.stream.Collectors; |
| |
| import com.google.common.collect.ImmutableList; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| import com.datastax.driver.core.ResultSet; |
| import com.datastax.driver.core.Row; |
| import org.apache.cassandra.config.Config; |
| import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.InternodeEncryption; |
| import org.apache.cassandra.config.ParameterizedClass; |
| import org.apache.cassandra.cql3.CQLTester; |
| import org.apache.cassandra.security.SSLFactory; |
| |
| public class SettingsTableTest extends CQLTester |
| { |
| private static final String KS_NAME = "vts"; |
| |
| private Config config; |
| private SettingsTable table; |
| |
| @BeforeClass |
| public static void setUpClass() |
| { |
| CQLTester.setUpClass(); |
| } |
| |
| @Before |
| public void config() |
| { |
| config = new Config(); |
| config.client_encryption_options.applyConfig(); |
| config.server_encryption_options.applyConfig(); |
| table = new SettingsTable(KS_NAME, config); |
| VirtualKeyspaceRegistry.instance.register(new VirtualKeyspace(KS_NAME, ImmutableList.of(table))); |
| } |
| |
| private String getValue(Field f) |
| { |
| Object untypedValue = table.getValue(f); |
| String value = null; |
| if (untypedValue != null) |
| { |
| if (untypedValue.getClass().isArray()) |
| { |
| value = Arrays.toString((Object[]) untypedValue); |
| } |
| else |
| value = untypedValue.toString(); |
| } |
| return value; |
| } |
| |
| @Test |
| public void testSelectAll() throws Throwable |
| { |
| int paging = (int) (Math.random() * 100 + 1); |
| ResultSet result = executeNetWithPaging("SELECT * FROM vts.settings", paging); |
| int i = 0; |
| for (Row r : result) |
| { |
| i++; |
| String name = r.getString("name"); |
| Field f = SettingsTable.FIELDS.get(name); |
| if (f != null) // skip overrides |
| Assert.assertEquals(getValue(f), r.getString("value")); |
| } |
| Assert.assertTrue(SettingsTable.FIELDS.size() <= i); |
| } |
| |
| @Test |
| public void testSelectPartition() throws Throwable |
| { |
| List<Field> fields = Arrays.stream(Config.class.getFields()) |
| .filter(f -> !Modifier.isStatic(f.getModifiers())) |
| .collect(Collectors.toList()); |
| for (Field f : fields) |
| { |
| if (table.overrides.containsKey(f.getName())) |
| continue; |
| |
| String q = "SELECT * FROM vts.settings WHERE name = '"+f.getName()+'\''; |
| assertRowsNet(executeNet(q), new Object[] {f.getName(), getValue(f)}); |
| } |
| } |
| |
| @Test |
| public void testSelectEmpty() throws Throwable |
| { |
| String q = "SELECT * FROM vts.settings WHERE name = 'EMPTY'"; |
| assertRowsNet(executeNet(q)); |
| } |
| |
| @Test |
| public void testSelectOverride() throws Throwable |
| { |
| String q = "SELECT * FROM vts.settings WHERE name = 'server_encryption_options_enabled'"; |
| assertRowsNet(executeNet(q), new Object[] {"server_encryption_options_enabled", "false"}); |
| q = "SELECT * FROM vts.settings WHERE name = 'server_encryption_options_XYZ'"; |
| assertRowsNet(executeNet(q)); |
| } |
| |
| private void check(String setting, String expected) throws Throwable |
| { |
| String q = "SELECT * FROM vts.settings WHERE name = '"+setting+'\''; |
| assertRowsNet(executeNet(q), new Object[] {setting, expected}); |
| } |
| |
| @Test |
| public void testEncryptionOverride() throws Throwable |
| { |
| String pre = "server_encryption_options_"; |
| check(pre + "enabled", "false"); |
| String all = "SELECT * FROM vts.settings WHERE " + |
| "name > 'server_encryption' AND name < 'server_encryptionz' ALLOW FILTERING"; |
| |
| Assert.assertEquals(9, executeNet(all).all().size()); |
| |
| check(pre + "algorithm", null); |
| config.server_encryption_options = config.server_encryption_options.withAlgorithm("SUPERSSL"); |
| check(pre + "algorithm", "SUPERSSL"); |
| |
| check(pre + "cipher_suites", null); |
| config.server_encryption_options = config.server_encryption_options.withCipherSuites("c1", "c2"); |
| check(pre + "cipher_suites", "[c1, c2]"); |
| |
| check(pre + "protocol", null); |
| config.server_encryption_options = config.server_encryption_options.withProtocol("TLSv5"); |
| check(pre + "protocol", "[TLSv5]"); |
| |
| config.server_encryption_options = config.server_encryption_options.withProtocol("TLS"); |
| check(pre + "protocol", SSLFactory.tlsInstanceProtocolSubstitution().toString()); |
| |
| config.server_encryption_options = config.server_encryption_options.withProtocol("TLS"); |
| config.server_encryption_options = config.server_encryption_options.withAcceptedProtocols(ImmutableList.of("TLSv1.2","TLSv1.1")); |
| check(pre + "protocol", "[TLSv1.2, TLSv1.1]"); |
| |
| config.server_encryption_options = config.server_encryption_options.withProtocol("TLSv2"); |
| config.server_encryption_options = config.server_encryption_options.withAcceptedProtocols(ImmutableList.of("TLSv1.2","TLSv1.1")); |
| check(pre + "protocol", "[TLSv1.2, TLSv1.1, TLSv2]"); // protocol goes after the explicit accept list if non-TLS |
| |
| check(pre + "optional", "false"); |
| config.server_encryption_options = config.server_encryption_options.withOptional(true); |
| check(pre + "optional", "true"); |
| |
| check(pre + "client_auth", "false"); |
| config.server_encryption_options = config.server_encryption_options.withRequireClientAuth(true); |
| check(pre + "client_auth", "true"); |
| |
| check(pre + "endpoint_verification", "false"); |
| config.server_encryption_options = config.server_encryption_options.withRequireEndpointVerification(true); |
| check(pre + "endpoint_verification", "true"); |
| |
| check(pre + "internode_encryption", "none"); |
| config.server_encryption_options = config.server_encryption_options.withInternodeEncryption(InternodeEncryption.all); |
| check(pre + "internode_encryption", "all"); |
| check(pre + "enabled", "true"); |
| |
| check(pre + "legacy_ssl_storage_port", "false"); |
| config.server_encryption_options = config.server_encryption_options.withLegacySslStoragePort(true); |
| check(pre + "legacy_ssl_storage_port", "true"); |
| } |
| |
| @Test |
| public void testAuditOverride() throws Throwable |
| { |
| String pre = "audit_logging_options_"; |
| check(pre + "enabled", "false"); |
| String all = "SELECT * FROM vts.settings WHERE " + |
| "name > 'audit_logging' AND name < 'audit_loggingz' ALLOW FILTERING"; |
| |
| config.audit_logging_options.enabled = true; |
| Assert.assertEquals(9, executeNet(all).all().size()); |
| check(pre + "enabled", "true"); |
| |
| check(pre + "logger", "BinAuditLogger"); |
| config.audit_logging_options.logger = new ParameterizedClass("logger", null); |
| check(pre + "logger", "logger"); |
| |
| config.audit_logging_options.audit_logs_dir = "dir"; |
| check(pre + "audit_logs_dir", "dir"); |
| |
| check(pre + "included_keyspaces", ""); |
| config.audit_logging_options.included_keyspaces = "included_keyspaces"; |
| check(pre + "included_keyspaces", "included_keyspaces"); |
| |
| check(pre + "excluded_keyspaces", "system,system_schema,system_virtual_schema"); |
| config.audit_logging_options.excluded_keyspaces = "excluded_keyspaces"; |
| check(pre + "excluded_keyspaces", "excluded_keyspaces"); |
| |
| check(pre + "included_categories", ""); |
| config.audit_logging_options.included_categories = "included_categories"; |
| check(pre + "included_categories", "included_categories"); |
| |
| check(pre + "excluded_categories", ""); |
| config.audit_logging_options.excluded_categories = "excluded_categories"; |
| check(pre + "excluded_categories", "excluded_categories"); |
| |
| check(pre + "included_users", ""); |
| config.audit_logging_options.included_users = "included_users"; |
| check(pre + "included_users", "included_users"); |
| |
| check(pre + "excluded_users", ""); |
| config.audit_logging_options.excluded_users = "excluded_users"; |
| check(pre + "excluded_users", "excluded_users"); |
| } |
| |
| @Test |
| public void testTransparentEncryptionOptionsOverride() throws Throwable |
| { |
| String pre = "transparent_data_encryption_options_"; |
| check(pre + "enabled", "false"); |
| String all = "SELECT * FROM vts.settings WHERE " + |
| "name > 'transparent_data_encryption_options' AND " + |
| "name < 'transparent_data_encryption_optionsz' ALLOW FILTERING"; |
| |
| config.transparent_data_encryption_options.enabled = true; |
| Assert.assertEquals(4, executeNet(all).all().size()); |
| check(pre + "enabled", "true"); |
| |
| check(pre + "cipher", "AES/CBC/PKCS5Padding"); |
| config.transparent_data_encryption_options.cipher = "cipher"; |
| check(pre + "cipher", "cipher"); |
| |
| check(pre + "chunk_length_kb", "64"); |
| config.transparent_data_encryption_options.chunk_length_kb = 5; |
| check(pre + "chunk_length_kb", "5"); |
| |
| check(pre + "iv_length", "16"); |
| config.transparent_data_encryption_options.iv_length = 7; |
| check(pre + "iv_length", "7"); |
| } |
| } |