mirror of https://github.com/apache/cassandra
Add guardrail to disallow creation of secondary indexes
Patch by Josh McKenzie; reviewed by Chris Lohfink for CASSANDRA-17498
This commit is contained in:
parent
105d69fdc5
commit
910bbb9b5f
|
|
@ -1,4 +1,5 @@
|
|||
4.1
|
||||
* Add guardrail for creation of secondary indexes (CASSANDRA-17498)
|
||||
* Add guardrail to disallow creation of uncompressed tables (CASSANDRA-17504)
|
||||
* Add guardrail to disallow creation of new COMPACT STORAGE tables (CASSANDRA-17522)
|
||||
* repair vtables should expose a completed field due to lack of filtering options in CQL (CASSANDRA-17520)
|
||||
|
|
|
|||
|
|
@ -1619,6 +1619,8 @@ drop_compact_storage_enabled: false
|
|||
# The two thresholds default to -1 to disable.
|
||||
# secondary_indexes_per_table_warn_threshold: -1
|
||||
# secondary_indexes_per_table_fail_threshold: -1
|
||||
# Guardrail to enable or disable the creation of secondary indexes
|
||||
# secondary_indexes_enabled: true
|
||||
# Guardrail to warn or fail when creating more materialized views per table than threshold.
|
||||
# The two thresholds default to -1 to disable.
|
||||
# materialized_views_per_table_warn_threshold: -1
|
||||
|
|
|
|||
|
|
@ -800,6 +800,7 @@ public class Config
|
|||
public volatile Set<ConsistencyLevel> write_consistency_levels_warned = Collections.emptySet();
|
||||
public volatile Set<ConsistencyLevel> write_consistency_levels_disallowed = Collections.emptySet();
|
||||
public volatile boolean user_timestamps_enabled = true;
|
||||
public volatile boolean secondary_indexes_enabled = true;
|
||||
public volatile boolean uncompressed_tables_enabled = true;
|
||||
public volatile boolean compact_tables_enabled = true;
|
||||
public volatile boolean read_before_write_list_operations_enabled = true;
|
||||
|
|
|
|||
|
|
@ -332,6 +332,20 @@ public class GuardrailsOptions implements GuardrailsConfig
|
|||
x -> config.user_timestamps_enabled = x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecondaryIndexesEnabled()
|
||||
{
|
||||
return config.secondary_indexes_enabled;
|
||||
}
|
||||
|
||||
public void setSecondaryIndexesEnabled(boolean enabled)
|
||||
{
|
||||
updatePropertyWithLogging("secondary_indexes_enabled",
|
||||
enabled,
|
||||
() -> config.secondary_indexes_enabled,
|
||||
x -> config.secondary_indexes_enabled = x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUncompressedTablesEnabled()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ public final class CreateIndexStatement extends AlterSchemaStatement
|
|||
{
|
||||
attrs.validate();
|
||||
|
||||
Guardrails.createSecondaryIndexesEnabled.ensureEnabled("Creating secondary indexes", state);
|
||||
|
||||
if (attrs.isCustom && attrs.customClass.equals(SASIIndex.class.getName()) && !DatabaseDescriptor.getSASIIndexesEnabled())
|
||||
throw new InvalidRequestException("SASI indexes are disabled. Enable in cassandra.yaml to use.");
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,14 @@ public final class Guardrails implements GuardrailsMBean
|
|||
: format("Tables cannot have more than %s secondary indexes, aborting the creation of secondary index %s",
|
||||
threshold, what));
|
||||
|
||||
/**
|
||||
* Guardrail disabling user's ability to create secondary indexes
|
||||
*/
|
||||
public static final DisableFlag createSecondaryIndexesEnabled =
|
||||
new DisableFlag("secondary_indexes",
|
||||
state -> !CONFIG_PROVIDER.getOrCreate(state).getSecondaryIndexesEnabled(),
|
||||
"User creation of secondary indexes");
|
||||
|
||||
/**
|
||||
* Guardrail on the number of materialized views per table.
|
||||
*/
|
||||
|
|
@ -355,6 +363,18 @@ public final class Guardrails implements GuardrailsMBean
|
|||
DEFAULT_CONFIG.setSecondaryIndexesPerTableThreshold(warn, fail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecondaryIndexesEnabled()
|
||||
{
|
||||
return DEFAULT_CONFIG.getSecondaryIndexesEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSecondaryIndexesEnabled(boolean enabled)
|
||||
{
|
||||
DEFAULT_CONFIG.setSecondaryIndexesEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaterializedViewsPerTableWarnThreshold()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -93,6 +93,11 @@ public interface GuardrailsConfig
|
|||
*/
|
||||
int getSecondaryIndexesPerTableFailThreshold();
|
||||
|
||||
/**
|
||||
* @return Whether creation of secondary indexes is allowed.
|
||||
*/
|
||||
boolean getSecondaryIndexesEnabled();
|
||||
|
||||
/**
|
||||
* @return The threshold to warn when creating more materialized views per table than threshold.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -119,6 +119,17 @@ public interface GuardrailsMBean
|
|||
*/
|
||||
void setSecondaryIndexesPerTableThreshold(int warn, int fail);
|
||||
|
||||
/**
|
||||
* @return Whether secondary index creation is active or not on the node
|
||||
*/
|
||||
boolean getSecondaryIndexesEnabled();
|
||||
|
||||
/**
|
||||
* Enables or disables the ability to create secondary indexes
|
||||
* @param enabled
|
||||
*/
|
||||
void setSecondaryIndexesEnabled(boolean enabled);
|
||||
|
||||
/**
|
||||
* @return The threshold to warn when creating more materialized views per table than threshold.
|
||||
* -1 means disabled.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.guardrails;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Tests the guardrail for disabling user creation of secondary indexes, {@link Guardrails#setSecondaryIndexesEnabled(boolean)}.
|
||||
*/
|
||||
public class GuardrailSecondaryIndexTester extends GuardrailTester
|
||||
{
|
||||
public GuardrailSecondaryIndexTester()
|
||||
{
|
||||
super(Guardrails.createSecondaryIndexesEnabled);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setupTest()
|
||||
{
|
||||
createTable("CREATE TABLE %s (k int PRIMARY KEY, v1 int, v2 int, v3 int, v4 int)");
|
||||
}
|
||||
|
||||
private void setGuardrail(boolean enabled)
|
||||
{
|
||||
guardrails().setSecondaryIndexesEnabled(enabled);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateIndex() throws Throwable
|
||||
{
|
||||
setGuardrail(true);
|
||||
assertValid(String.format("CREATE INDEX %s ON %s.%s(%s)", "v1_idx", keyspace(), currentTable(), "v1"));
|
||||
assertValid(String.format("CREATE INDEX %s ON %s.%s(%s)", "v2_idx", keyspace(), currentTable(), "v2"));
|
||||
|
||||
setGuardrail(false);
|
||||
assertFails(String.format("CREATE INDEX %s ON %s.%s(%s)", "v3_idx", keyspace(), currentTable(), "v3"), "Creating secondary indexes");
|
||||
assertFails(String.format("CREATE INDEX %s ON %s.%s(%s)", "v4_idx", keyspace(), currentTable(), "v4"), "Creating secondary indexes");
|
||||
assertFails(String.format("CREATE INDEX %s ON %s.%s(%s)", "v2_idx", keyspace(), currentTable(), "v2"), "Creating secondary indexes");
|
||||
|
||||
setGuardrail(true);
|
||||
assertValid(String.format("CREATE INDEX %s ON %s.%s(%s)", "v3_idx", keyspace(), currentTable(), "v3"));
|
||||
assertValid(String.format("CREATE INDEX %s ON %s.%s(%s)", "v4_idx", keyspace(), currentTable(), "v4"));
|
||||
|
||||
// Confirm can drop in either state
|
||||
setGuardrail(false);
|
||||
dropIndex(format("DROP INDEX %s.%s", keyspace(), "v1_idx"));
|
||||
|
||||
setGuardrail(true);
|
||||
dropIndex(format("DROP INDEX %s.%s", keyspace(), "v2_idx"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomIndex() throws Throwable
|
||||
{
|
||||
// 2i guardrail will also affect custom indexes
|
||||
setGuardrail(false);
|
||||
assertFails(format("CREATE CUSTOM INDEX ON %%s (%s) USING 'org.apache.cassandra.index.sasi.SASIIndex'", "v4"),
|
||||
format("Creating secondary indexes", currentTable())
|
||||
);
|
||||
|
||||
// Confirm custom creation will work on flip
|
||||
setGuardrail(true);
|
||||
assertValid(format("CREATE CUSTOM INDEX ON %%s (%s) USING 'org.apache.cassandra.index.sasi.SASIIndex'", "v4"));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue