iXô
iXô

Reputation: 1182

Updating from Infinispan 7 to 10, how to deal with UUID as key of UUID as field in a class?

I am trying to update a big project that was using Infinispan 7 to the v10.1.3.

I would like to use the new protostream marshaller, but I don't understand how to be able to use UUID as cache key, or even (easier ?) as a field in a class that I want to insert in a cache.

My cache was accessed like that : Map<UUID, Foo> testUUIDAsKey = manager.getCache("t1");

Here when trying to put a value into the cache, infinispan tells me that he don't know how to marshal an uuid.

Ok, so after reading the documentation, I tryied to switch to a easier test case : Map<String, Bar> testUUIDAsField = manager.getCache("t2");

Here, the Bar class have a field of type UUID, and I tried to use the protostream annotation processor that will generated and build a proto file automatically when the right annotation are used.

But this time, the annotation processor tells me that UUID class must be instantiable using an accessible no-argument constructor.

I know that protobuf can't manage UUID, I can store the value as string or by storing the 2 long values part of an uuid.

How can I register a UUID marshaller that would use String as it representation in the end ?

And how can I tell the annotation processor that it must use this marshaller ?

Then, how can I use UUID as a key ?

Thanks.

Upvotes: 1

Views: 569

Answers (1)

Ryan Emerson
Ryan Emerson

Reputation: 406

Currently Infinispan registers a Protostream marshaller for the UUID, but unfortunately it is only in the server. I have created ISPN-11426 to make it so that UUIDs will be marshallable out of the box in embedded mode in future releases (10.1.4.Final and 11.x).

In the mean time, you can get UUIDs to work as the key by creating a SerializationContextInitializer and defining a UUIDMarshallerclass:


       public static class Initializer implements SerializationContextInitializer {

          @Override
          public String getProtoFileName() {
             return "org.example.package.proto";
          }

          @Override
          public String getProtoFile() throws UncheckedIOException {
             return "package org.example.package;\n" +
                   "message UUID {\n" +
                   "    optional string value = 1;\n" +
                   "}\n";
          }

          @Override
          public void registerSchema(SerializationContext serCtx) {
             serCtx.registerProtoFiles(org.infinispan.protostream.FileDescriptorSource.fromString(getProtoFileName(), getProtoFile()));
          }

          @Override
          public void registerMarshallers(SerializationContext serCtx) {
             serCtx.registerMarshaller(new UUIDMarshaller("org.example.package.UUID"));
          }
       }

    import java.io.IOException;
    import java.util.UUID;

    import org.infinispan.protostream.MessageMarshaller;

    public class UUIDMarshaller implements MessageMarshaller<UUID> {

       private final String typeName;

       /**
        * @param typeName so that marshaller can be used in multiple contexts
        */
       public UUIDMarshaller(String typeName) {
          this.typeName = typeName;
       }

       @Override
       public UUID readFrom(ProtoStreamReader reader) throws IOException {
          return UUID.fromString(reader.readString("value"));
       }

       @Override
       public void writeTo(ProtoStreamWriter writer, UUID uuid) throws IOException {
          writer.writeString("value", uuid.toString());
       }

       @Override
       public Class<? extends UUID> getJavaClass() {
          return UUID.class;
       }

       @Override
       public String getTypeName() {
          return typeName;
       }
    }

You will need to update the org.example.package to something relevant to your project.

The Initializer class can then be provided programmatically via:

new GlobalConfigurationBuilder().serialization().addContextInitializer(new Initializer());

Or via xml:

      <serialization>
         <context-initializer class="org.example.package.Initializer" />
      </serialization>

Upvotes: 4

Related Questions