package org.infinispan.server.hotrod;
import java.io.IOException;
import java.util.Set;
import java.util.stream.Collectors;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.marshall.Marshaller;
import org.infinispan.commons.marshall.jboss.GenericJBossMarshaller;
import org.infinispan.container.versioning.NumericVersion;
import org.infinispan.metadata.EmbeddedMetadata.Builder;
import org.infinispan.metadata.Metadata;
import org.infinispan.upgrade.SourceMigrator;
/**
* An implementation of Migrator, that understands the Hot Rod key and value formats.
*
* @author Manik Surtani
* @since 5.2
*/
class HotRodSourceMigrator implements SourceMigrator {
private final static String KNOWN_KEY = "___MigrationManager_HotRod_KnownKeys___";
private final AdvancedCache<byte[], byte[]> cache;
private final Marshaller marshaller;
@Override
public String getCacheName() {
return cache.getName();
}
HotRodSourceMigrator(AdvancedCache<byte[], byte[]> cache) {
this.cache = cache;
this.marshaller = new GenericJBossMarshaller(); // TODO: Hard coded! Yuck! Assumes the Synchronizer service will use the same marshaller. Doesn't matter what actual clients use to store/retrieve data.
}
@Override
public void recordKnownGlobalKeyset() {
try {
// TODO: the bulk of this code is reusable across different implementations of Migrator
byte[] bak = marshaller.objectToByteBuffer(KNOWN_KEY);
Set<byte[]> allKeys = cache.keySet();
Set<byte[]> copy = allKeys.stream().collect(Collectors.toSet());
// Remove KNOWN_KEY from the key set - just in case it is there from a previous run.
copy.remove(bak);
// we cannot store the Set as it is; it will break if attempting to be read via Hot Rod. This should be wrapped
// in a CacheValue.
Metadata metadata = new Builder().version(new NumericVersion(1)).build();
cache.put(bak, marshaller.objectToByteBuffer(copy), metadata);
} catch (InterruptedException | IOException e) {
throw new CacheException(e);
}
}
}