20.7.14. イベントのカスタマイズ
デフォルトで生成されるイベントには、イベントを関連させるのに十分な情報が含まれていますが、送信コストを削減するために情報を詰め込みすぎないようにしています。必要に応じて、イベントに含まれる情報は、値などの詳細情報を含むか、より少ない情報を含めるためにカスタム化できます。このカスタマイズは、CacheEventConverterFactory によって生成された CacheEventConverter インスタンスを使用して行われます。
import org.infinispan.notifications.cachelistener.filter.CacheEventConverterFactory;
import org.infinispan.notifications.cachelistener.filter.CacheEventConverter;
import org.infinispan.filter.NamedFactory;
@NamedFactory(name = "static-converter")
class StaticConverterFactory implements CacheEventConverterFactory {
final CacheEventConverter<Integer, String, CustomEvent> staticConverter = new StaticCacheEventConverter();
public CacheEventConverter<Integer, String, CustomEvent> getConverter(final Object[] params) {
return staticConverter;
}
}
// Serializable, Externalizable or marshallable with Infinispan Externalizers
// needed when running in a cluster
class StaticCacheEventConverter implements CacheEventConverter<Integer, String, CustomEvent>, Serializable {
public CustomEvent convert(Integer key, String oldValue, Metadata oldMetadata, String newValue, Metadata newMetadata, EventType eventType) {
return new CustomEvent(key, newValue);
}
}
// Needs to be Serializable, Externalizable or marshallable with Infinispan Externalizers
// regardless of cluster or local caches
static class CustomEvent implements Serializable {
final Integer key;
final String value;
CustomEvent(Integer key, String value) {
this.key = key;
this.value = value;
}
}
上記の例では、コンバーターは、イベント内の値とキーを含む新しいカスタムイベントを生成します。これにより、デフォルトのイベントと比べて大量のイベントペイロードが発生しますが、フィルターと組み合わせると、ネットワークの帯域幅コストを減らすことができます。
コンバーターのターゲットタイプは、Serializable または Externalizable のいずれかである必要があります。この特定のコンバーターの場合、デフォルトの Hot Rod クライアントマーシャラーではサポートされないため、デフォルトで Externalizer を提供しません。
カスタムイベントの処理には、以前に実証されたものに対して、若干異なるクライアントリスナーの実装が必要になります。より正確な状態に戻すには、ClientCacheEntryCustomEvent インスタンスを処理する必要があります。
import org.infinispan.client.hotrod.annotation.*;
import org.infinispan.client.hotrod.event.*;
@ClientListener
public class CustomEventPrintListener {
@ClientCacheEntryCreated
@ClientCacheEntryModified
@ClientCacheEntryRemoved
public void handleCustomEvent(ClientCacheEntryCustomEvent<CustomEvent> e) {
System.out.println(e);
}
}
コールバックで受け取ったClientCacheEntryCustomEventは、getEventDataメソッドを介してカスタムイベントを公開し、getTypeメソッドは、生成されたイベントがキャッシュエントリの作成、変更、または削除の結果であったかどうかに関する情報を提供します。
フィルタリングと同様に、リスナーをこのコンバーターファクトリに登録できるようにするには、ファクトリに一意の名前を付ける必要があり、Hot Rodサーバーに名前とキャッシュイベントコンバーターファクトリインスタンスを接続する必要があります。イベントコンバーターで Red Hat Data Grid Server をプラグインするには、以下の手順を行います。
- コンバーターの実装を含むJARファイルを作成します。
-
オプション: キャッシュがカスタムキー/値クラスを使用する場合は、コールバックを JAR に含める必要があります。これにより、コールバックは正しくアンマーシャリングされたキーや値インスタンス/または値インスタンスで実行できます。クライアントリスナーで
useRawDataが有効になっている場合、コールバックのキー/値インスタンスはバイナリ形式で提供されるため、これは必要ありません。 -
JAR ファイル内で
META-INF/services/org.infinispan.notifications.cachelistener.filter.CacheEventConverterFactoryファイルを作成し、コンバータークラス実装の完全修飾クラス名を作成します。 - JAR ファイルを Red Hat Data Grid Server にデプロイします。
その上で、ファクトリーの名前を @ClientListener アノテーションに追加して、クライアントリスナーをこのコンバーターファクトリーにリンクする必要があります。
@ClientListener(converterFactoryName = "static-converter")
public class CustomEventPrintListener { ... }
そして、リスナーをサーバーに登録します。
RemoteCache<?, ?> cache = ...
cache.addClientListener(new CustomEventPrintListener());
リスナーの登録時に提供されたパラメーターを基に変換する動的コンバーターインスタンスもあります。コンバーターは、コンバーターファクトリーによって受け取ったパラメーターを使用してこのオプションを有効にします。以下に例を示します。
import org.infinispan.notifications.cachelistener.filter.CacheEventConverterFactory;
import org.infinispan.notifications.cachelistener.filter.CacheEventConverter;
@NamedFactory(name = "dynamic-converter")
class DynamicCacheEventConverterFactory implements CacheEventConverterFactory {
public CacheEventConverter<Integer, String, CustomEvent> getConverter(final Object[] params) {
return new DynamicCacheEventConverter(params);
}
}
// Serializable, Externalizable or marshallable with Infinispan Externalizers needed when running in a cluster
class DynamicCacheEventConverter implements CacheEventConverter<Integer, String, CustomEvent>, Serializable {
final Object[] params;
DynamicCacheEventConverter(Object[] params) {
this.params = params;
}
public CustomEvent convert(Integer key, String oldValue, Metadata oldMetadata,
String newValue, Metadata newMetadata, EventType eventType) {
// If the key matches a key given via parameter, only send the key information
if (params[0].equals(key))
return new CustomEvent(key, null);
return new CustomEvent(key, newValue);
}
}
変換を行うために必要な動的パラメーターは、リスナーが登録されたときに提供されます。
RemoteCache<?, ?> cache = ...
cache.addClientListener(new EventPrintListener(), null, new Object[]{1});
コンバーターインスタンスは、クラスターにデプロイされるときにマーシャリングする必要があります。これにより、リスナーの登録先の別のノードで生成された場合でも、イベントが生成される場所を正確に変換できます。それらをマーシャリング可能にするには、Serializable、Externalizableを拡張するか、カスタムExternalizerを提供します。