検索

5.2. ProtoStream を使用したユーザータイプのマーシャリング

download PDF

ユーザータイプは、Data Grid がそのままではサポートしない Java オブジェクトです。ユーザータイプをマーシャリングするには、SerializationContextInitializer インターフェイスを実装して Java オブジェクトを記述し、ProtoStream ライブラリーが Protobuf 形式にエンコードし、Data Grid がそれらを送信および保存できるようにします。

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

ProtoStream SerializationContext には、Protobuf スキーマからロードされたカスタム Java オブジェクトの Protobuf タイプ定義と、それらのオブジェクトに付随するマーシャラーが含まれています。

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

注記

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

手順

  1. protostream-processor 依存関係を pom.xml に追加します。

    <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>
        <!--
          This dependency should be declared in the "provided" scope or made "optional"
          because it is a compile-only dependency and is not required at runtime.
          Transitive propagation of this dependency should be also be avoided.
        -->
        <scope>provided</scope>
      </dependency>
    </dependencies>
  2. マーシャリングする Java オブジェクトに @ProtoField@ProtoFactory アノテーションを付けます。

    Author.java

    import org.infinispan.protostream.annotations.ProtoFactory;
    import org.infinispan.protostream.annotations.ProtoField;
    
    public class Author {
       @ProtoField(number = 1)
       final String name;
    
       @ProtoField(number = 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)
       final String title;
    
       @ProtoField(number = 2)
       final String description;
    
       @ProtoField(number = 3, defaultValue = "0")
       final int publicationYear;
    
       @ProtoField(number = 4, collectionImplementation = ArrayList.class)
       final List<Author> authors;
    
       @ProtoFactory
       Book(String title, String description, int publicationYear, List<Author> authors) {
          this.title = title;
          this.description = description;
          this.publicationYear = publicationYear;
          this.authors = authors;
       }
       // public Getter methods omitted for brevity
    }

  3. SerializationContextInitializer を拡張し、 @AutoProtoSchemaBuilder アノテーションが付けられたインターフェイスを定義します。

    @AutoProtoSchemaBuilder(
          includeClasses = {
                Book.class,
                Author.class,
          },
          schemaFileName = "library.proto", 1
          schemaFilePath = "proto/", 2
          schemaPackageName = "book_sample")
    interface LibraryInitializer extends SerializationContextInitializer {
    }
    1
    生成された .proto スキーマファイルに名前を付けます。
    2
    スキーマファイルが生成される target/classes の下にパスを設定します。

次のステップ

SerializationContextInitializer 実装を Data Grid 設定に追加して登録します。

シリアル化コンテキストイニシャライザーの登録 を参照してください。

5.2.2. シリアライゼーションコンテキストイニシャライザーの手動実装

場合によっては、Protobuf スキーマを手動で定義し、ProtoStream マーシャラーを実装する必要があります。たとえば、Java オブジェクトクラスを変更してアノテーションを追加できない場合などです。

