Repository: cassandra Updated Branches: refs/heads/trunk a827a3717 -> 16044a6f4
Make CFMetaData.triggers immutable patch by Aleksey Yeschenko; reviewed by Robert Stupp for CASSANDRA-9712 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/16044a6f Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/16044a6f Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/16044a6f Branch: refs/heads/trunk Commit: 16044a6f4c19a899172efc8b2d0ac3e4723d4c88 Parents: a827a37 Author: Aleksey Yeschenko <[email protected]> Authored: Thu Jul 2 16:46:14 2015 +0300 Committer: Aleksey Yeschenko <[email protected]> Committed: Fri Jul 10 20:08:59 2015 +0300 ---------------------------------------------------------------------- .../org/apache/cassandra/config/CFMetaData.java | 31 +---- .../cassandra/config/TriggerDefinition.java | 69 ---------- .../cql3/statements/CreateTriggerStatement.java | 22 +-- .../cql3/statements/DropTriggerStatement.java | 20 ++- .../cassandra/schema/LegacySchemaMigrator.java | 13 +- .../apache/cassandra/schema/SchemaKeyspace.java | 51 ++++--- .../cassandra/schema/TriggerMetadata.java | 72 ++++++++++ .../org/apache/cassandra/schema/Triggers.java | 137 +++++++++++++++++++ .../cassandra/thrift/ThriftConversion.java | 21 +-- .../cassandra/triggers/TriggerExecutor.java | 9 +- .../cql3/validation/operations/CreateTest.java | 46 +++---- .../schema/LegacySchemaMigratorTest.java | 8 +- .../cassandra/triggers/TriggerExecutorTest.java | 24 ++-- .../cassandra/triggers/TriggersSchemaTest.java | 26 ++-- 14 files changed, 348 insertions(+), 201 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/config/CFMetaData.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java index f3c8bc1..53d2171 100644 --- a/src/java/org/apache/cassandra/config/CFMetaData.java +++ b/src/java/org/apache/cassandra/config/CFMetaData.java @@ -49,6 +49,7 @@ import org.apache.cassandra.io.compress.CompressionParameters; import org.apache.cassandra.io.compress.LZ4Compressor; import org.apache.cassandra.io.util.DataOutputPlus; import org.apache.cassandra.schema.SchemaKeyspace; +import org.apache.cassandra.schema.Triggers; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.UUIDGen; @@ -190,8 +191,8 @@ public final class CFMetaData private volatile int memtableFlushPeriod = 0; private volatile int defaultTimeToLive = DEFAULT_DEFAULT_TIME_TO_LIVE; private volatile SpeculativeRetry speculativeRetry = DEFAULT_SPECULATIVE_RETRY; - private volatile Map<ColumnIdentifier, DroppedColumn> droppedColumns = new HashMap(); - private volatile Map<String, TriggerDefinition> triggers = new HashMap<>(); + private volatile Map<ColumnIdentifier, DroppedColumn> droppedColumns = new HashMap<>(); + private volatile Triggers triggers = Triggers.none(); private volatile boolean isPurged = false; /* * All CQL3 columns definition are stored in the columnMetadata map. @@ -237,7 +238,7 @@ public final class CFMetaData public CFMetaData defaultTimeToLive(int prop) {defaultTimeToLive = prop; return this;} public CFMetaData speculativeRetry(SpeculativeRetry prop) {speculativeRetry = prop; return this;} public CFMetaData droppedColumns(Map<ColumnIdentifier, DroppedColumn> cols) {droppedColumns = cols; return this;} - public CFMetaData triggers(Map<String, TriggerDefinition> prop) {triggers = prop; return this;} + public CFMetaData triggers(Triggers prop) {triggers = prop; return this;} private CFMetaData(String keyspace, String name, @@ -352,7 +353,7 @@ public final class CFMetaData return CFMetaData.Builder.create(keyspace, name).addPartitionKey("key", BytesType.instance).build(); } - public Map<String, TriggerDefinition> getTriggers() + public Triggers getTriggers() { return triggers; } @@ -467,7 +468,7 @@ public final class CFMetaData .speculativeRetry(oldCFMD.speculativeRetry) .memtableFlushPeriod(oldCFMD.memtableFlushPeriod) .droppedColumns(new HashMap<>(oldCFMD.droppedColumns)) - .triggers(new HashMap<>(oldCFMD.triggers)); + .triggers(oldCFMD.triggers); } /** @@ -1198,24 +1199,6 @@ public final class CFMetaData return removed; } - public void addTriggerDefinition(TriggerDefinition def) throws InvalidRequestException - { - if (containsTriggerDefinition(def)) - throw new InvalidRequestException( - String.format("Cannot create trigger %s, a trigger with the same name already exists", def.name)); - triggers.put(def.name, def); - } - - public boolean containsTriggerDefinition(TriggerDefinition def) - { - return triggers.containsKey(def.name); - } - - public boolean removeTrigger(String name) - { - return triggers.remove(name) != null; - } - public void recordColumnDrop(ColumnDefinition def) { droppedColumns.put(def.name, new DroppedColumn(def.type, FBUtilities.timestampMicros())); @@ -1366,7 +1349,7 @@ public final class CFMetaData .append("maxIndexInterval", maxIndexInterval) .append("speculativeRetry", speculativeRetry) .append("droppedColumns", droppedColumns) - .append("triggers", triggers.values()) + .append("triggers", triggers) .toString(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/config/TriggerDefinition.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/config/TriggerDefinition.java b/src/java/org/apache/cassandra/config/TriggerDefinition.java deleted file mode 100644 index 6a84379..0000000 --- a/src/java/org/apache/cassandra/config/TriggerDefinition.java +++ /dev/null @@ -1,69 +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.cassandra.config; - -import com.google.common.base.Objects; - -public class TriggerDefinition -{ - public static final String CLASS = "class"; - - public final String name; - - // For now, the only supported option is 'class'. - // Proper trigger parametrization will be added later. - public final String classOption; - - public TriggerDefinition(String name, String classOption) - { - this.name = name; - this.classOption = classOption; - } - - public static TriggerDefinition create(String name, String classOption) - { - return new TriggerDefinition(name, classOption); - } - - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - - if (!(o instanceof TriggerDefinition)) - return false; - - TriggerDefinition td = (TriggerDefinition) o; - - return Objects.equal(name, td.name) && Objects.equal(classOption, td.classOption); - } - - @Override - public int hashCode() - { - return Objects.hashCode(name, classOption); - } - - @Override - public String toString() - { - return Objects.toStringHelper(this).add("name", name).add("classOption", classOption).toString(); - } -} http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java index 6ebe0d3..c2d5616 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java @@ -22,12 +22,13 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.Schema; -import org.apache.cassandra.config.TriggerDefinition; import org.apache.cassandra.cql3.CFName; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.exceptions.UnauthorizedException; +import org.apache.cassandra.schema.TriggerMetadata; +import org.apache.cassandra.schema.Triggers; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.thrift.ThriftValidation; @@ -71,17 +72,20 @@ public class CreateTriggerStatement extends SchemaAlteringStatement public boolean announceMigration(boolean isLocalOnly) throws ConfigurationException, InvalidRequestException { CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), columnFamily()).copy(); + Triggers triggers = cfm.getTriggers(); - TriggerDefinition triggerDefinition = TriggerDefinition.create(triggerName, triggerClass); - - if (!ifNotExists || !cfm.containsTriggerDefinition(triggerDefinition)) + if (triggers.get(triggerName).isPresent()) { - cfm.addTriggerDefinition(triggerDefinition); - logger.info("Adding trigger with name {} and class {}", triggerName, triggerClass); - MigrationManager.announceColumnFamilyUpdate(cfm, false, isLocalOnly); - return true; + if (ifNotExists) + return false; + else + throw new InvalidRequestException(String.format("Trigger %s already exists", triggerName)); } - return false; + + cfm.triggers(triggers.with(TriggerMetadata.create(triggerName, triggerClass))); + logger.info("Adding trigger with name {} and class {}", triggerName, triggerClass); + MigrationManager.announceColumnFamilyUpdate(cfm, false, isLocalOnly); + return true; } public Event.SchemaChange changeEvent() http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java index e3db1e1..54711de 100644 --- a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java @@ -27,6 +27,7 @@ import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.exceptions.RequestValidationException; import org.apache.cassandra.exceptions.UnauthorizedException; +import org.apache.cassandra.schema.Triggers; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.MigrationManager; import org.apache.cassandra.thrift.ThriftValidation; @@ -60,15 +61,20 @@ public class DropTriggerStatement extends SchemaAlteringStatement public boolean announceMigration(boolean isLocalOnly) throws ConfigurationException, InvalidRequestException { CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), columnFamily()).copy(); - if (cfm.removeTrigger(triggerName)) + Triggers triggers = cfm.getTriggers(); + + if (!triggers.get(triggerName).isPresent()) { - logger.info("Dropping trigger with name {}", triggerName); - MigrationManager.announceColumnFamilyUpdate(cfm, false, isLocalOnly); - return true; + if (ifExists) + return false; + else + throw new InvalidRequestException(String.format("Trigger %s was not found", triggerName)); } - if (!ifExists) - throw new InvalidRequestException(String.format("Trigger %s was not found", triggerName)); - return false; + + logger.info("Dropping trigger with name {}", triggerName); + cfm.triggers(triggers.without(triggerName)); + MigrationManager.announceColumnFamilyUpdate(cfm, false, isLocalOnly); + return true; } public Event.SchemaChange changeEvent() http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java b/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java index a049194..4748820 100644 --- a/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java +++ b/src/java/org/apache/cassandra/schema/LegacySchemaMigrator.java @@ -337,7 +337,7 @@ public final class LegacySchemaMigrator addDroppedColumns(cfm, tableRow.getMap("dropped_columns", UTF8Type.instance, LongType.instance), types); } - triggerRows.forEach(row -> cfm.addTriggerDefinition(readTrigger(row))); + cfm.triggers(createTriggersFromTriggerRows(triggerRows)); return cfm; } @@ -479,11 +479,18 @@ public final class LegacySchemaMigrator return Enum.valueOf(ColumnDefinition.Kind.class, kind.toUpperCase()); } - private static TriggerDefinition readTrigger(UntypedResultSet.Row row) + private static Triggers createTriggersFromTriggerRows(UntypedResultSet rows) + { + Triggers.Builder triggers = org.apache.cassandra.schema.Triggers.builder(); + rows.forEach(row -> triggers.add(createTriggerFromTriggerRow(row))); + return triggers.build(); + } + + private static TriggerMetadata createTriggerFromTriggerRow(UntypedResultSet.Row row) { String name = row.getString("trigger_name"); String classOption = row.getMap("trigger_options", UTF8Type.instance, UTF8Type.instance).get("class"); - return new TriggerDefinition(name, classOption); + return new TriggerMetadata(name, classOption); } /* http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/schema/SchemaKeyspace.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java index 0e40ed2..5aad59f 100644 --- a/src/java/org/apache/cassandra/schema/SchemaKeyspace.java +++ b/src/java/org/apache/cassandra/schema/SchemaKeyspace.java @@ -764,7 +764,7 @@ public final class SchemaKeyspace private static Types createTypesFromPartition(RowIterator partition) { - String query = String.format("SELECT * FROM %s.%s", SchemaKeyspace.NAME, TYPES); + String query = String.format("SELECT * FROM %s.%s", NAME, TYPES); Types.Builder types = org.apache.cassandra.schema.Types.builder(); QueryProcessor.resultify(query, partition).forEach(row -> types.add(createTypeFromRow(row))); return types.build(); @@ -859,7 +859,7 @@ public final class SchemaKeyspace for (ColumnDefinition column : table.allColumns()) addColumnToSchemaMutation(table, column, timestamp, mutation); - for (TriggerDefinition trigger : table.getTriggers().values()) + for (TriggerMetadata trigger : table.getTriggers()) addTriggerToSchemaMutation(table, trigger, timestamp, mutation); } @@ -898,19 +898,30 @@ public final class SchemaKeyspace for (ByteBuffer name : columnDiff.entriesDiffering().keySet()) addColumnToSchemaMutation(newTable, newTable.getColumnDefinition(name), timestamp, mutation); - MapDifference<String, TriggerDefinition> triggerDiff = Maps.difference(oldTable.getTriggers(), newTable.getTriggers()); + MapDifference<String, TriggerMetadata> triggerDiff = triggersDiff(oldTable.getTriggers(), newTable.getTriggers()); // dropped triggers - for (TriggerDefinition trigger : triggerDiff.entriesOnlyOnLeft().values()) + for (TriggerMetadata trigger : triggerDiff.entriesOnlyOnLeft().values()) dropTriggerFromSchemaMutation(oldTable, trigger, timestamp, mutation); // newly created triggers - for (TriggerDefinition trigger : triggerDiff.entriesOnlyOnRight().values()) + for (TriggerMetadata trigger : triggerDiff.entriesOnlyOnRight().values()) addTriggerToSchemaMutation(newTable, trigger, timestamp, mutation); return mutation; } + private static MapDifference<String, TriggerMetadata> triggersDiff(Triggers before, Triggers after) + { + Map<String, TriggerMetadata> beforeMap = new HashMap<>(); + before.forEach(t -> beforeMap.put(t.name, t)); + + Map<String, TriggerMetadata> afterMap = new HashMap<>(); + after.forEach(t -> afterMap.put(t.name, t)); + + return Maps.difference(beforeMap, afterMap); + } + public static Mutation makeDropTableMutation(KeyspaceMetadata keyspace, CFMetaData table, long timestamp) { // Include the serialized keyspace in case the target node missed a CREATE KEYSPACE migration (see CASSANDRA-5631). @@ -921,7 +932,7 @@ public final class SchemaKeyspace for (ColumnDefinition column : table.allColumns()) dropColumnFromSchemaMutation(table, column, timestamp, mutation); - for (TriggerDefinition trigger : table.getTriggers().values()) + for (TriggerMetadata trigger : table.getTriggers()) dropTriggerFromSchemaMutation(table, trigger, timestamp, mutation); return mutation; @@ -979,9 +990,7 @@ public final class SchemaKeyspace CFMetaData cfm = readSchemaPartitionForTableAndApply(COLUMNS, ksName, cfName, partition -> createTableFromTableRowAndColumnsPartition(result, partition)); - readSchemaPartitionForTableAndApply(TRIGGERS, ksName, cfName, - partition -> { createTriggersFromTriggersPartition(partition).forEach(cfm::addTriggerDefinition); return null; } - ); + readSchemaPartitionForTableAndApply(TRIGGERS, ksName, cfName, partition -> cfm.triggers(createTriggersFromTriggersPartition(partition))); return cfm; } @@ -1248,7 +1257,7 @@ public final class SchemaKeyspace * Trigger metadata serialization/deserialization. */ - private static void addTriggerToSchemaMutation(CFMetaData table, TriggerDefinition trigger, long timestamp, Mutation mutation) + private static void addTriggerToSchemaMutation(CFMetaData table, TriggerMetadata trigger, long timestamp, Mutation mutation) { new RowUpdateBuilder(Triggers, timestamp, mutation) .clustering(table.cfName, trigger.name) @@ -1256,7 +1265,7 @@ public final class SchemaKeyspace .build(); } - private static void dropTriggerFromSchemaMutation(CFMetaData table, TriggerDefinition trigger, long timestamp, Mutation mutation) + private static void dropTriggerFromSchemaMutation(CFMetaData table, TriggerMetadata trigger, long timestamp, Mutation mutation) { RowUpdateBuilder.deleteRow(Triggers, timestamp, mutation, table.cfName, trigger.name); } @@ -1267,17 +1276,19 @@ public final class SchemaKeyspace * @param partition storage-level partition containing the trigger definitions * @return the list of processed TriggerDefinitions */ - private static List<TriggerDefinition> createTriggersFromTriggersPartition(RowIterator partition) + private static Triggers createTriggersFromTriggersPartition(RowIterator partition) { - List<TriggerDefinition> triggers = new ArrayList<>(); + Triggers.Builder triggers = org.apache.cassandra.schema.Triggers.builder(); String query = String.format("SELECT * FROM %s.%s", NAME, TRIGGERS); - for (UntypedResultSet.Row row : QueryProcessor.resultify(query, partition)) - { - String name = row.getString("trigger_name"); - String classOption = row.getMap("trigger_options", UTF8Type.instance, UTF8Type.instance).get("class"); - triggers.add(new TriggerDefinition(name, classOption)); - } - return triggers; + QueryProcessor.resultify(query, partition).forEach(row -> triggers.add(createTriggerFromTriggerRow(row))); + return triggers.build(); + } + + private static TriggerMetadata createTriggerFromTriggerRow(UntypedResultSet.Row row) + { + String name = row.getString("trigger_name"); + String classOption = row.getMap("trigger_options", UTF8Type.instance, UTF8Type.instance).get("class"); + return new TriggerMetadata(name, classOption); } /* http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/schema/TriggerMetadata.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/schema/TriggerMetadata.java b/src/java/org/apache/cassandra/schema/TriggerMetadata.java new file mode 100644 index 0000000..2e0d547 --- /dev/null +++ b/src/java/org/apache/cassandra/schema/TriggerMetadata.java @@ -0,0 +1,72 @@ +/* + * 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.schema; + +import com.google.common.base.Objects; + +public final class TriggerMetadata +{ + public static final String CLASS = "class"; + + public final String name; + + // For now, the only supported option is 'class'. + // Proper trigger parametrization will be added later. + public final String classOption; + + public TriggerMetadata(String name, String classOption) + { + this.name = name; + this.classOption = classOption; + } + + public static TriggerMetadata create(String name, String classOption) + { + return new TriggerMetadata(name, classOption); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + + if (!(o instanceof TriggerMetadata)) + return false; + + TriggerMetadata td = (TriggerMetadata) o; + + return name.equals(td.name) && classOption.equals(td.classOption); + } + + @Override + public int hashCode() + { + return Objects.hashCode(name, classOption); + } + + @Override + public String toString() + { + return Objects.toStringHelper(this) + .add("name", name) + .add("class", classOption) + .toString(); + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/schema/Triggers.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/schema/Triggers.java b/src/java/org/apache/cassandra/schema/Triggers.java new file mode 100644 index 0000000..bb39f1f --- /dev/null +++ b/src/java/org/apache/cassandra/schema/Triggers.java @@ -0,0 +1,137 @@ +/* + * 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.schema; + +import java.util.Iterator; +import java.util.Optional; + +import com.google.common.collect.ImmutableMap; + +import static com.google.common.collect.Iterables.filter; + +public final class Triggers implements Iterable<TriggerMetadata> +{ + private final ImmutableMap<String, TriggerMetadata> triggers; + + private Triggers(Builder builder) + { + triggers = builder.triggers.build(); + } + + public static Builder builder() + { + return new Builder(); + } + + public static Triggers none() + { + return builder().build(); + } + + public Iterator<TriggerMetadata> iterator() + { + return triggers.values().iterator(); + } + + public int size() + { + return triggers.size(); + } + + public boolean isEmpty() + { + return triggers.isEmpty(); + } + + /** + * Get the trigger with the specified name + * + * @param name a non-qualified trigger name + * @return an empty {@link Optional} if the trigger name is not found; a non-empty optional of {@link TriggerMetadata} otherwise + */ + public Optional<TriggerMetadata> get(String name) + { + return Optional.ofNullable(triggers.get(name)); + } + + /** + * Create a Triggers instance with the provided trigger added + */ + public Triggers with(TriggerMetadata trigger) + { + if (get(trigger.name).isPresent()) + throw new IllegalStateException(String.format("Trigger %s already exists", trigger.name)); + + return builder().add(this).add(trigger).build(); + } + + /** + * Creates a Triggers instance with the trigger with the provided name removed + */ + public Triggers without(String name) + { + TriggerMetadata trigger = + get(name).orElseThrow(() -> new IllegalStateException(String.format("Trigger %s doesn't exists", name))); + + return builder().add(filter(this, t -> t != trigger)).build(); + } + + @Override + public boolean equals(Object o) + { + return this == o || (o instanceof Triggers && triggers.equals(((Triggers) o).triggers)); + } + + @Override + public int hashCode() + { + return triggers.hashCode(); + } + + @Override + public String toString() + { + return triggers.values().toString(); + } + + public static final class Builder + { + final ImmutableMap.Builder<String, TriggerMetadata> triggers = new ImmutableMap.Builder<>(); + + private Builder() + { + } + + public Triggers build() + { + return new Triggers(this); + } + + public Builder add(TriggerMetadata trigger) + { + triggers.put(trigger.name, trigger); + return this; + } + + public Builder add(Iterable<TriggerMetadata> triggers) + { + triggers.forEach(this::add); + return this; + } + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/thrift/ThriftConversion.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/thrift/ThriftConversion.java b/src/java/org/apache/cassandra/thrift/ThriftConversion.java index 3e0c8f4..2b210e9 100644 --- a/src/java/org/apache/cassandra/thrift/ThriftConversion.java +++ b/src/java/org/apache/cassandra/thrift/ThriftConversion.java @@ -42,6 +42,8 @@ import org.apache.cassandra.schema.KeyspaceMetadata; import org.apache.cassandra.schema.KeyspaceParams; import org.apache.cassandra.schema.SchemaKeyspace; import org.apache.cassandra.schema.Tables; +import org.apache.cassandra.schema.TriggerMetadata; +import org.apache.cassandra.schema.Triggers; import org.apache.cassandra.serializers.MarshalException; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.UUIDGen; @@ -463,7 +465,7 @@ public class ThriftConversion def.setCells_per_row_to_cache(cfm.getCaching().toThriftCellsPerRow()); def.setDefault_time_to_live(cfm.getDefaultTimeToLive()); def.setSpeculative_retry(cfm.getSpeculativeRetry().toString()); - def.setTriggers(triggerDefinitionsToThrift(cfm.getTriggers().values())); + def.setTriggers(triggerDefinitionsToThrift(cfm.getTriggers())); return def; } @@ -542,23 +544,22 @@ public class ThriftConversion return thriftDefs; } - private static Map<String, TriggerDefinition> triggerDefinitionsFromThrift(List<TriggerDef> thriftDefs) + private static Triggers triggerDefinitionsFromThrift(List<TriggerDef> thriftDefs) { - Map<String, TriggerDefinition> triggerDefinitions = new HashMap<>(); + Triggers.Builder triggers = Triggers.builder(); for (TriggerDef thriftDef : thriftDefs) - triggerDefinitions.put(thriftDef.getName(), - new TriggerDefinition(thriftDef.getName(), thriftDef.getOptions().get(TriggerDefinition.CLASS))); - return triggerDefinitions; + triggers.add(new TriggerMetadata(thriftDef.getName(), thriftDef.getOptions().get(TriggerMetadata.CLASS))); + return triggers.build(); } - private static List<TriggerDef> triggerDefinitionsToThrift(Collection<TriggerDefinition> triggers) + private static List<TriggerDef> triggerDefinitionsToThrift(Triggers triggers) { - List<TriggerDef> thriftDefs = new ArrayList<>(triggers.size()); - for (TriggerDefinition def : triggers) + List<TriggerDef> thriftDefs = new ArrayList<>(); + for (TriggerMetadata def : triggers) { TriggerDef td = new TriggerDef(); td.setName(def.name); - td.setOptions(Collections.singletonMap(TriggerDefinition.CLASS, def.classOption)); + td.setOptions(Collections.singletonMap(TriggerMetadata.CLASS, def.classOption)); thriftDefs.add(td); } return thriftDefs; http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/src/java/org/apache/cassandra/triggers/TriggerExecutor.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/triggers/TriggerExecutor.java b/src/java/org/apache/cassandra/triggers/TriggerExecutor.java index 071a973..d75d2f1 100644 --- a/src/java/org/apache/cassandra/triggers/TriggerExecutor.java +++ b/src/java/org/apache/cassandra/triggers/TriggerExecutor.java @@ -28,12 +28,12 @@ import com.google.common.collect.Lists; import com.google.common.collect.ListMultimap; import com.google.common.collect.Maps; -import org.apache.cassandra.config.TriggerDefinition; import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.db.*; import org.apache.cassandra.db.partitions.PartitionUpdate; -import org.apache.cassandra.db.marshal.AbstractType; import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.schema.TriggerMetadata; +import org.apache.cassandra.schema.Triggers; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; @@ -72,7 +72,6 @@ public class TriggerExecutor * key as the primary update; if not, InvalidRequestException is thrown. If no * additional mutations are generated, the original updates are returned unmodified. * - * @param key partition key for the update * @param updates partition update to be applied, contains the merge of the original * update and any generated mutations * @return the final update to be applied, the original update merged with any @@ -211,14 +210,14 @@ public class TriggerExecutor */ private List<Mutation> executeInternal(PartitionUpdate update) { - Map<String, TriggerDefinition> triggers = update.metadata().getTriggers(); + Triggers triggers = update.metadata().getTriggers(); if (triggers.isEmpty()) return null; List<Mutation> tmutations = Lists.newLinkedList(); Thread.currentThread().setContextClassLoader(customClassLoader); try { - for (TriggerDefinition td : triggers.values()) + for (TriggerMetadata td : triggers) { ITrigger trigger = cachedTriggers.get(td.classOption); if (trigger == null) http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java index 18f2db4..053d291 100644 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/CreateTest.java @@ -18,17 +18,14 @@ package org.apache.cassandra.cql3.validation.operations; -import java.nio.ByteBuffer; import java.util.Collection; import java.util.Collections; import java.util.UUID; -import org.junit.Assert; import org.junit.Test; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.Schema; -import org.apache.cassandra.config.TriggerDefinition; import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.db.Mutation; import org.apache.cassandra.db.partitions.Partition; @@ -403,12 +400,12 @@ public class CreateTest extends CQLTester { createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))"); execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("trigger_1", TestTrigger.class); + assertTriggerExists("trigger_1"); execute("CREATE TRIGGER trigger_2 ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("trigger_2", TestTrigger.class); + assertTriggerExists("trigger_2"); assertInvalid("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'"); execute("CREATE TRIGGER \"Trigger 3\" ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("Trigger 3", TestTrigger.class); + assertTriggerExists("Trigger 3"); } @Test @@ -417,10 +414,10 @@ public class CreateTest extends CQLTester createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))"); execute("CREATE TRIGGER IF NOT EXISTS trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("trigger_1", TestTrigger.class); + assertTriggerExists("trigger_1"); execute("CREATE TRIGGER IF NOT EXISTS trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("trigger_1", TestTrigger.class); + assertTriggerExists("trigger_1"); } @Test @@ -429,21 +426,21 @@ public class CreateTest extends CQLTester createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))"); execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("trigger_1", TestTrigger.class); + assertTriggerExists("trigger_1"); execute("DROP TRIGGER trigger_1 ON %s"); - assertTriggerDoesNotExists("trigger_1", TestTrigger.class); + assertTriggerDoesNotExists("trigger_1"); execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("trigger_1", TestTrigger.class); + assertTriggerExists("trigger_1"); assertInvalid("DROP TRIGGER trigger_2 ON %s"); execute("CREATE TRIGGER \"Trigger 3\" ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("Trigger 3", TestTrigger.class); + assertTriggerExists("Trigger 3"); execute("DROP TRIGGER \"Trigger 3\" ON %s"); - assertTriggerDoesNotExists("Trigger 3", TestTrigger.class); + assertTriggerDoesNotExists("Trigger 3"); } @Test @@ -452,13 +449,13 @@ public class CreateTest extends CQLTester createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))"); execute("DROP TRIGGER IF EXISTS trigger_1 ON %s"); - assertTriggerDoesNotExists("trigger_1", TestTrigger.class); + assertTriggerDoesNotExists("trigger_1"); execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'"); - assertTriggerExists("trigger_1", TestTrigger.class); + assertTriggerExists("trigger_1"); execute("DROP TRIGGER IF EXISTS trigger_1 ON %s"); - assertTriggerDoesNotExists("trigger_1", TestTrigger.class); + assertTriggerDoesNotExists("trigger_1"); } @Test @@ -497,26 +494,23 @@ public class CreateTest extends CQLTester // tests CASSANDRA-9565 public void testDoubleWith() throws Throwable { - String[] stmts = new String[] { "CREATE KEYSPACE WITH WITH DURABLE_WRITES = true", - "CREATE KEYSPACE ks WITH WITH DURABLE_WRITES = true" }; + String[] stmts = { "CREATE KEYSPACE WITH WITH DURABLE_WRITES = true", + "CREATE KEYSPACE ks WITH WITH DURABLE_WRITES = true" }; - for (String stmt : stmts) { + for (String stmt : stmts) assertInvalidSyntaxMessage("no viable alternative at input 'WITH'", stmt); - } } - private void assertTriggerExists(String name, Class<?> clazz) + private void assertTriggerExists(String name) { CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), currentTable()).copy(); - assertTrue("the trigger does not exist", cfm.containsTriggerDefinition(TriggerDefinition.create(name, - clazz.getName()))); + assertTrue("the trigger does not exist", cfm.getTriggers().get(name).isPresent()); } - private void assertTriggerDoesNotExists(String name, Class<?> clazz) + private void assertTriggerDoesNotExists(String name) { CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), currentTable()).copy(); - Assert.assertFalse("the trigger exists", cfm.containsTriggerDefinition(TriggerDefinition.create(name, - clazz.getName()))); + assertFalse("the trigger exists", cfm.getTriggers().get(name).isPresent()); } public static class TestTrigger implements ITrigger http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java index b4149a0..17cffaf 100644 --- a/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java +++ b/test/unit/org/apache/cassandra/schema/LegacySchemaMigratorTest.java @@ -248,9 +248,11 @@ public class LegacySchemaMigratorTest { String keyspace = KEYSPACE_PREFIX + "Triggers"; + Triggers.Builder triggers = Triggers.builder(); CFMetaData table = SchemaLoader.standardCFMD(keyspace, "WithTriggers"); for (int i = 0; i < 10; i++) - table.addTriggerDefinition(new TriggerDefinition("trigger" + i, "DummyTrigger" + i)); + triggers.add(new TriggerMetadata("trigger" + i, "DummyTrigger" + i)); + table.triggers(triggers.build()); return KeyspaceMetadata.create(keyspace, KeyspaceParams.simple(1), Tables.of(table)); } @@ -418,7 +420,7 @@ public class LegacySchemaMigratorTest for (ColumnDefinition column : table.allColumns()) addColumnToSchemaMutation(table, column, timestamp, mutation); - for (TriggerDefinition trigger : table.getTriggers().values()) + for (TriggerMetadata trigger : table.getTriggers()) addTriggerToSchemaMutation(table, trigger, timestamp, mutation); } @@ -451,7 +453,7 @@ public class LegacySchemaMigratorTest return kind.toString().toLowerCase(); } - private static void addTriggerToSchemaMutation(CFMetaData table, TriggerDefinition trigger, long timestamp, Mutation mutation) + private static void addTriggerToSchemaMutation(CFMetaData table, TriggerMetadata trigger, long timestamp, Mutation mutation) { new RowUpdateBuilder(SystemKeyspace.LegacyTriggers, timestamp, mutation) .clustering(table.cfName, trigger.name) http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/test/unit/org/apache/cassandra/triggers/TriggerExecutorTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/triggers/TriggerExecutorTest.java b/test/unit/org/apache/cassandra/triggers/TriggerExecutorTest.java index a5d79d3..0cf7491 100644 --- a/test/unit/org/apache/cassandra/triggers/TriggerExecutorTest.java +++ b/test/unit/org/apache/cassandra/triggers/TriggerExecutorTest.java @@ -23,7 +23,6 @@ import org.junit.Test; import org.apache.cassandra.Util; import org.apache.cassandra.config.CFMetaData; -import org.apache.cassandra.config.TriggerDefinition; import org.apache.cassandra.db.*; import org.apache.cassandra.db.rows.UnfilteredRowIterators; import org.apache.cassandra.db.rows.Cell; @@ -34,6 +33,7 @@ import org.apache.cassandra.db.partitions.Partition; import org.apache.cassandra.db.partitions.PartitionUpdate; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.schema.TriggerMetadata; import org.apache.cassandra.utils.FBUtilities; import static org.apache.cassandra.utils.ByteBufferUtil.bytes; @@ -46,7 +46,7 @@ public class TriggerExecutorTest @Test public void sameKeySameCfColumnFamilies() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", SameKeySameCfTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", SameKeySameCfTrigger.class.getName())); PartitionUpdate mutated = TriggerExecutor.instance.execute(makeCf(metadata, "k1", "v1", null)); RowIterator rowIterator = UnfilteredRowIterators.filter(mutated.unfilteredIterator(), FBUtilities.nowInSeconds()); @@ -60,21 +60,21 @@ public class TriggerExecutorTest @Test(expected = InvalidRequestException.class) public void sameKeyDifferentCfColumnFamilies() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", SameKeyDifferentCfTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", SameKeyDifferentCfTrigger.class.getName())); TriggerExecutor.instance.execute(makeCf(metadata, "k1", "v1", null)); } @Test(expected = InvalidRequestException.class) public void differentKeyColumnFamilies() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", DifferentKeyTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", DifferentKeyTrigger.class.getName())); TriggerExecutor.instance.execute(makeCf(metadata, "k1", "v1", null)); } @Test public void noTriggerMutations() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", NoOpTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", NoOpTrigger.class.getName())); Mutation rm = new Mutation(makeCf(metadata, "k1", "v1", null)); assertNull(TriggerExecutor.instance.execute(Collections.singletonList(rm))); } @@ -82,7 +82,7 @@ public class TriggerExecutorTest @Test public void sameKeySameCfRowMutations() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", SameKeySameCfTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", SameKeySameCfTrigger.class.getName())); PartitionUpdate cf1 = makeCf(metadata, "k1", "k1v1", null); PartitionUpdate cf2 = makeCf(metadata, "k2", "k2v1", null); Mutation rm1 = new Mutation("ks1", cf1.partitionKey()).add(cf1); @@ -108,7 +108,7 @@ public class TriggerExecutorTest @Test public void sameKeySameCfPartialRowMutations() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", SameKeySameCfPartialTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", SameKeySameCfPartialTrigger.class.getName())); PartitionUpdate cf1 = makeCf(metadata, "k1", "k1v1", null); PartitionUpdate cf2 = makeCf(metadata, "k2", "k2v1", null); Mutation rm1 = new Mutation("ks1", cf1.partitionKey()).add(cf1); @@ -134,7 +134,7 @@ public class TriggerExecutorTest @Test public void sameKeyDifferentCfRowMutations() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", SameKeyDifferentCfTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", SameKeyDifferentCfTrigger.class.getName())); PartitionUpdate cf1 = makeCf(metadata, "k1", "k1v1", null); PartitionUpdate cf2 = makeCf(metadata, "k2", "k2v1", null); Mutation rm1 = new Mutation("ks1", cf1.partitionKey()).add(cf1); @@ -185,7 +185,7 @@ public class TriggerExecutorTest @Test public void sameKeyDifferentKsRowMutations() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", SameKeyDifferentKsTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", SameKeyDifferentKsTrigger.class.getName())); PartitionUpdate cf1 = makeCf(metadata, "k1", "k1v1", null); PartitionUpdate cf2 = makeCf(metadata, "k2", "k2v1", null); Mutation rm1 = new Mutation("ks1", cf1.partitionKey()).add(cf1); @@ -224,7 +224,7 @@ public class TriggerExecutorTest public void differentKeyRowMutations() throws ConfigurationException, InvalidRequestException { - CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerDefinition.create("test", DifferentKeyTrigger.class.getName())); + CFMetaData metadata = makeCfMetaData("ks1", "cf1", TriggerMetadata.create("test", DifferentKeyTrigger.class.getName())); PartitionUpdate cf1 = makeCf(metadata, "k1", "v1", null); Mutation rm = new Mutation("ks1", cf1.partitionKey()).add(cf1); @@ -248,7 +248,7 @@ public class TriggerExecutorTest assertNull(row.getCell(metadata.getColumnDefinition(bytes("c1")))); } - private static CFMetaData makeCfMetaData(String ks, String cf, TriggerDefinition trigger) + private static CFMetaData makeCfMetaData(String ks, String cf, TriggerMetadata trigger) { CFMetaData metadata = CFMetaData.Builder.create(ks, cf) .addPartitionKey("pkey", UTF8Type.instance) @@ -259,7 +259,7 @@ public class TriggerExecutorTest try { if (trigger != null) - metadata.addTriggerDefinition(trigger); + metadata.triggers(metadata.getTriggers().with(trigger)); } catch (InvalidRequestException e) { http://git-wip-us.apache.org/repos/asf/cassandra/blob/16044a6f/test/unit/org/apache/cassandra/triggers/TriggersSchemaTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/triggers/TriggersSchemaTest.java b/test/unit/org/apache/cassandra/triggers/TriggersSchemaTest.java index 8d66ca7..211cc9a 100644 --- a/test/unit/org/apache/cassandra/triggers/TriggersSchemaTest.java +++ b/test/unit/org/apache/cassandra/triggers/TriggersSchemaTest.java @@ -23,11 +23,11 @@ import org.junit.Test; import org.apache.cassandra.SchemaLoader; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.Schema; -import org.apache.cassandra.config.TriggerDefinition; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.schema.KeyspaceMetadata; import org.apache.cassandra.schema.KeyspaceParams; import org.apache.cassandra.schema.Tables; +import org.apache.cassandra.schema.TriggerMetadata; import org.apache.cassandra.service.MigrationManager; import static org.junit.Assert.*; @@ -48,16 +48,16 @@ public class TriggersSchemaTest @Test public void newKsContainsCfWithTrigger() throws Exception { - TriggerDefinition td = TriggerDefinition.create(triggerName, triggerClass); + TriggerMetadata td = TriggerMetadata.create(triggerName, triggerClass); CFMetaData cfm1 = CFMetaData.compile(String.format("CREATE TABLE %s (k int PRIMARY KEY, v int)", cfName), ksName); - cfm1.addTriggerDefinition(td); + cfm1.triggers(cfm1.getTriggers().with(td)); KeyspaceMetadata ksm = KeyspaceMetadata.create(ksName, KeyspaceParams.simple(1), Tables.of(cfm1)); MigrationManager.announceNewKeyspace(ksm); CFMetaData cfm2 = Schema.instance.getCFMetaData(ksName, cfName); assertFalse(cfm2.getTriggers().isEmpty()); assertEquals(1, cfm2.getTriggers().size()); - assertEquals(td, cfm2.getTriggers().get(triggerName)); + assertEquals(td, cfm2.getTriggers().get(triggerName).get()); } @Test @@ -67,15 +67,15 @@ public class TriggersSchemaTest MigrationManager.announceNewKeyspace(ksm); CFMetaData cfm1 = CFMetaData.compile(String.format("CREATE TABLE %s (k int PRIMARY KEY, v int)", cfName), ksName); - TriggerDefinition td = TriggerDefinition.create(triggerName, triggerClass); - cfm1.addTriggerDefinition(td); + TriggerMetadata td = TriggerMetadata.create(triggerName, triggerClass); + cfm1.triggers(cfm1.getTriggers().with(td)); MigrationManager.announceNewColumnFamily(cfm1); CFMetaData cfm2 = Schema.instance.getCFMetaData(ksName, cfName); assertFalse(cfm2.getTriggers().isEmpty()); assertEquals(1, cfm2.getTriggers().size()); - assertEquals(td, cfm2.getTriggers().get(triggerName)); + assertEquals(td, cfm2.getTriggers().get(triggerName).get()); } @Test @@ -86,27 +86,27 @@ public class TriggersSchemaTest MigrationManager.announceNewKeyspace(ksm); CFMetaData cfm2 = Schema.instance.getCFMetaData(ksName, cfName).copy(); - TriggerDefinition td = TriggerDefinition.create(triggerName, triggerClass); - cfm2.addTriggerDefinition(td); + TriggerMetadata td = TriggerMetadata.create(triggerName, triggerClass); + cfm2.triggers(cfm2.getTriggers().with(td)); MigrationManager.announceColumnFamilyUpdate(cfm2, false); CFMetaData cfm3 = Schema.instance.getCFMetaData(ksName, cfName); assertFalse(cfm3.getTriggers().isEmpty()); assertEquals(1, cfm3.getTriggers().size()); - assertEquals(td, cfm3.getTriggers().get(triggerName)); + assertEquals(td, cfm3.getTriggers().get(triggerName).get()); } @Test public void removeTriggerFromCf() throws Exception { - TriggerDefinition td = TriggerDefinition.create(triggerName, triggerClass); + TriggerMetadata td = TriggerMetadata.create(triggerName, triggerClass); CFMetaData cfm1 = CFMetaData.compile(String.format("CREATE TABLE %s (k int PRIMARY KEY, v int)", cfName), ksName); - cfm1.addTriggerDefinition(td); + cfm1.triggers(cfm1.getTriggers().with(td)); KeyspaceMetadata ksm = KeyspaceMetadata.create(ksName, KeyspaceParams.simple(1), Tables.of(cfm1)); MigrationManager.announceNewKeyspace(ksm); CFMetaData cfm2 = Schema.instance.getCFMetaData(ksName, cfName).copy(); - cfm2.removeTrigger(triggerName); + cfm2.triggers(cfm2.getTriggers().without(triggerName)); MigrationManager.announceColumnFamilyUpdate(cfm2, false); CFMetaData cfm3 = Schema.instance.getCFMetaData(ksName, cfName).copy();
