20.7.12. イベントのフィルタリング
クライアントにイベントが殺到するのを防ぐために、ユーザーはフィルタリング機能を提供して、特定のクライアントリスナーに対し、サーバーによって発生するイベントの数を制限できます。フィルターを有効にするには、フィルターインスタンスを生成するキャッシュイベントフィルターファクトリーを作成する必要があります。
import org.infinispan.notifications.cachelistener.filter.CacheEventFilterFactory;
import org.infinispan.filter.NamedFactory;
@NamedFactory(name = "static-filter")
class StaticCacheEventFilterFactory implements CacheEventFilterFactory {
@Override
public CacheEventFilterFactory<Integer, String> getFilter(Object[] params) {
return new StaticCacheEventFilter();
}
}
// Serializable, Externalizable or marshallable with Infinispan Externalizers
// needed when running in a cluster
class StaticCacheEventFilter implements CacheEventFilter<Integer, String>, Serializable {
@Override
public boolean accept(Integer key, String oldValue, Metadata oldMetadata,
String newValue, Metadata newMetadata, EventType eventType) {
if (key.equals(1)) // static key
return true;
return false;
}
}
上記で定義されたキャッシュイベントフィルターファクトリーインスタンスは、キーが 1 であるものを除くすべてのエントリーを静的にフィルターするインスタンスを作成します。
このキャッシュイベントフィルターファクトリにリスナーを登録できるようにするには、ファクトリに一意の名前を付ける必要があり、Hot Rodサーバーに名前とキャッシュイベントフィルターファクトリインスタンスを接続する必要があります。カスタムフィルターで Red Hat Data Grid Server をプラグインするには、以下の手順を行います。
- フィルター実装で JAR ファイルを作成します。
-
オプション: キャッシュがカスタムキー/値クラスを使用する場合は、コールバックを JAR に含める必要があります。これにより、コールバックは正しくアンマーシャリングされたキーや値インスタンス/または値インスタンスで実行できます。クライアントリスナーで
useRawDataが有効になっている場合、コールバックのキー/値インスタンスはバイナリ形式で提供されるため、これは必要ありません。 -
JAR ファイル内で
META-INF/services/org.infinispan.notifications.cachelistener.filter.CacheEventFilterFactoryファイルを作成し、フィルタークラス実装の完全修飾クラス名を作成します。 - JAR ファイルを Red Hat Data Grid Server にデプロイします。
その上で、ファクトリーの名前を @ClientListener アノテーションに追加して、クライアントリスナーをこのキャッシュイベントフィルターファクトリーにリンクする必要があります。
@ClientListener(filterFactoryName = "static-filter")
public class EventPrintListener { ... }
そして、リスナーをサーバーに登録します。
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener());
リスナーの登録時に提供されるパラメーターに基づいてフィルターする動的フィルターインスタンスも使用できます。フィルターは、フィルターファクトリーが受信したパラメーターを使用して、このオプションを有効にします。以下に例を示します。
import org.infinispan.notifications.cachelistener.filter.CacheEventFilterFactory;
import org.infinispan.notifications.cachelistener.filter.CacheEventFilter;
class DynamicCacheEventFilterFactory implements CacheEventFilterFactory {
@Override
public CacheEventFilter<Integer, String> getFilter(Object[] params) {
return new DynamicCacheEventFilter(params);
}
}
// Serializable, Externalizable or marshallable with Infinispan Externalizers
// needed when running in a cluster
class DynamicCacheEventFilter implements CacheEventFilter<Integer, String>, Serializable {
final Object[] params;
DynamicCacheEventFilter(Object[] params) {
this.params = params;
}
@Override
public boolean accept(Integer key, String oldValue, Metadata oldMetadata,
String newValue, Metadata newMetadata, EventType eventType) {
if (key.equals(params[0])) // dynamic key
return true;
return false;
}
}
リスナーの登録時に、フィルタリングに必要な動的パラメーターが提供されます。
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener(), new Object[]{1}, null);
フィルターインスタンスは、クラスターにデプロイされるときにマーシャル可能である必要があります。これにより、リスナーの登録先の別のノードで生成された場合でも、イベントが生成される際にフィルターが適切に行われるようにします。それらをマーシャリング可能にするには、Serializable、Externalizableを拡張するか、カスタムExternalizerを提供します。