手順

  1. マーシャリングする Java オブジェクトの構造化表現を提供する Protobuf スキーマの .proto ファイルを作成します。

    package book_sample;
    
    message Book {
        optional string title = 1;
        optional string description = 2;
        optional int32 publicationYear = 3; // no native Date type available in Protobuf
    
        repeated Author authors = 4;
    }
    
    message Author {
        optional string name = 1;
        optional string surname = 2;
    }

    前述の .library.proto ファイルは、book_sample パッケージに含まれる Book という名前のエンティティー (Protobuf メッセージタイプ) を定義します。Book は、プリミティブ型のいくつかのフィールドと、Author メッセージタイプである authors という名前のアレイ (Protobuf 反復可能フィールド) を宣言します。

    • メッセージをネストできますが、結果的に構造は厳密にツリーであり、グラフではありません。
    • 型の継承はできません。
    • コレクションはサポート対象外ですが、フィールドを繰り返してアレイをエミュレートできます。
  2. org.infinispan.protostream.MessageMarshaller インターフェイスを使用して、クラスのマーシャラーを実装します。

    注記

    MessageMarshaller インターフェイスが非推奨になりました。

    次のバージョンの Data Grid は、外部のサードパーティー Java オブジェクトクラスに @ProtoAdaptor アノテーションを使用するアダプタークラスを作成できる代替実装を提供します。

    BookMarshaller.java

    import org.infinispan.protostream.MessageMarshaller;
    
    public class BookMarshaller implements MessageMarshaller<Book> {
    
       @Override
       public String getTypeName() {
          return "book_sample.Book";
       }
    
       @Override
       public Class<? extends Book> getJavaClass() {
          return Book.class;
       }
    
       @Override
       public void writeTo(MessageMarshaller.ProtoStreamWriter writer, Book book) throws IOException {
          writer.writeString("title", book.getTitle());
          writer.writeString("description", book.getDescription());
          writer.writeInt("publicationYear", book.getPublicationYear());
          writer.writeCollection("authors", book.getAuthors(), Author.class);
       }
    
       @Override
       public Book readFrom(MessageMarshaller.ProtoStreamReader reader) throws IOException {
          String title = reader.readString("title");
          String description = reader.readString("description");
          int publicationYear = reader.readInt("publicationYear");
          List<Author> authors = reader.readCollection("authors", new ArrayList<>(), Author.class);
          return new Book(title, description, publicationYear, authors);
       }
    }

    AuthorMarshaller.java

    import org.infinispan.protostream.MessageMarshaller;
    
    public class AuthorMarshaller implements MessageMarshaller<Author> {
    
       @Override
       public String getTypeName() {
          return "book_sample.Author";
       }
    
       @Override
       public Class<? extends Author> getJavaClass() {
          return Author.class;
       }
    
       @Override
       public void writeTo(MessageMarshaller.ProtoStreamWriter writer, Author author) throws IOException {
          writer.writeString("name", author.getName());
          writer.writeString("surname", author.getSurname());
       }
    
       @Override
       public Author readFrom(MessageMarshaller.ProtoStreamReader reader) throws IOException {
          String name = reader.readString("name");
          String surname = reader.readString("surname");
          return new Author(name, surname);
       }
    }

  3. .proto スキーマと ProtoStream マーシャラー実装を SerializationContext に登録するSerializationContextInitializer 実装を作成します。

    ManualSerializationContextInitializer.java

    import org.infinispan.protostream.FileDescriptorSource;
    import org.infinispan.protostream.SerializationContext;
    import org.infinispan.protostream.SerializationContextInitializer;
    ...
    
    public class ManualSerializationContextInitializer implements SerializationContextInitializer {
       @Override
       public String getProtoFileName() {
          return "library.proto";
       }
    
       @Override
       public String getProtoFile() throws UncheckedIOException {
          // Assumes that the file is located in a Jar's resources, we must provide the path to the library.proto file
          return FileDescriptorSource.getResourceAsString(getClass(), "/" + getProtoFileName());
       }
    
       @Override
       public void registerSchema(SerializationContext serCtx) {
          serCtx.registerProtoFiles(FileDescriptorSource.fromString(getProtoFileName(), getProtoFile()));
       }
    
       @Override
       public void registerMarshallers(SerializationContext serCtx) {
          serCtx.registerMarshaller(new AuthorMarshaller());
          serCtx.registerMarshaller(new BookMarshaller());
       }
    }

次のステップ

SerializationContextInitializer 実装を Data Grid 設定に追加して登録します。

シリアル化コンテキストイニシャライザーの登録 を参照してください。

5.2.3. シリアル化コンテキストイニシャライザーの登録

Data Grid 設定で SerializationContextInitializer 実装を宣言して登録します。

手順

  • 以下の例のように、プログラムまたは宣言的に SerializationContextInitializer 実装を手動で登録します。

プログラムによる設定

GlobalConfigurationBuilder builder = new GlobalConfigurationBuilder();
builder.serialization()
       .addContextInitializers(new LibraryInitializerImpl(), new SCIImpl());

宣言型設定

<serialization>
    <context-initializer class="org.infinispan.example.LibraryInitializerImpl"/>
    <context-initializer class="org.infinispan.example.another.SCIImpl"/>
</serialization>

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

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

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

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

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

会社概要

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

© 2024 Red Hat, Inc.