package io.airlift.airship.coordinator;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.io.Files;
import com.google.common.io.PatternFilenameFilter;
import io.airlift.airship.shared.ExpectedSlotStatus;
import io.airlift.airship.shared.FileUtils;
import io.airlift.json.JsonCodec;
import io.airlift.log.Logger;
import javax.inject.Inject;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
public class FileStateManager
implements StateManager
{
private static final Logger log = Logger.get(FileStateManager.class);
private final File dataDir;
private final JsonCodec<ExpectedSlotStatus> codec;
@Inject
public FileStateManager(FileStateManagerConfig fileStateManagerConfig, JsonCodec<ExpectedSlotStatus> codec)
{
this(new File(checkNotNull(fileStateManagerConfig, "fileStateManagerConfig is null").getExpectedStateDir()), codec);
}
public FileStateManager(File dataDir, JsonCodec<ExpectedSlotStatus> codec)
{
Preconditions.checkNotNull(dataDir, "dataDir is null");
Preconditions.checkNotNull(codec, "codec is null");
this.dataDir = dataDir;
this.codec = codec;
dataDir.mkdirs();
Preconditions.checkArgument(dataDir.isDirectory(), "dataDir is not a directory");
}
@Override
public Collection<ExpectedSlotStatus> getAllExpectedStates()
{
List<ExpectedSlotStatus> slots = newArrayList();
for (File file : FileUtils.listFiles(dataDir, new PatternFilenameFilter("[^\\.].*\\.json"))) {
try {
String json = Files.toString(file, Charsets.UTF_8);
ExpectedSlotStatus expectedSlotStatus = codec.fromJson(json);
slots.add(expectedSlotStatus);
}
catch (Exception e) {
// skip corrupted entries... these will be marked as unexpected
// and someone will resolve the conflict (and overwrite the corrupted record)
}
}
return slots;
}
@Override
public void deleteExpectedState(UUID slotId)
{
new File(dataDir, slotId.toString() + ".json").delete();
}
@Override
public void setExpectedState(ExpectedSlotStatus slotStatus)
{
Preconditions.checkNotNull(slotStatus, "slotStatus is null");
try {
Files.write(codec.toJson(slotStatus), new File(dataDir, slotStatus.getId().toString() + ".json"), Charsets.UTF_8);
}
catch (Exception e) {
log.error(e, "Error writing expected slot status");
}
}
}