use of org.apache.jackrabbit.core.data.DataStoreException in project jackrabbit by apache.
the class DbDataStore method addRecord.
public DataRecord addRecord(InputStream stream) throws DataStoreException {
InputStream fileInput = null;
String tempId = null;
ResultSet rs = null;
try {
long tempModified;
while (true) {
try {
tempModified = System.currentTimeMillis();
String id = UUID.randomUUID().toString();
tempId = TEMP_PREFIX + id;
temporaryInUse.add(tempId);
// SELECT LENGTH, LAST_MODIFIED FROM DATASTORE WHERE ID=?
rs = conHelper.query(selectMetaSQL, tempId);
boolean hasNext = rs.next();
DbUtility.close(rs);
rs = null;
if (hasNext) {
// re-try in the very, very unlikely event that the row already exists
continue;
}
// INSERT INTO DATASTORE VALUES(?, 0, ?, NULL)
conHelper.exec(insertTempSQL, tempId, tempModified);
break;
} catch (Exception e) {
throw convert("Can not insert new record", e);
} finally {
DbUtility.close(rs);
// prevent that rs.close() is called again
rs = null;
}
}
MessageDigest digest = getDigest();
DigestInputStream dIn = new DigestInputStream(stream, digest);
CountingInputStream in = new CountingInputStream(dIn);
StreamWrapper wrapper;
if (STORE_SIZE_MINUS_ONE.equals(storeStream)) {
wrapper = new StreamWrapper(in, -1);
} else if (STORE_SIZE_MAX.equals(storeStream)) {
wrapper = new StreamWrapper(in, Integer.MAX_VALUE);
} else if (STORE_TEMP_FILE.equals(storeStream)) {
File temp = moveToTempFile(in);
long length = temp.length();
wrapper = new StreamWrapper(new ResettableTempFileInputStream(temp), length);
} else {
throw new DataStoreException("Unsupported stream store algorithm: " + storeStream);
}
// UPDATE DATASTORE SET DATA=? WHERE ID=?
conHelper.exec(updateDataSQL, wrapper, tempId);
long length = in.getByteCount();
DataIdentifier identifier = new DataIdentifier(encodeHexString(digest.digest()));
usesIdentifier(identifier);
String id = identifier.toString();
long newModified;
while (true) {
newModified = System.currentTimeMillis();
if (checkExisting(tempId, length, identifier)) {
touch(identifier, newModified);
conHelper.exec(deleteSQL, tempId);
break;
}
try {
// UPDATE DATASTORE SET ID=?, LENGTH=?, LAST_MODIFIED=?
// WHERE ID=? AND LAST_MODIFIED=?
int count = conHelper.update(updateSQL, id, length, newModified, tempId, tempModified);
// collection could delete rows)
if (count != 0) {
// update was successful
break;
}
} catch (SQLException e) {
// duplicate key (the row already exists) - repeat
// we use exception handling for flow control here, which is bad,
// but the alternative is to use UPDATE ... WHERE ... (SELECT ...)
// which could cause a deadlock in some databases - also,
// duplicate key will only occur if somebody else concurrently
// added the same record (which is very unlikely)
}
// SELECT LENGTH, LAST_MODIFIED FROM DATASTORE WHERE ID=?
rs = conHelper.query(selectMetaSQL, tempId);
if (!rs.next()) {
// the row was deleted, which is unexpected / not allowed
String msg = DIGEST + " temporary entry deleted: " + " id=" + tempId + " length=" + length;
log.error(msg);
throw new DataStoreException(msg);
}
tempModified = rs.getLong(2);
DbUtility.close(rs);
rs = null;
}
usesIdentifier(identifier);
DbDataRecord record = new DbDataRecord(this, identifier, length, newModified);
return record;
} catch (Exception e) {
throw convert("Can not insert new record", e);
} finally {
if (tempId != null) {
temporaryInUse.remove(tempId);
}
DbUtility.close(rs);
if (fileInput != null) {
try {
fileInput.close();
} catch (IOException e) {
throw convert("Can not close temporary file", e);
}
}
}
}
use of org.apache.jackrabbit.core.data.DataStoreException in project jackrabbit by apache.
the class DbDataStore method checkExisting.
/**
* Check if a row with this ID already exists.
*
* @return true if the row exists and the length matches
* @throw DataStoreException if a row exists, but the length is different
*/
private boolean checkExisting(String tempId, long length, DataIdentifier identifier) throws DataStoreException, SQLException {
String id = identifier.toString();
// SELECT LENGTH, LAST_MODIFIED FROM DATASTORE WHERE ID=?
ResultSet rs = null;
try {
rs = conHelper.query(selectMetaSQL, id);
if (rs.next()) {
long oldLength = rs.getLong(1);
long lastModified = rs.getLong(2);
if (oldLength != length) {
String msg = DIGEST + " collision: temp=" + tempId + " id=" + id + " length=" + length + " oldLength=" + oldLength;
log.error(msg);
throw new DataStoreException(msg);
}
DbUtility.close(rs);
rs = null;
touch(identifier, lastModified);
// row already exists
conHelper.exec(deleteSQL, tempId);
return true;
}
} finally {
DbUtility.close(rs);
}
return false;
}
use of org.apache.jackrabbit.core.data.DataStoreException in project jackrabbit by apache.
the class DbDataStore method deleteAllOlderThan.
public synchronized int deleteAllOlderThan(long min) throws DataStoreException {
try {
ArrayList<String> touch = new ArrayList<String>();
ArrayList<DataIdentifier> ids = new ArrayList<DataIdentifier>(inUse.keySet());
for (DataIdentifier identifier : ids) {
if (identifier != null) {
touch.add(identifier.toString());
}
}
touch.addAll(temporaryInUse);
for (String key : touch) {
updateLastModifiedDate(key, 0);
}
// DELETE FROM DATASTORE WHERE LAST_MODIFIED<?
return conHelper.update(deleteOlderSQL, min);
} catch (Exception e) {
throw convert("Can not delete records", e);
}
}
use of org.apache.jackrabbit.core.data.DataStoreException in project jackrabbit by apache.
the class DbDataStore method getRecordIfStored.
public DataRecord getRecordIfStored(DataIdentifier identifier) throws DataStoreException {
usesIdentifier(identifier);
ResultSet rs = null;
try {
String id = identifier.toString();
// SELECT LENGTH, LAST_MODIFIED FROM DATASTORE WHERE ID = ?
rs = conHelper.query(selectMetaSQL, id);
if (!rs.next()) {
return null;
}
long length = rs.getLong(1);
long lastModified = rs.getLong(2);
DbUtility.close(rs);
rs = null;
lastModified = touch(identifier, lastModified);
return new DbDataRecord(this, identifier, length, lastModified);
} catch (Exception e) {
throw convert("Can not read identifier " + identifier, e);
} finally {
DbUtility.close(rs);
}
}
use of org.apache.jackrabbit.core.data.DataStoreException in project jackrabbit by apache.
the class RepositoryImpl method doShutdown.
/**
* Protected method that performs the actual shutdown after the shutdown
* lock has been acquired by the {@link #shutdown()} method.
*/
protected synchronized void doShutdown() {
log.info("Shutting down repository...");
// stop optional cluster node
ClusterNode clusterNode = context.getClusterNode();
if (clusterNode != null) {
clusterNode.stop();
}
if (securityMgr != null) {
securityMgr.close();
}
// close active user sessions
// (copy sessions to array to avoid ConcurrentModificationException;
// manually copy entries rather than calling ReferenceMap#toArray() in
// order to work around http://issues.apache.org/bugzilla/show_bug.cgi?id=25551)
List<Session> sa;
synchronized (activeSessions) {
sa = new ArrayList<Session>(activeSessions.size());
for (Session session : activeSessions.values()) {
sa.add(session);
}
}
for (Session session : sa) {
if (session != null) {
session.logout();
}
}
// shutdown system search manager if there is one
if (systemSearchMgr != null) {
systemSearchMgr.close();
}
// shut down workspaces
synchronized (wspInfos) {
for (WorkspaceInfo wspInfo : wspInfos.values()) {
wspInfo.dispose();
}
}
try {
InternalVersionManager m = context.getInternalVersionManager();
if (m != null) {
m.close();
}
} catch (Exception e) {
log.error("Error while closing Version Manager.", e);
}
repDescriptors.clear();
DataStore dataStore = context.getDataStore();
if (dataStore != null) {
try {
// close the datastore
dataStore.close();
} catch (DataStoreException e) {
log.error("error while closing datastore", e);
}
}
try {
// close repository file system
context.getFileSystem().close();
} catch (FileSystemException e) {
log.error("error while closing repository file system", e);
}
try {
nodeIdFactory.close();
} catch (RepositoryException e) {
log.error("error while closing repository file system", e);
}
// make sure this instance is not used anymore
disposed = true;
// wake up threads waiting on this instance's monitor (e.g. workspace janitor)
notifyAll();
// Shut down the executor service
ScheduledExecutorService executor = context.getExecutor();
executor.shutdown();
try {
// Wait for all remaining background threads to terminate
if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
log.warn("Attempting to forcibly shutdown runaway threads");
executor.shutdownNow();
}
} catch (InterruptedException e) {
log.warn("Interrupted while waiting for background threads", e);
}
repConfig.getConnectionFactory().close();
// finally release repository lock
if (repLock != null) {
try {
repLock.release();
} catch (RepositoryException e) {
log.error("failed to release the repository lock", e);
}
}
log.info("Repository has been shutdown");
}
Aggregations