List of usage examples for com.mongodb WriteResult getN
public int getN()
From source file:com.redhat.lightblue.crud.mongo.IterateAndUpdate.java
License:Open Source License
@Override public void update(CRUDOperationContext ctx, DBCollection collection, EntityMetadata md, CRUDUpdateResponse response, DBObject query) { LOGGER.debug("iterateUpdate: start"); LOGGER.debug("Computing the result set for {}", query); DBCursor cursor = null;//from w ww.j ava 2 s. c o m int docIndex = 0; int numFailed = 0; try { cursor = new FindCommand(null, collection, query, null).execute(); LOGGER.debug("Found {} documents", cursor.count()); // read-update-write while (cursor.hasNext()) { DBObject document = cursor.next(); boolean hasErrors = false; LOGGER.debug("Retrieved doc {}", docIndex); DocCtx doc = ctx.addDocument(translator.toJson(document)); doc.setOutputDocument(doc.copy()); // From now on: doc contains the old copy, and doc.getOutputDocument contains the new copy if (updater.update(doc.getOutputDocument(), md.getFieldTreeRoot(), Path.EMPTY)) { LOGGER.debug("Document {} modified, updating", docIndex); PredefinedFields.updateArraySizes(nodeFactory, doc.getOutputDocument()); LOGGER.debug("Running constraint validations"); validator.clearErrors(); validator.validateDoc(doc.getOutputDocument()); List<Error> errors = validator.getErrors(); if (errors != null && !errors.isEmpty()) { ctx.addErrors(errors); hasErrors = true; LOGGER.debug("Doc has errors"); } errors = validator.getDocErrors().get(doc.getOutputDocument()); if (errors != null && !errors.isEmpty()) { doc.addErrors(errors); hasErrors = true; LOGGER.debug("Doc has data errors"); } if (!hasErrors) { List<Path> paths = roleEval.getInaccessibleFields_Update(doc.getOutputDocument(), doc); LOGGER.debug("Inaccesible fields during update={}" + paths); if (paths != null && !paths.isEmpty()) { doc.addError(Error.get("update", CrudConstants.ERR_NO_FIELD_UPDATE_ACCESS, paths.toString())); hasErrors = true; } } if (!hasErrors) { try { DBObject updatedObject = translator.toBson(doc.getOutputDocument()); translator.addInvisibleFields(document, updatedObject, md); WriteResult result = new SaveCommand(null, collection, updatedObject).execute(); doc.setOperationPerformed(Operation.UPDATE); LOGGER.debug("Number of rows affected : ", result.getN()); } catch (Exception e) { LOGGER.warn("Update exception for document {}: {}", docIndex, e); doc.addError(Error.get(MongoCrudConstants.ERR_UPDATE_ERROR, e.toString())); hasErrors = true; } } } else { LOGGER.debug("Document {} was not modified", docIndex); } if (hasErrors) { LOGGER.debug("Document {} has errors", docIndex); numFailed++; doc.setOutputDocument(errorProjector.project(doc.getOutputDocument(), nodeFactory)); } else { if (projector != null) { LOGGER.debug("Projecting document {}", docIndex); doc.setOutputDocument(projector.project(doc.getOutputDocument(), nodeFactory)); } } docIndex++; } } finally { if (cursor != null) { cursor.close(); } } response.setNumUpdated(docIndex); response.setNumFailed(numFailed); }
From source file:com.redhat.lightblue.crud.mongo.IterateDeleter.java
License:Open Source License
@Override public void delete(CRUDOperationContext ctx, DBCollection collection, DBObject mongoQuery, CRUDDeleteResponse response) {//www .j ava 2 s . co m LOGGER.debug("Computing the result set for {}", mongoQuery); DBCursor cursor = null; int docIndex = 0; int numDeleted = 0; try { // Find docs cursor = new FindCommand(null, collection, mongoQuery, null).execute(); LOGGER.debug("Found {} documents", cursor.count()); // read-delet while (cursor.hasNext()) { DBObject document = cursor.next(); LOGGER.debug("Retrieved doc {}", docIndex); Object id = document.get(MongoCRUDController.ID_STR); DocCtx doc = ctx.addDocument(translator.toJson(document)); doc.setOriginalDocument(doc); WriteResult result = new RemoveCommand(null, collection, new BasicDBObject("_id", id), WriteConcern.SAFE).execute(); if (result.getN() == 1) { numDeleted++; doc.setOperationPerformed(Operation.DELETE); } docIndex++; } } finally { if (cursor != null) { cursor.close(); } } response.setNumDeleted(numDeleted); }
From source file:com.redhat.lightblue.crud.mongo.MongoLocking.java
License:Open Source License
/** * Attempt to acquire a lock. If successful, return true, otherwise return false. *///from w w w .j a va 2 s . com public boolean acquire(String callerId, String resourceId, Long ttl) { /* Creating an atomic acquire() method in mongodb is not easy. The key is to use the uniqueness of a unique index, in this case, a unique index on resourceId. There can be at most one lock record for a resource in the db at any given time. The insertion operation is atomic: if it is successful, we acquire the lock. We assume the update operation is transactional: once a document is found to be matching to the query of the update operation, it is locked, and no other caller can modify that document until our update operation is complete. We will use a version number to make sure we are updating the correct doc. */ LOGGER.debug("acquire({}/{},ttl={})", callerId, resourceId, ttl); // Try to insert doc Date now = new Date(); Date expiration; if (ttl == null) ttl = defaultTTL; expiration = new Date(now.getTime() + ttl); LOGGER.debug("{}/{}: lock will expire on {}", callerId, resourceId, expiration); BasicDBObject query; BasicDBObject update; WriteResult wr; int readVer = -1; String readCallerId = null; int readCount = -1; boolean locked = acquire(callerId, resourceId, ttl, now, expiration); if (!locked) { // At this point, we can add "if expired" predicate to the // queries to filter expired locks, but it is not safe to // rely on timestamps. Not all nodes have the same // timestamp, and any node can wait an arbitrary amount of // time at any point. So, we read the existing lock at // this point, and use the version number for all the // updates. if anybody updates the lock before we do, the // version number will change, and we will fail. query = new BasicDBObject(RESOURCEID, resourceId); LOGGER.debug("find: {}", query); DBObject lockObject = coll.findOne(query); if (lockObject == null) { LOGGER.debug("{}/{}: lock cannot be read. Retrying to acquire", callerId, resourceId); locked = acquire(callerId, resourceId, ttl, now, expiration); LOGGER.debug("{}/{}: acquire result: {}", callerId, resourceId, locked); // No need to continue here. If insertion fails, that means someone else inserted a record return locked; } readVer = ((Number) lockObject.get(VERSION)).intValue(); readCallerId = (String) lockObject.get(CALLERID); readCount = ((Number) lockObject.get(COUNT)).intValue(); // Lock already exists // Possibilities: // - lock is not expired, but ours : increment count // - lock is not expired, but someone else owns it : fail // - lock is expired : attempt to acquire // - lock count is less than 1 : attempt to acquire // lock is not expired and we own it: increment lock count LOGGER.debug("{}/{} locked, assuming lock is ours, attempting to increment lock count", callerId, resourceId); if (readCallerId.equals(callerId)) { query = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(VERSION, readVer); update = new BasicDBObject() .append("$set", new BasicDBObject(TIMESTAMP, now).append(EXPIRATION, expiration).append(TTL, ttl)) .append("$inc", new BasicDBObject(VERSION, 1).append(COUNT, 1)); LOGGER.debug("update: {} {}", query, update); wr = coll.update(query, update, false, false, WriteConcern.SAFE); if (wr.getN() == 1) { LOGGER.debug("{}/{} locked again", callerId, resourceId); locked = true; } } } if (!locked) { // assume lock is expired or count <=0, and try to acquire it LOGGER.debug("{}/{} lock is expired or count <= 0, attempting to reacquire expired lock", callerId, resourceId); query = new BasicDBObject().append(RESOURCEID, resourceId) .append("$or", Arrays.asList(new BasicDBObject(EXPIRATION, new BasicDBObject("$lte", now)), new BasicDBObject(COUNT, new BasicDBObject("$lte", 0)))) .append(VERSION, readVer); update = new BasicDBObject() .append("$set", new BasicDBObject(CALLERID, callerId).append(TIMESTAMP, now) .append(EXPIRATION, expiration).append(TTL, ttl).append(COUNT, 1)) .append("$inc", new BasicDBObject(VERSION, 1)); LOGGER.debug("update: {} {}", query, update); wr = coll.update(query, update, false, false, WriteConcern.SAFE); if (wr.getN() == 1) { LOGGER.debug("{}/{} locked", callerId, resourceId); locked = true; } } LOGGER.debug("{}/{}: {}", callerId, resourceId, locked ? "locked" : "not locked"); return locked; }
From source file:com.redhat.lightblue.crud.mongo.MongoLocking.java
License:Open Source License
/** * Release the lock. Returns true if the lock is released by this call *///from w ww .j a va 2 s. c o m public boolean release(String callerId, String resourceId) { LOGGER.debug("release({}/{})", callerId, resourceId); Date now = new Date(); // If lock count is only one, we can remove the lock BasicDBObject query = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(COUNT, 1); LOGGER.debug("remove {}", query); WriteResult wr = coll.remove(query, WriteConcern.SAFE); if (wr.getN() == 1) { LOGGER.debug("{}/{} released", callerId, resourceId); return true; } // Retrieve the lock query = new BasicDBObject(RESOURCEID, resourceId).append(CALLERID, callerId); DBObject lock = coll.findOne(query); if (lock != null) { long ttl = ((Number) lock.get(TTL)).longValue(); Date expiration = new Date(now.getTime() + ttl); int ver = ((Number) lock.get(VERSION)).intValue(); // Try decrementing the lock count of our lock query = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(COUNT, new BasicDBObject("$gt", 0)) .append(VERSION, ver); BasicDBObject update = new BasicDBObject() .append("$set", new BasicDBObject(EXPIRATION, expiration).append(TTL, ttl).append(TIMESTAMP, now)) .append("$inc", new BasicDBObject(COUNT, -1).append(VERSION, 1)); wr = coll.update(query, update, false, false, WriteConcern.SAFE); if (wr.getN() == 1) { LOGGER.debug("{}/{} lock count decremented, still locked", callerId, resourceId); return false; } } // Both attempts failed, Lock is no longer owned by us throw new InvalidLockException(resourceId); }
From source file:com.redhat.lightblue.crud.mongo.MongoLocking.java
License:Open Source License
public void ping(String callerId, String resourceId) { Date now = new Date(); BasicDBObject q = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(COUNT, new BasicDBObject("$gt", 0)); DBObject lock = coll.findOne(q);/*from w ww .j av a 2 s.c o m*/ if (lock != null) { Date expiration = new Date(now.getTime() + ((Number) lock.get(TTL)).longValue()); int ver = ((Number) lock.get(VERSION)).intValue(); BasicDBObject update = new BasicDBObject() .append("$set", new BasicDBObject(TIMESTAMP, now).append(EXPIRATION, expiration)) .append("$inc", new BasicDBObject(VERSION, 1)); q = q.append(VERSION, ver); WriteResult wr = coll.update(q, update, false, false, WriteConcern.SAFE); if (wr.getN() != 1) throw new InvalidLockException(resourceId); LOGGER.debug("{}/{} pinged", callerId, resourceId); } else throw new InvalidLockException(resourceId); }
From source file:com.redhat.lightblue.metadata.mongo.MetadataCache.java
License:Open Source License
/** * Update the collection version in db, and invalidate cache *//*from w ww .j av a 2s .co m*/ public synchronized void updateCollectionVersion(DBCollection collection) { BasicDBObject query = new BasicDBObject(MongoMetadata.LITERAL_ID, LITERAL_COLL_VER); BasicDBObject update = new BasicDBObject("$inc", new BasicDBObject(LITERAL_COLL_VER, 1)); int nUpdated; try { WriteResult r = collection.update(query, update); nUpdated = r.getN(); } catch (Exception e) { nUpdated = 0; } if (nUpdated == 0) { // Try to ins BasicDBObject doc = new BasicDBObject(MongoMetadata.LITERAL_ID, LITERAL_COLL_VER); doc.put(LITERAL_COLL_VER, 0l); try { collection.insert(doc); } catch (Exception e) { } } cache.clear(); }
From source file:com.redhat.lightblue.mongo.crud.MongoLocking.java
License:Open Source License
/** * Attempt to acquire a lock. If successful, return true, otherwise return * false.//from ww w.java2 s.c o m */ public boolean acquire(String callerId, String resourceId, Long ttl) { /* Creating an atomic acquire() method in mongodb is not easy. The key is to use the uniqueness of a unique index, in this case, a unique index on resourceId. There can be at most one lock record for a resource in the db at any given time. The insertion operation is atomic: if it is successful, we acquire the lock. We assume the update operation is transactional: once a document is found to be matching to the query of the update operation, it is locked, and no other caller can modify that document until our update operation is complete. We will use a version number to make sure we are updating the correct doc. */ LOGGER.debug("acquire({}/{},ttl={})", callerId, resourceId, ttl); // Try to insert doc Date now = new Date(); Date expiration; if (ttl == null) { ttl = defaultTTL; } expiration = new Date(now.getTime() + ttl); LOGGER.debug("{}/{}: lock will expire on {}", callerId, resourceId, expiration); BasicDBObject query; BasicDBObject update; WriteResult wr; int readVer = -1; String readCallerId = null; int readCount = -1; boolean locked = acquire(callerId, resourceId, ttl, now, expiration); if (!locked) { // At this point, we can add "if expired" predicate to the // queries to filter expired locks, but it is not safe to // rely on timestamps. Not all nodes have the same // timestamp, and any node can wait an arbitrary amount of // time at any point. So, we read the existing lock at // this point, and use the version number for all the // updates. if anybody updates the lock before we do, the // version number will change, and we will fail. query = new BasicDBObject(RESOURCEID, resourceId); LOGGER.debug("find: {}", query); DBObject lockObject = coll.findOne(query, null, ReadPreference.primary()); if (lockObject == null) { LOGGER.debug("{}/{}: lock cannot be read. Retrying to acquire", callerId, resourceId); locked = acquire(callerId, resourceId, ttl, now, expiration); LOGGER.debug("{}/{}: acquire result: {}", callerId, resourceId, locked); // No need to continue here. If insertion fails, that means someone else inserted a record return locked; } readVer = ((Number) lockObject.get(VERSION)).intValue(); readCallerId = (String) lockObject.get(CALLERID); readCount = ((Number) lockObject.get(COUNT)).intValue(); // Lock already exists // Possibilities: // - lock is not expired, but ours : increment count // - lock is not expired, but someone else owns it : fail // - lock is expired : attempt to acquire // - lock count is less than 1 : attempt to acquire // lock is not expired and we own it: increment lock count LOGGER.debug("{}/{} locked, assuming lock is ours, attempting to increment lock count", callerId, resourceId); if (readCallerId.equals(callerId)) { query = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(VERSION, readVer); update = new BasicDBObject() .append("$set", new BasicDBObject(TIMESTAMP, now).append(EXPIRATION, expiration).append(TTL, ttl)) .append("$inc", new BasicDBObject(VERSION, 1).append(COUNT, 1)); LOGGER.debug("update: {} {}", query, update); wr = coll.update(query, update, false, false, WriteConcern.ACKNOWLEDGED); if (wr.getN() == 1) { LOGGER.debug("{}/{} locked again", callerId, resourceId); locked = true; } } } if (!locked) { // assume lock is expired or count <=0, and try to acquire it LOGGER.debug("{}/{} lock is expired or count <= 0, attempting to reacquire expired lock", callerId, resourceId); query = new BasicDBObject().append(RESOURCEID, resourceId) .append("$or", Arrays.asList(new BasicDBObject(EXPIRATION, new BasicDBObject("$lte", now)), new BasicDBObject(COUNT, new BasicDBObject("$lte", 0)))) .append(VERSION, readVer); update = new BasicDBObject() .append("$set", new BasicDBObject(CALLERID, callerId).append(TIMESTAMP, now) .append(EXPIRATION, expiration).append(TTL, ttl).append(COUNT, 1)) .append("$inc", new BasicDBObject(VERSION, 1)); LOGGER.debug("update: {} {}", query, update); wr = coll.update(query, update, false, false, WriteConcern.ACKNOWLEDGED); if (wr.getN() == 1) { LOGGER.debug("{}/{} locked", callerId, resourceId); locked = true; } } LOGGER.debug("{}/{}: {}", callerId, resourceId, locked ? "locked" : "not locked"); return locked; }
From source file:com.redhat.lightblue.mongo.crud.MongoLocking.java
License:Open Source License
/** * Release the lock. Returns true if the lock is released by this call *///from w ww . j av a 2s . co m public boolean release(String callerId, String resourceId) { LOGGER.debug("release({}/{})", callerId, resourceId); Date now = new Date(); // If lock count is only one, we can remove the lock BasicDBObject query = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(COUNT, 1); LOGGER.debug("remove {}", query); WriteResult wr = coll.remove(query, WriteConcern.ACKNOWLEDGED); if (wr.getN() == 1) { LOGGER.debug("{}/{} released", callerId, resourceId); return true; } // Retrieve the lock query = new BasicDBObject(RESOURCEID, resourceId).append(CALLERID, callerId); DBObject lock = coll.findOne(query, null, ReadPreference.primary()); if (lock != null) { long ttl = ((Number) lock.get(TTL)).longValue(); Date expiration = new Date(now.getTime() + ttl); int ver = ((Number) lock.get(VERSION)).intValue(); // Try decrementing the lock count of our lock query = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(COUNT, new BasicDBObject("$gt", 0)) .append(VERSION, ver); BasicDBObject update = new BasicDBObject() .append("$set", new BasicDBObject(EXPIRATION, expiration).append(TTL, ttl).append(TIMESTAMP, now)) .append("$inc", new BasicDBObject(COUNT, -1).append(VERSION, 1)); wr = coll.update(query, update, false, false, WriteConcern.ACKNOWLEDGED); if (wr.getN() == 1) { LOGGER.debug("{}/{} lock count decremented, still locked", callerId, resourceId); return false; } } // Both attempts failed, Lock is no longer owned by us throw new InvalidLockException(resourceId); }
From source file:com.redhat.lightblue.mongo.crud.MongoLocking.java
License:Open Source License
public void ping(String callerId, String resourceId) { Date now = new Date(); BasicDBObject q = new BasicDBObject().append(CALLERID, callerId).append(RESOURCEID, resourceId) .append(EXPIRATION, new BasicDBObject("$gt", now)).append(COUNT, new BasicDBObject("$gt", 0)); DBObject lock = coll.findOne(q, null, ReadPreference.primary()); if (lock != null) { Date expiration = new Date(now.getTime() + ((Number) lock.get(TTL)).longValue()); int ver = ((Number) lock.get(VERSION)).intValue(); BasicDBObject update = new BasicDBObject() .append("$set", new BasicDBObject(TIMESTAMP, now).append(EXPIRATION, expiration)) .append("$inc", new BasicDBObject(VERSION, 1)); q = q.append(VERSION, ver);/*from ww w . j a va 2s . c o m*/ WriteResult wr = coll.update(q, update, false, false, WriteConcern.ACKNOWLEDGED); if (wr.getN() != 1) { throw new InvalidLockException(resourceId); } LOGGER.debug("{}/{} pinged", callerId, resourceId); } else { throw new InvalidLockException(resourceId); } }
From source file:com.sitewhere.mongodb.device.MongoDeviceManagement.java
License:Open Source License
@Override public List<IDeviceGroupElement> removeDeviceGroupElements(String groupToken, List<IDeviceGroupElementCreateRequest> elements) throws SiteWhereException { List<IDeviceGroupElement> deleted = new ArrayList<IDeviceGroupElement>(); for (IDeviceGroupElementCreateRequest request : elements) { BasicDBObject match = new BasicDBObject(MongoDeviceGroupElement.PROP_GROUP_TOKEN, groupToken) .append(MongoDeviceGroupElement.PROP_TYPE, request.getType().name()) .append(MongoDeviceGroupElement.PROP_ELEMENT_ID, request.getElementId()); DBCursor found = getMongoClient().getGroupElementsCollection().find(match); while (found.hasNext()) { DBObject current = found.next(); WriteResult result = MongoPersistence.delete(getMongoClient().getGroupElementsCollection(), current);//w w w . j ava 2 s . co m if (result.getN() > 0) { deleted.add(MongoDeviceGroupElement.fromDBObject(current)); } } } return deleted; }