package org.dcache.pool.repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.EnumSet;
import diskCacheV111.util.PnfsId;
public class MetaDataCopyTool
{
private static final Logger _log =
LoggerFactory.getLogger(MetaDataCopyTool.class);
static ReplicaStore createStore(Class<? extends ReplicaStore> clazz,
FileStore fileStore, File poolDir, boolean readOnly)
throws NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException
{
Constructor<? extends ReplicaStore> constructor =
clazz.getConstructor(FileStore.class, File.class, Boolean.TYPE);
return constructor.newInstance(fileStore, poolDir, readOnly);
}
public static void main(String[] args)
throws Exception
{
if (args.length != 3) {
System.err.println("Synopsis: MetaDataCopyTool DIR FROM TO");
System.err.println();
System.err.println("Where DIR is the pool directory, and FROM and TO are");
System.err.println("meta data store class names.");
System.exit(1);
}
File poolDir = new File(args[0]);
FileStore fromFileStore = new DummyFileStore(DummyFileStore.Mode.ALL_EXIST);
FileStore toFileStore = new DummyFileStore(DummyFileStore.Mode.NONE_EXIST);
try (ReplicaStore fromStore =
createStore(Class.forName(args[1]).asSubclass(ReplicaStore.class), fromFileStore, poolDir, true);
ReplicaStore toStore =
createStore(Class.forName(args[2]).asSubclass(ReplicaStore.class), toFileStore, poolDir, false)) {
fromStore.init();
toStore.init();
if (!toStore.index(ReplicaStore.IndexOption.META_ONLY).isEmpty()) {
System.err.println("ERROR: Target store is not empty");
System.exit(1);
}
Collection<PnfsId> ids = fromStore.index(ReplicaStore.IndexOption.META_ONLY);
int size = ids.size();
int count = 1;
for (PnfsId id : ids) {
_log.info("Copying {} ({} of {})", id, count, size);
ReplicaRecord entry = fromStore.get(id);
if (entry == null) {
System.err.println("Failed to load " + id);
System.exit(1);
}
toStore.create(id, EnumSet.noneOf(Repository.OpenFlags.class)).update(r -> {
/* NOTE: We do not copy the last access time, as this is currently stored
* as the last modification time on the data file. If we at some point move
* the last access time into the meta data, this has to be updated here.
*/
r.setState(entry.getState());
for (StickyRecord s : entry.stickyRecords()) {
r.setSticky(s.owner(), s.expire(), true);
}
r.setFileAttributes(entry.getFileAttributes());
return null;
});
count++;
}
}
}
}