2.2. シリアル化のコンテキストイニシャライザーの作成
シリアル化コンテキストイニシャライザーを使用すると、Data Grid で以下を登録することができます。
- ユーザータイプを記述する Protobuf スキーマ。
- シリアル化およびデシリアライズ機能を提供するマーシャラー。
概略としては、以下の操作を行いシリアル化コンテキストイニシャライザーを作成する必要があります。
- ProtoStream アノテーションを Java クラスに追加します。
-
Data Grid が提供する ProtoStream プロセッサーを使用して、
SerializationContextInitializer実装をコンパイルします。
org.infinispan.protostream.MessageMarshaller インターフェイスは非推奨となり、ProtoStream の今後のバージョンで削除される予定です。完全に削除されるまで MessageMarshaller の使用方法を示すコード例またはドキュメントは無視する必要があります。
2.2.1. ProtoStream プロセッサーの追加 リンクのコピーリンクがクリップボードにコピーされました!
Data Grid は、コンパイル時にクラスの Java アノテーションを処理する ProtoStream プロセッサーアーティファクトを提供し、Protobuf スキーマ、付随マーシャラー、および SerializationContextInitializer インターフェイスの具体的な実装を生成します。
手順
pom.xmlのmaven-compiler-pluginのアノテーションプロセッサー設定にprotostream-processorを追加します。<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>...</version> <configuration> <annotationProcessorPaths> <annotationProcessorPath> <groupId>org.infinispan.protostream</groupId> <artifactId>protostream-processor</artifactId> <version>...</version> </annotationProcessorPath> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
2.2.2. ProtoStream アノテーションの Java クラスへの追加 リンクのコピーリンクがクリップボードにコピーされました!
Java クラスとそのメンバーにアノテーションを追加して ProtoStream メタデータを宣言します。次に、Data Grid は ProtoStream プロセッサーを使用して Protobuf スキーマと、それらのアノテーションから関連するマーシャラーを生成します。
手順
フィールドで直接、または getter メソッドまたは setter メソッドのいずれかで、
@ProtoFieldでマーシャリングする Java フィールドにアノテーションを付けます。Java クラスのアノテーションが付けられていないフィールドは一時的です。たとえば、Java クラスに 15 つのフィールドがあり、それらのうち 5 つにアノテーションを付けるとします。作成されるスキーマにはこれらの 5 つのフィールドのみが含まれ、これらの 5 つのフィールドのみが Data Grid にクラスインスタンスを保存するときにマーシャリングされます。
-
@ProtoFactoryを使用して、イミュータブルオブジェクトのコンストラクターにアノテーションを付けます。アノテーションが付けられたコンストラクターは@ProtoFieldアノテーションが付けられたフィールドをすべて初期化する必要があります。 -
@ProtoEnumValueで Java 列挙型のメンバーにアノテーションを付けます。
以下の Author.java および Book.java の例は、@ProtoField および @ProtoFactory のアノテーションが付けられた Java クラスを示しています。
Author.java
import org.infinispan.protostream.annotations.ProtoFactory;
import org.infinispan.protostream.annotations.ProtoField;
public class Author {
@ProtoField(1)
final String name;
@ProtoField(2)
final String surname;
@ProtoFactory
Author(String name, String surname) {
this.name = name;
this.surname = surname;
}
// public Getter methods omitted for brevity
}
Book.java
import org.infinispan.protostream.annotations.ProtoFactory;
import org.infinispan.protostream.annotations.ProtoField;
public class Book {
@ProtoField(number = 1)
public final UUID id;
@ProtoField(number = 2)
final String title;
@ProtoField(number = 3)
final String description;
@ProtoField(number = 4, defaultValue = "0")
final int publicationYear;
@ProtoField(number = 5, collectionImplementation = ArrayList.class)
final List<Author> authors;
@ProtoField(number = 6)
public Language language;
@ProtoFactory
Book(UUID id, String title, String description, int publicationYear, List<Author> authors, Language language) {
this.id = id;
this.title = title;
this.description = description;
this.publicationYear = publicationYear;
this.authors = authors;
this.language = language;
}
// public Getter methods not included for brevity
}
以下の Language.java の例は、対応する Protobuf スキーマとともに @ProtoEnumValue アノテーションが付けられた Java 列挙を示しています。
Language.java
import org.infinispan.protostream.annotations.ProtoEnumValue;
public enum Language {
@ProtoEnumValue(number = 0, name = "EN")
ENGLISH,
@ProtoEnumValue(number = 1, name = "DE")
GERMAN,
@ProtoEnumValue(number = 2, name = "IT")
ITALIAN,
@ProtoEnumValue(number = 3, name = "ES")
SPANISH,
@ProtoEnumValue(number = 4, name = "FR")
FRENCH;
}
Language.proto
enum Language {
EN = 0;
DE = 1;
IT = 2;
ES = 3;
FR = 4;
}
2.2.3. ProtoStream アダプタークラスの作成 リンクのコピーリンクがクリップボードにコピーされました!
ProtoStream は @ProtoAdapter アノテーションを提供し、これを使用して、直接アノテーションを付けることができない外部のサードパーティーの Java オブジェクトクラスをマーシャリングすることができます。
手順
Adapterクラスを作成し、以下の例のように@ProtoAdapterアノテーションを追加します。import java.util.UUID; import org.infinispan.protostream.annotations.ProtoAdapter; import org.infinispan.protostream.annotations.ProtoFactory; import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.descriptors.Type; /** * Human readable UUID adapter for UUID marshalling */ @ProtoAdapter(UUID.class) public class UUIDAdapter { @ProtoFactory UUID create(String stringUUID) { return UUID.fromString(stringUUID); } @ProtoField(1) String getStringUUID(UUID uuid) { return uuid.toString(); } }
2.2.4. シリアル化コンテキストイニシャライザーの生成 リンクのコピーリンクがクリップボードにコピーされました!
ProtoStream プロセッサーを追加して Java クラスにアノテーションを付けると、Data Grid が Protobuf スキーマ、付随するマーシャラー、および SerializationContextInitializer の具体的な実装を生成するように、@ProtoSchema アノテーションをインターフェイスに追加できます。
デフォルトでは、生成された実装名は "Impl" 接尾辞が付いたアノテーション付きクラス名です。
手順
GeneratedSchemaを拡張するインターフェイスまたはそのスーパーインターフェイスSerializationContextInitializerを定義します。注記GeneratedSchemaインターフェイスには Protobuf スキーマにアクセスするためのメソッドが含まれていますが、SerializationContextInitializerインターフェイスは登録メソッドのみをサポートします。-
インターフェイスに
@ProtoSchemaアノテーションを付けます。 -
includeClassesパラメーターには、生成されたSerializationContextInitializer実装のすべてのクラスが含まれることを確認します。 -
schemaFileNameパラメーターで、生成された.protoスキーマの名前を指定します。 -
schemaFilePathパラメーターで、スキーマファイルが生成されるtarget/classesの下にパスを設定します。 -
schemaPackageNameパラメーターで、生成された.protoスキーマのパッケージ名を指定します。
次の例は、@ProtoSchema でアノテーションが付けられた GeneratedSchema インターフェイスを示しています。
@ProtoSchema(
includeClasses = {
Book.class,
Author.class,
UUIDAdapter.class,
Language.class
},
schemaFileName = "library.proto",
schemaFilePath = "proto/",
schemaPackageName = "book_sample")
interface LibraryInitializer extends GeneratedSchema {
}
次のステップ
組み込みキャッシュを使用する場合は、Data Grid は SerializationContextInitializer 実装を自動的に登録します。
リモートキャッシュを使用する場合は、SerializationContextInitializer 実装を Data Grid Server に登録する必要があります。
2.2.5. Protocol Buffers のベストプラクティス リンクのコピーリンクがクリップボードにコピーされました!
Protocol Buffers のドキュメントには、下位互換性を維持するためにメッセージを設計する方法とスキーマを 進化させる 方法に関する ベストプラクティス のリストが記載されています。
Data Grid は、スキーマが更新されたときに自動的に互換性チェックを実行し、非互換性が検出された場合は更新を拒否できます。チェックの種類は、グローバル serialization 設定の schema-compatibility 属性を介して設定できます。利用可能なレベルは次のとおりです。
-
UNRESTRICTED: チェックは実行されない -
LENIENT: ルールのサブセットが適用される -
STRICT: すべてのルールが適用される (デフォルト)
次の表は、各レベルで有効になっている互換性チェックルールを示しています。
| ルール | 説明 | レベル |
|---|---|---|
| 予約フィールドを使用しない | 現在の定義と更新された定義を比較し、メッセージの以前に予約されたフィールドまたは ID が同じメッセージの一部として使用されている場合は、警告のリストを返します。 |
|
| フィールド ID の変更なし | 現在の定義と更新された定義を比較し、フィールド ID 番号が変更されている場合は、警告のリストを返します。 |
|
| フィールドタイプを変更なし | 現在の定義と更新された定義を比較し、フィールドタイプが変更されている場合は、警告のリストを返します。 |
|
| 予約なしでフィールドを削除しない | 現在の定義と更新された定義を比較し、フィールド名または ID の対応する予約なしにフィールドが削除された場合は、警告のリストを返します。 |
|
| 予約フィールドを削除しない | 現在の定義と更新された定義を比較し、予約済みフィールドが削除されている場合は、警告のリストを返します。 |
|
| フィールド名を変更しない | 現在の定義と更新された定義を比較し、メッセージの以前のフィールドの名前が変更されている場合は、警告のリストを返します。 |
|
2.2.6. シリアル化コンテキストイニシャライザーの登録 リンクのコピーリンクがクリップボードにコピーされました!
組み込みキャッシュの場合、Data Grid は java.util.ServiceLoader を使用してアノテーションが付けられた SerializationContextInitializer 実装にシリアル化コンテキストおよびマーシャラーを自動的に登録します。
必要に応じて、SerializationContextInitializer 実装の自動登録を無効にして、手動で登録することができます。
1 つの SerializationContextInitializer 実装を手動で登録する場合は、自動登録が無効になります。その後、他のすべての実装を手動で登録する必要があります。
手順
ProtoSchema.serviceアノテーションの値をfalseに設定します。@ProtoSchema( includeClasses = SomeClass.class, ... service = false )-
以下の例のように、プログラムまたは宣言的に
SerializationContextInitializer実装を手動で登録します。
宣言的
<serialization>
<context-initializer class="org.infinispan.example.LibraryInitializerImpl"/>
<context-initializer class="org.infinispan.example.another.SCIImpl"/>
</serialization>
プログラマティック
GlobalConfigurationBuilder builder = new GlobalConfigurationBuilder();
builder.serialization()
.addContextInitializers(new LibraryInitializerImpl(), new SCIImpl());
2.2.7. Data Grid Server への Protobuf スキーマの登録 リンクのコピーリンクがクリップボードにコピーされました!
Ickle クエリーを実行する場合、または application/x-protostream から application/json などの他のメディアタイプに変換する場合は、Data Grid Server に Protobuf スキーマを登録する必要があります。
前提条件
ProtoStream プロセッサーで Protobuf スキーマを生成します。
生成された Protobuf スキーマは、
target/<schemaFilePath>/ディレクトリーにあります。CREATE権限を持つユーザーを用意します。注記セキュリティー認可には、スキーマを追加するための
CREATE権限が必要です。デフォルト設定では、少なくともdeployerのロールが必要です。
手順
次のいずれかの方法で、Protobuf スキーマを Data Grid サーバーに追加します。
- 任意のブラウザーで Data Grid コンソールを開き、Schema タブを選択してから Add Protobuf schema を選択します。
Data Grid コマンドラインインターフェイス (CLI) から
--upload=引数を指定してschemaコマンドを使用します。schema --upload=person.proto personREST API を使用して、
POST要求のペイロードに Protobuf スキーマを含めます。POST/rest/v2/schemas/<schema_name>以下の例のように、Hot Rod クライアントで生成された
SerializationContextInitializer実装を使用して、Protobuf スキーマを登録します。/** * Register generated Protobuf schema with Data Grid Server. * This requires the RemoteCacheManager to be initialized. * * @param initializer The serialization context initializer for the schema. */ private void registerSchemas(SerializationContextInitializer initializer) { // Store schemas in the '___protobuf_metadata' cache to register them. // Using ProtobufMetadataManagerConstants might require the query dependency. final RemoteCache<String, String> protoMetadataCache = remoteCacheManager.getCache(ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME); // Add the generated schema to the cache. protoMetadataCache.put(initializer.getProtoFileName(), initializer.getProtoFile()); // Ensure the registered Protobuf schemas do not contain errors. // Throw an exception if errors exist. String errors = protoMetadataCache.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX); if (errors != null) { throw new IllegalStateException("Some Protobuf schema files contain errors: " + errors + "\nSchema :\n" + initializer.getProtoFileName()); } }SerializationContextInitializer実装およびカスタムクラスを持つ JAR ファイルを$RHDG_HOME/server/libディレクトリーに追加します。これを実行すると、Data Grid Server は起動時に Protobuf スキーマを登録します。ただし、スキーマは
___protobuf_metadataキャッシュに保存されたり、クラスター全体で自動的に分散されたりしないため、アーカイブを各サーバーインストールに追加する必要があります。注記Data Grid Server が
application/x-protostreamからapplication/x-java-objectへの変換を実施する必要がある場合、これを実行する必要があります。この場合、POJO 用の JAR ファイルも追加する必要があります。
次のステップ
以下の例のように、SerializationContextInitializer を Hot Rod クライアントに登録します。
ConfigurationBuilder remoteBuilder = new ConfigurationBuilder();
remoteBuilder.addServer().host(host).port(Integer.parseInt(port));
// Add your generated SerializationContextInitializer implementation.
LibraryInitalizer initializer = new LibraryInitalizerImpl();
remoteBuilder.addContextInitializer(initializer);
2.2.8. 手動によるシリアル化コンテキストイニシャライザーの実装 リンクのコピーリンクがクリップボードにコピーされました!
Data Grid は、SerializationContextInitializer または GeneratedSchema インターフェイスを手動で実装しないことを強く推奨します。
ProtobufTagMarshaller および RawProtobufMarshaller アノテーションを使用して SerializationContextInitializer または GeneratedSchema インターフェイスを手動で実装できます。
ただし、手動の実装には多くの面倒なオーバーヘッドが必要で、エラーが発生する可能性が高くなります。protostream-processor アーティファクトを使用して生成する実装は、ProtoStream マーシャリングを設定するより効率的で信頼できる方法です。