Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ partition key, the query will be immediately rejected with an `InvalidQueryExcep

== How to denylist a partition key

Denylisting partitions is disabled by default. To use this feature, enable it in the `cassandra.yaml` file.

....
partition_denylist_enabled: true
....


The ``system_distributed.denylisted_partitions`` table can be used to denylist partitions.
There are a couple of ways to interact with and mutate this data. First: directly
via CQL by inserting a record with the following details:
Expand Down
16 changes: 16 additions & 0 deletions src/java/org/apache/cassandra/service/StorageProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -3637,9 +3637,16 @@ public void initialLoadPartitionDenylist()
@Override
public void loadPartitionDenylist()
{
checkPartitionDenylistEnabled();
partitionDenylist.load();
}

@Override
public boolean getPartitionDenylistEnabled()
{
return DatabaseDescriptor.getPartitionDenylistEnabled();
}

@Override
public int getPartitionDenylistLoadAttempts()
{
Expand Down Expand Up @@ -3698,6 +3705,7 @@ public void setDenylistMaxKeysTotal(int value)
@Override
public boolean denylistKey(String keyspace, String table, String partitionKeyAsString)
{
checkPartitionDenylistEnabled();
if (!Schema.instance.getKeyspaces().contains(keyspace))
return false;

Expand All @@ -3719,6 +3727,7 @@ public boolean denylistKey(String keyspace, String table, String partitionKeyAsS
@Override
public boolean removeDenylistKey(String keyspace, String table, String partitionKeyAsString)
{
checkPartitionDenylistEnabled();
if (!Schema.instance.getKeyspaces().contains(keyspace))
return false;

Expand All @@ -3735,6 +3744,7 @@ public boolean removeDenylistKey(String keyspace, String table, String partition
*/
public boolean isKeyDenylisted(String keyspace, String table, String partitionKeyAsString)
{
checkPartitionDenylistEnabled();
if (!Schema.instance.getKeyspaces().contains(keyspace))
return false;

Expand All @@ -3746,6 +3756,12 @@ public boolean isKeyDenylisted(String keyspace, String table, String partitionKe
return !partitionDenylist.isKeyPermitted(keyspace, table, bytes);
}

private void checkPartitionDenylistEnabled() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

braces on new line

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename it to ensurePartitionDenylistEnabled

if (!getPartitionDenylistEnabled()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

braces for one line is not necessary

throw new UnsupportedOperationException("Denylisting partitions is disabled");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this is the most appropriate one. This looks like the code is not there yet. RuntimeException is probably just enough.

}
}

@Override
public void logBlockingReadRepairAttemptsForNSeconds(int seconds)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public interface StorageProxyMBean
public int getOtcBacklogExpirationInterval();

public void loadPartitionDenylist();
public boolean getPartitionDenylistEnabled();
public int getPartitionDenylistLoadAttempts();
public int getPartitionDenylistLoadSuccesses();
public void setEnablePartitionDenylist(boolean enabled);
Expand Down
24 changes: 24 additions & 0 deletions test/unit/org/apache/cassandra/service/PartitionDenylistTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,30 @@ public void testGlobalLimitRespected()
confirmAllowed("table3", Integer.toString(i), Integer.toString(i));
}

@Test
public void testJmxThrowExcepitonWhenDenylistDisable() {
// Disable denylisting
DatabaseDescriptor.setPartitionDenylistEnabled(false);
// read and write work well
process("SELECT * FROM " + ks_cql + ".table1 WHERE keyone='aaa' and keytwo='bbb'", ConsistencyLevel.ONE);
process("SELECT * FROM " + ks_cql + ".table1 WHERE keyone='bbb' and keytwo='ccc'", ConsistencyLevel.ONE);
process("INSERT INTO " + ks_cql + ".table1 (keyone, keytwo, qux, quz, foo) VALUES ('eee', 'fff', 'ccc', 'ddd', 'v')", ConsistencyLevel.ONE);
process("INSERT INTO " + ks_cql + ".table1 (keyone, keytwo, qux, quz, foo) VALUES ('bbb', 'ccc', 'eee', 'fff', 'w')", ConsistencyLevel.ONE);
// when denylisting is disabled, JMX operation will throw excepiton
assertThatThrownBy(() -> denylist("table1", "foo:bar"))
.isInstanceOf(UnsupportedOperationException.class)
.hasMessageContaining("Denylisting partitions is disabled");
assertThatThrownBy(() -> refreshList())
.isInstanceOf(UnsupportedOperationException.class)
.hasMessageContaining("Denylisting partitions is disabled");
assertThatThrownBy(() -> removeDenylist(ks_cql, "table1", "foo:bar"))
.isInstanceOf(UnsupportedOperationException.class)
.hasMessageContaining("Denylisting partitions is disabled");
assertThatThrownBy(() -> StorageProxy.instance.isKeyDenylisted(ks_cql, "table1", "bbb:ccc"))
.isInstanceOf(UnsupportedOperationException.class)
.hasMessageContaining("Denylisting partitions is disabled");
}

private void confirmDenied(String table, String keyOne, String keyTwo)
{
String query = String.format("SELECT * FROM " + ks_cql + "." + table + " WHERE keyone='%s' and keytwo='%s'", keyOne, keyTwo);
Expand Down