package org.dcache.pool.repository.meta.db;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.DiskOrderedCursor;
import com.sleepycat.je.DiskOrderedCursorConfig;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.EnvironmentFailureException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Properties;
/**
* MetaDataRepositoryDatabase encapsulates the initialisation of
* the BerkelyDB used for storing meta data.
*/
public class ReplicaStoreDatabase
{
private static final Logger _log =
LoggerFactory.getLogger("logger.org.dcache.repository");
private final Environment env;
private static final String CLASS_CATALOG = "java_class_catalog";
private static final String STORAGE_INFO_STORE = "storage_info_store";
private static final String STATE_STORE = "state_store";
private final StoredClassCatalog javaCatalog;
private final Database storageInfoDatabase;
private final Database stateDatabase;
private boolean _failed;
private boolean _closed;
public ReplicaStoreDatabase(Properties properties, File homeDirectory, boolean readonly)
throws DatabaseException
{
EnvironmentConfig envConfig = new EnvironmentConfig(properties);
envConfig.setTransactional(true);
envConfig.setAllowCreate(true);
envConfig.setReadOnly(readonly);
env = new Environment(homeDirectory, envConfig);
envConfig.setExceptionListener(event -> {
if (event.getException() instanceof EnvironmentFailureException && !env.isValid()) {
setFailed();
_log.error("Pool restart required due to Berkeley DB failure: " + event.getException().getMessage());
}
});
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setTransactional(true);
dbConfig.setAllowCreate(true);
dbConfig.setReadOnly(readonly);
Database catalogDb = env.openDatabase(null, CLASS_CATALOG, dbConfig);
javaCatalog = new StoredClassCatalog(catalogDb);
storageInfoDatabase =
env.openDatabase(null, STORAGE_INFO_STORE, dbConfig);
stateDatabase = env.openDatabase(null, STATE_STORE, dbConfig);
}
private synchronized void setFailed()
{
_failed = true;
}
public synchronized boolean isFailed()
{
return _failed;
}
public synchronized void close()
throws DatabaseException
{
if (!_closed) {
stateDatabase.close();
storageInfoDatabase.close();
javaCatalog.close();
env.close();
_closed = true;
}
}
public final Environment getEnvironment()
{
return env;
}
public final StoredClassCatalog getClassCatalog()
{
return javaCatalog;
}
public final Database getStorageInfoDatabase()
{
return storageInfoDatabase;
}
public final Database getStateDatabase()
{
return stateDatabase;
}
public DiskOrderedCursor openKeyCursor()
{
DiskOrderedCursorConfig config = new DiskOrderedCursorConfig();
config.setKeysOnly(true);
return env.openDiskOrderedCursor(new Database[]{storageInfoDatabase, stateDatabase}, config);
}
}