blob: c4537e199982a62351729651ebfefa1c2eac1933 [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.cassandra.schema;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.cassandra.cql3.functions.UDAggregate;
import org.apache.cassandra.cql3.functions.UDFunction;
import org.apache.cassandra.db.marshal.UserType;
import org.apache.cassandra.schema.SchemaTransformation.SchemaTransformationResult;
/**
* Registers schema change listeners and sends the notifications. The interface of this class just takes the high level
* keyspace metadata changes. It iterates over all keyspaces elements and distributes appropriate notifications about
* changes around those elements (tables, views, types, functions).
*/
public class SchemaChangeNotifier
{
private final List<SchemaChangeListener> changeListeners = new CopyOnWriteArrayList<>();
public void registerListener(SchemaChangeListener listener)
{
changeListeners.add(listener);
}
@SuppressWarnings("unused")
public void unregisterListener(SchemaChangeListener listener)
{
changeListeners.remove(listener);
}
public void notifyKeyspaceCreated(KeyspaceMetadata keyspace)
{
notifyCreateKeyspace(keyspace);
keyspace.types.forEach(this::notifyCreateType);
keyspace.tables.forEach(this::notifyCreateTable);
keyspace.views.forEach(this::notifyCreateView);
keyspace.functions.udfs().forEach(this::notifyCreateFunction);
keyspace.functions.udas().forEach(this::notifyCreateAggregate);
}
public void notifyKeyspaceAltered(KeyspaceMetadata.KeyspaceDiff delta, boolean dropData)
{
// notify on everything dropped
delta.udas.dropped.forEach(uda -> notifyDropAggregate((UDAggregate) uda));
delta.udfs.dropped.forEach(udf -> notifyDropFunction((UDFunction) udf));
delta.views.dropped.forEach(view -> notifyDropView(view, dropData));
delta.tables.dropped.forEach(metadata -> notifyDropTable(metadata, dropData));
delta.types.dropped.forEach(this::notifyDropType);
// notify on everything created
delta.types.created.forEach(this::notifyCreateType);
delta.tables.created.forEach(this::notifyCreateTable);
delta.views.created.forEach(this::notifyCreateView);
delta.udfs.created.forEach(udf -> notifyCreateFunction((UDFunction) udf));
delta.udas.created.forEach(uda -> notifyCreateAggregate((UDAggregate) uda));
// notify on everything altered
if (!delta.before.params.equals(delta.after.params))
notifyAlterKeyspace(delta.before, delta.after);
delta.types.altered.forEach(diff -> notifyAlterType(diff.before, diff.after));
delta.tables.altered.forEach(diff -> notifyAlterTable(diff.before, diff.after));
delta.views.altered.forEach(diff -> notifyAlterView(diff.before, diff.after));
delta.udfs.altered.forEach(diff -> notifyAlterFunction(diff.before, diff.after));
delta.udas.altered.forEach(diff -> notifyAlterAggregate(diff.before, diff.after));
}
public void notifyKeyspaceDropped(KeyspaceMetadata keyspace, boolean dropData)
{
keyspace.functions.udas().forEach(this::notifyDropAggregate);
keyspace.functions.udfs().forEach(this::notifyDropFunction);
keyspace.views.forEach(view -> notifyDropView(view, dropData));
keyspace.tables.forEach(metadata -> notifyDropTable(metadata, dropData));
keyspace.types.forEach(this::notifyDropType);
notifyDropKeyspace(keyspace, dropData);
}
public void notifyPreChanges(SchemaTransformationResult transformationResult)
{
transformationResult.diff.altered.forEach(this::notifyPreAlterKeyspace);
}
private void notifyPreAlterKeyspace(KeyspaceMetadata.KeyspaceDiff keyspaceDiff)
{
keyspaceDiff.tables.altered.forEach(this::notifyPreAlterTable);
keyspaceDiff.views.altered.forEach(this::notifyPreAlterView);
}
private void notifyPreAlterTable(Diff.Altered<TableMetadata> altered)
{
changeListeners.forEach(l -> l.onPreAlterTable(altered.before, altered.after));
}
private void notifyPreAlterView(Diff.Altered<ViewMetadata> altered)
{
changeListeners.forEach(l -> l.onPreAlterView(altered.before, altered.after));
}
private void notifyCreateKeyspace(KeyspaceMetadata ksm)
{
changeListeners.forEach(l -> l.onCreateKeyspace(ksm));
}
private void notifyCreateTable(TableMetadata metadata)
{
changeListeners.forEach(l -> l.onCreateTable(metadata));
}
private void notifyCreateView(ViewMetadata view)
{
changeListeners.forEach(l -> l.onCreateView(view));
}
private void notifyCreateType(UserType ut)
{
changeListeners.forEach(l -> l.onCreateType(ut));
}
private void notifyCreateFunction(UDFunction udf)
{
changeListeners.forEach(l -> l.onCreateFunction(udf));
}
private void notifyCreateAggregate(UDAggregate udf)
{
changeListeners.forEach(l -> l.onCreateAggregate(udf));
}
private void notifyAlterKeyspace(KeyspaceMetadata before, KeyspaceMetadata after)
{
changeListeners.forEach(l -> l.onAlterKeyspace(before, after));
}
private void notifyAlterTable(TableMetadata before, TableMetadata after)
{
boolean changeAffectedPreparedStatements = before.changeAffectsPreparedStatements(after);
changeListeners.forEach(l -> l.onAlterTable(before, after, changeAffectedPreparedStatements));
}
private void notifyAlterView(ViewMetadata before, ViewMetadata after)
{
boolean changeAffectedPreparedStatements = before.metadata.changeAffectsPreparedStatements(after.metadata);
changeListeners.forEach(l -> l.onAlterView(before, after, changeAffectedPreparedStatements));
}
private void notifyAlterType(UserType before, UserType after)
{
changeListeners.forEach(l -> l.onAlterType(before, after));
}
private void notifyAlterFunction(UDFunction before, UDFunction after)
{
changeListeners.forEach(l -> l.onAlterFunction(before, after));
}
private void notifyAlterAggregate(UDAggregate before, UDAggregate after)
{
changeListeners.forEach(l -> l.onAlterAggregate(before, after));
}
private void notifyDropKeyspace(KeyspaceMetadata ksm, boolean dropData)
{
changeListeners.forEach(l -> l.onDropKeyspace(ksm, dropData));
}
private void notifyDropTable(TableMetadata metadata, boolean dropData)
{
changeListeners.forEach(l -> l.onDropTable(metadata, dropData));
}
private void notifyDropView(ViewMetadata view, boolean dropData)
{
changeListeners.forEach(l -> l.onDropView(view, dropData));
}
private void notifyDropType(UserType ut)
{
changeListeners.forEach(l -> l.onDropType(ut));
}
private void notifyDropFunction(UDFunction udf)
{
changeListeners.forEach(l -> l.onDropFunction(udf));
}
private void notifyDropAggregate(UDAggregate udf)
{
changeListeners.forEach(l -> l.onDropAggregate(udf));
}
}