package com.emc.ecs.sync.storage;
import com.emc.ecs.sync.AbstractPlugin;
import com.emc.ecs.sync.model.ObjectSummary;
import com.emc.ecs.sync.model.SyncObject;
import com.emc.ecs.sync.util.PerformanceWindow;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import java.io.IOException;
import java.io.StringReader;
public abstract class AbstractStorage<C> extends AbstractPlugin<C> implements SyncStorage<C> {
// 500ms measurement interval, 20-second window
private PerformanceWindow readPerformanceCounter = new PerformanceWindow(500, 20);
private PerformanceWindow writePerformanceCounter = new PerformanceWindow(500, 20);
/**
* Try to create an appropriate ObjectSummary representing the specified object. Exceptions are allowed and it is
* not necessary to throw or recast to ObjectNotFoundException (that will be discovered later)
*/
protected abstract ObjectSummary createSummary(String identifier);
/**
* Default implementation uses a CSV parser to extract the first value, then sets the raw line of text on the summary
* to make it available to other plugins. Note that any overriding implementation *must* catch Exception from
* {@link #createSummary(String)} and return a new zero-sized {@link ObjectSummary} for the identifier
*/
@Override
public ObjectSummary parseListLine(String listLine) {
try {
CSVRecord record = CSVFormat.EXCEL.parse(new StringReader(listLine)).iterator().next();
ObjectSummary summary;
try {
summary = createSummary(record.get(0));
} catch (Exception e) {
summary = new ObjectSummary(record.get(0), false, 0);
}
summary.setListFileRow(listLine);
return summary;
} catch (IOException e) {
throw new RuntimeException("could not parse list-file line", e);
}
}
@Override
public String createObject(SyncObject object) {
String identifier = getIdentifier(object.getRelativePath(), object.getMetadata().isDirectory());
updateObject(identifier, object);
return identifier;
}
@Override
public void close() {
try (PerformanceWindow readWindow = readPerformanceCounter;
PerformanceWindow writeWindow = writePerformanceCounter) {
super.close();
}
}
@Override
protected void finalize() throws Throwable {
try {
close();
} finally {
super.finalize(); // make sure we call super.finalize() no matter what!
}
}
@Override
public void delete(String identifier) {
throw new UnsupportedOperationException(String.format("Delete is not supported by the %s plugin", getClass().getSimpleName()));
}
@Override
public long getReadRate() {
return readPerformanceCounter.getWindowRate();
}
@Override
public long getWriteRate() {
return writePerformanceCounter.getWindowRate();
}
@Override
public PerformanceWindow getReadWindow() {
return readPerformanceCounter;
}
@Override
public PerformanceWindow getWriteWindow() {
return writePerformanceCounter;
}
}