Example usage for com.mongodb WriteResult getN

List of usage examples for com.mongodb WriteResult getN

Introduction

In this page you can find the example usage for com.mongodb WriteResult getN.

Prototype

public int getN() 

Source Link

Document

Gets the "n" field, which contains the number of documents affected in the write operation.

Usage

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;
}