2.2. シリアル化のコンテキストイニシャライザーの作成


シリアル化コンテキストイニシャライザーを使用すると、Data Grid で以下を登録することができます。

  • ユーザータイプを記述する Protobuf スキーマ。
  • シリアル化およびデシリアライズ機能を提供するマーシャラー。

概略としては、以下の操作を行いシリアル化コンテキストイニシャライザーを作成する必要があります。

  1. ProtoStream アノテーションを Java クラスに追加します。
  2. Data Grid が提供する ProtoStream プロセッサーを使用して、SerializationContextInitializer 実装をコンパイルします。
注記

org.infinispan.protostream.MessageMarshaller インターフェイスは非推奨となり、ProtoStream の今後のバージョンで削除される予定です。完全に削除されるまで MessageMarshaller の使用方法を示すコード例またはドキュメントは無視する必要があります。

2.2.1. ProtoStream プロセッサーの追加

Data Grid は、コンパイル時にクラスの Java アノテーションを処理する ProtoStream プロセッサーアーティファクトを提供し、Protobuf スキーマ、付随マーシャラー、および SerializationContextInitializer インターフェイスの具体的な実装を生成します。

手順

  • provided スコープで protostream-processor 依存関係を pom.xml に追加します。

    注記

    この依存関係はコンパイル時にのみ必要です。そのため、provided スコープを使用するか、オプションとしてマークする必要があります。また、protostream-processor が推移的な依存関係として伝播されないようにする必要があります。

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>org.infinispan</groupId>
          <artifactId>infinispan-bom</artifactId>
          <version>${version.infinispan}</version>
          <type>pom</type>
        </dependency>
      </dependencies>
    </dependencyManagement>
    
    <dependencies>
      <dependency>
        <groupId>org.infinispan.protostream</groupId>
        <artifactId>protostream-processor</artifactId>
        <scope>provided</scope>
      </dependency>
    </dependencies>

2.2.2. ProtoStream アノテーションの Java クラスへの追加

Java クラスとそのメンバーにアノテーションを追加して ProtoStream メタデータを宣言します。次に、Data Grid は ProtoStream プロセッサーを使用して Protobuf スキーマと、それらのアノテーションから関連するマーシャラーを生成します。

手順

  1. フィールドで直接、または getter メソッドまたは setter メソッドのいずれかで、@ProtoField でマーシャリングする Java フィールドにアノテーションを付けます。

    Java クラスのアノテーションが付けられていないフィールドは一時的です。たとえば、Java クラスに 15 つのフィールドがあり、それらのうち 5 つにアノテーションを付けるとします。作成されるスキーマにはこれらの 5 つのフィールドのみが含まれ、これらの 5 つのフィールドのみが Data Grid にクラスインスタンスを保存するときにマーシャリングされます。

  2. @ProtoFactory を使用して、イミュータブルオブジェクトのコンストラクターにアノテーションを付けます。アノテーションが付けられたコンストラクターは @ProtoField アノテーションが付けられたフィールドをすべて初期化する必要があります。
  3. @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 オブジェクトクラスをマーシャリングすることができます。

手順

  1. 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 の具体的な実装を生成するように @AutoProtoSchemaBuilder アノテーションをインターフェイスに追加できます。

注記

デフォルトでは、生成された実装名は Impl 接尾辞が付いたアノテーション付きクラス名です。

手順

  1. GeneratedSchema を拡張するインターフェイスまたはそのスーパーインターフェイス SerializationContextInitializer を定義します。

    注記

    GeneratedSchema インターフェイスには Protobuf スキーマにアクセスするためのメソッドが含まれていますが、SerializationContextInitializer インターフェイスは登録メソッドのみをサポートします。

  2. インターフェイスに @AutoProtoSchemaBuilder アノテーションを付けます。
  3. includeClasses パラメーターには、生成された SerializationContextInitializer 実装のすべてのクラスが含まれることを確認します。
  4. schemaFileName パラメーターで、生成された .proto スキーマの名前を指定します。
  5. schemaFilePath パラメーターで、スキーマファイルが生成される target/classes の下にパスを設定します。
  6. schemaPackageName パラメーターで、生成された .proto スキーマのパッケージ名を指定します。

以下の例は、@AutoProtoSchemaBuilder アノテーションが付けられた GeneratedSchema インターフェイスを示しています。

@AutoProtoSchemaBuilder(
      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. シリアル化コンテキストイニシャライザーの登録

埋め込みキャッシュの場合、Data Grid は java.util.ServiceLoader を使用してアノテーションが付けられた SerializationContextInitializer 実装にシリアル化コンテキストおよびマーシャラーを自動的に登録します。

必要に応じて、SerializationContextInitializer 実装の自動登録を無効にして、手動で登録することができます。

重要

1 つの SerializationContextInitializer 実装を手動で登録する場合は、自動登録が無効になります。その後、他のすべての実装を手動で登録する必要があります。

手順

  1. AutoProtoSchemaBuilder.service アノテーションに false の値を設定します。

    @AutoProtoSchemaBuilder(
          includeClasses = SomeClass.class,
          ...
          service = false
    )
  2. 以下の例のように、プログラムまたは宣言的に SerializationContextInitializer 実装を手動で登録します。

宣言的 (Declarative)

<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.6. Data Grid Server への Protobuf スキーマの登録

Ickle クエリーを実行する場合、または application/x-protostream から application/json などの他のメディアタイプに変換する場合は、Data Grid Server に Protobuf スキーマを登録する必要があります。

前提条件

  • ProtoStream プロセッサーを使用して SerializationContextInitializer 実装を生成している。

    ビルドの完了後に、生成された Protobuf スキーマを target/<schemaFilePath>/ ディレクトリーに見つけることができます。

手順

以下のいずれかを実行して、生成された Protobuf スキーマを Data Grid Server に登録します。

  • 生成された Protobuf スキーマを、Data Grid コマンドラインインターフェイス (CLI)、REST インターフェイス、または ProtobufMetadataManager JMX MBean を使用して専用の ___protobuf_metadata キャッシュに追加します。

    この方法では、Data Grid がスキーマを自動的にクラスター全体に分散できるようにします。

    注記

    キャッシュのセキュリティー承認を有効にする場合、ユーザーは ___protobuf_metadata キャッシュにスキーマを追加する CREATE パーミッションを持っている必要があります。デフォルトの承認設定を使用する場合は、ユーザーに少なくとも deployer ロールを割り当てます。

  • 以下の例のように、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.7. 手動によるシリアル化コンテキストイニシャライザーの実装

重要

Data Grid は、SerializationContextInitializer または GeneratedSchema インターフェイスを手動で実装しないことを強く推奨します。

ProtobufTagMarshaller および RawProtobufMarshaller アノテーションを使用して SerializationContextInitializer または GeneratedSchema インターフェイスを手動で実装できます。

ただし、手動の実装には多くの面倒なオーバーヘッドが必要で、エラーが発生する可能性が高くなります。protostream-processor アーティファクトを使用して生成する実装は、ProtoStream マーシャリングを設定するより効率的で信頼できる方法です。

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.