package com.github.mongobee.dao; import org.bson.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mongodb.ErrorCategory; import com.mongodb.MongoWriteException; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.IndexOptions; /** * @author colsson11 * @since 13.01.15 */ public class LockDao { private static final Logger logger = LoggerFactory.getLogger(LockDao.class); private static final String COLLECTION = "mongobeelock"; private static final String KEY_PROP_NAME = "key"; private static final int INDEX_SORT_ASC = 1; private static final String LOCK_ENTRY_KEY_VAL = "LOCK"; public void intitializeLock(MongoDatabase db) { createCollectionAndUniqueIndexIfNotExists(db); } private void createCollectionAndUniqueIndexIfNotExists(MongoDatabase db) { Document indexKeys = new Document(KEY_PROP_NAME, INDEX_SORT_ASC); IndexOptions indexOptions = new IndexOptions().unique(true).name("mongobeelock_key_idx"); db.getCollection(COLLECTION).createIndex(indexKeys, indexOptions); } public boolean acquireLock(MongoDatabase db) { Document insertObj = new Document(KEY_PROP_NAME, LOCK_ENTRY_KEY_VAL).append("status", "LOCK_HELD"); // acquire lock by attempting to insert the same value in the collection - if it already exists (i.e. lock held) // there will be an exception try { db.getCollection(COLLECTION).insertOne(insertObj); } catch (MongoWriteException ex) { if (ex.getError().getCategory() == ErrorCategory.DUPLICATE_KEY) { logger.warn("Duplicate key exception while acquireLock. Probably the lock has been already acquired."); } return false; } return true; } public void releaseLock(MongoDatabase db) { // release lock by deleting collection entry db.getCollection(COLLECTION).deleteMany(new Document(KEY_PROP_NAME, LOCK_ENTRY_KEY_VAL)); } /** * Check if the lock is held. Could be used by external process for example. * * @param db MongoDatabase object * @return true if the lock is currently held */ public boolean isLockHeld(MongoDatabase db) { return db.getCollection(COLLECTION).count() == 1; } }