4.6.4. イベントのカスタマイズ
デフォルトで生成されるイベントには、イベントを関連させるのに十分な情報が含まれていますが、送信コストを削減するために情報を詰め込みすぎないようにしています。必要に応じて、イベントに含まれる情報は、値などの詳細情報を含むか、より少ない情報を含めるためにカスタム化できます。このカスタマイズは、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 サーバーに名前とキャッシュイベントコンバーターファクトリーインスタンスを接続する必要があります。
コンバーターの実装を含む JAR ファイルを作成します。
キャッシュがカスタムのキー/値クラスを使用する場合は、コールバックを正しくマーシャリングされていないキー/値インスタンスで実行できるように、これらを JAR に含める必要があります。クライアントリスナーで
useRawDataが有効になっている場合、コールバックのキー/値インスタンスはバイナリー形式で提供されるため、これは必要ありません。-
JAR ファイル内で
META-INF/services/org.infinispan.notifications.cachelistener.filter.CacheEventConverterFactoryファイルを作成し、コンバータークラス実装の完全修飾クラス名を作成します。 -
JAR ファイルを Data Grid サーバーのインストールディレクトリーの
server/libディレクトリーに追加します。 ファクトリー名を
@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 を提供します。