Search in sources :

Example 11 with ChangeRecord

use of org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord in project fabric8 by jboss-fuse.

the class PrepRequestProcessor method getRecordForPath.

ChangeRecord getRecordForPath(String path) throws KeeperException.NoNodeException {
    ChangeRecord lastChange = null;
    synchronized (zks.outstandingChanges) {
        lastChange = zks.outstandingChangesForPath.get(path);
        if (lastChange == null) {
            DataNode n = zks.getZKDatabase().getNode(path);
            if (n != null) {
                Long acl;
                Set<String> children;
                synchronized (n) {
                    acl = n.acl;
                    children = n.getChildren();
                }
                lastChange = new ChangeRecord(-1, path, n.stat, children != null ? children.size() : 0, zks.getZKDatabase().convertLong(acl));
            }
        }
    }
    if (lastChange == null || lastChange.stat == null) {
        throw new KeeperException.NoNodeException(path);
    }
    return lastChange;
}
Also used : ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord)

Example 12 with ChangeRecord

use of org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord in project fabric8 by jboss-fuse.

the class PrepRequestProcessor method pRequest2Txn.

/**
 * This method will be called inside the ProcessRequestThread, which is a
 * singleton, so there will be a single thread calling this code.
 *
 * @param type
 * @param zxid
 * @param request
 * @param record
 */
@SuppressWarnings("unchecked")
protected void pRequest2Txn(int type, long zxid, Request request, Record record, boolean deserialize) throws KeeperException, IOException, RequestProcessorException {
    request.hdr = new TxnHeader(request.sessionId, request.cxid, zxid, zks.getTime(), type);
    switch(type) {
        case OpCode.create:
            zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            CreateRequest createRequest = (CreateRequest) record;
            if (deserialize)
                ByteBufferInputStream.byteBuffer2Record(request.request, createRequest);
            String path = createRequest.getPath();
            int lastSlash = path.lastIndexOf('/');
            if (lastSlash == -1 || path.indexOf('\0') != -1 || failCreate) {
                LOG.info("Invalid path " + path + " with session 0x" + Long.toHexString(request.sessionId));
                throw new KeeperException.BadArgumentsException(path);
            }
            List<ACL> listACL = removeDuplicates(createRequest.getAcl());
            if (!fixupACL(request.authInfo, listACL)) {
                throw new KeeperException.InvalidACLException(path);
            }
            String parentPath = path.substring(0, lastSlash);
            ChangeRecord parentRecord = getRecordForPath(parentPath);
            checkACL(zks, parentRecord.acl, ZooDefs.Perms.CREATE, request.authInfo);
            int parentCVersion = parentRecord.stat.getCversion();
            CreateMode createMode = CreateMode.fromFlag(createRequest.getFlags());
            if (createMode.isSequential()) {
                path = path + String.format(Locale.ENGLISH, "%010d", parentCVersion);
            }
            validatePath(path, request.sessionId);
            try {
                if (getRecordForPath(path) != null) {
                    throw new KeeperException.NodeExistsException(path);
                }
            } catch (KeeperException.NoNodeException e) {
            // ignore this one
            }
            boolean ephemeralParent = parentRecord.stat.getEphemeralOwner() != 0;
            if (ephemeralParent) {
                throw new KeeperException.NoChildrenForEphemeralsException(path);
            }
            int newCversion = parentRecord.stat.getCversion() + 1;
            request.txn = new CreateTxn(path, createRequest.getData(), listACL, createMode.isEphemeral(), newCversion);
            StatPersisted s = new StatPersisted();
            if (createMode.isEphemeral()) {
                s.setEphemeralOwner(request.sessionId);
            }
            parentRecord = parentRecord.duplicate(request.hdr.getZxid());
            parentRecord.childCount++;
            parentRecord.stat.setCversion(newCversion);
            addChangeRecord(parentRecord);
            addChangeRecord(new ChangeRecord(request.hdr.getZxid(), path, s, 0, listACL));
            break;
        case OpCode.delete:
            zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            DeleteRequest deleteRequest = (DeleteRequest) record;
            if (deserialize)
                ByteBufferInputStream.byteBuffer2Record(request.request, deleteRequest);
            path = deleteRequest.getPath();
            lastSlash = path.lastIndexOf('/');
            if (lastSlash == -1 || path.indexOf('\0') != -1 || zks.getZKDatabase().isSpecialPath(path)) {
                throw new KeeperException.BadArgumentsException(path);
            }
            parentPath = path.substring(0, lastSlash);
            parentRecord = getRecordForPath(parentPath);
            ChangeRecord nodeRecord = getRecordForPath(path);
            checkACL(zks, parentRecord.acl, ZooDefs.Perms.DELETE, request.authInfo);
            int version = deleteRequest.getVersion();
            if (version != -1 && nodeRecord.stat.getVersion() != version) {
                throw new KeeperException.BadVersionException(path);
            }
            if (nodeRecord.childCount > 0) {
                throw new KeeperException.NotEmptyException(path);
            }
            request.txn = new DeleteTxn(path);
            parentRecord = parentRecord.duplicate(request.hdr.getZxid());
            parentRecord.childCount--;
            addChangeRecord(parentRecord);
            addChangeRecord(new ChangeRecord(request.hdr.getZxid(), path, null, -1, null));
            break;
        case OpCode.setData:
            zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            SetDataRequest setDataRequest = (SetDataRequest) record;
            if (deserialize)
                ByteBufferInputStream.byteBuffer2Record(request.request, setDataRequest);
            path = setDataRequest.getPath();
            validatePath(path, request.sessionId);
            nodeRecord = getRecordForPath(path);
            checkACL(zks, nodeRecord.acl, ZooDefs.Perms.WRITE, request.authInfo);
            version = setDataRequest.getVersion();
            int currentVersion = nodeRecord.stat.getVersion();
            if (version != -1 && version != currentVersion) {
                throw new KeeperException.BadVersionException(path);
            }
            version = currentVersion + 1;
            request.txn = new SetDataTxn(path, setDataRequest.getData(), version);
            nodeRecord = nodeRecord.duplicate(request.hdr.getZxid());
            nodeRecord.stat.setVersion(version);
            addChangeRecord(nodeRecord);
            break;
        case OpCode.setACL:
            zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            SetACLRequest setAclRequest = (SetACLRequest) record;
            if (deserialize)
                ByteBufferInputStream.byteBuffer2Record(request.request, setAclRequest);
            path = setAclRequest.getPath();
            validatePath(path, request.sessionId);
            listACL = removeDuplicates(setAclRequest.getAcl());
            if (!fixupACL(request.authInfo, listACL)) {
                throw new KeeperException.InvalidACLException(path);
            }
            nodeRecord = getRecordForPath(path);
            checkACL(zks, nodeRecord.acl, ZooDefs.Perms.ADMIN, request.authInfo);
            version = setAclRequest.getVersion();
            currentVersion = nodeRecord.stat.getAversion();
            if (version != -1 && version != currentVersion) {
                throw new KeeperException.BadVersionException(path);
            }
            version = currentVersion + 1;
            request.txn = new SetACLTxn(path, listACL, version);
            nodeRecord = nodeRecord.duplicate(request.hdr.getZxid());
            nodeRecord.stat.setAversion(version);
            addChangeRecord(nodeRecord);
            break;
        case OpCode.createSession:
            request.request.rewind();
            int to = request.request.getInt();
            request.txn = new CreateSessionTxn(to);
            request.request.rewind();
            zks.sessionTracker.addSession(request.sessionId, to);
            zks.setOwner(request.sessionId, request.getOwner());
            break;
        case OpCode.closeSession:
            // We don't want to do this check since the session expiration thread
            // queues up this operation without being the session owner.
            // this request is the last of the session so it should be ok
            // zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            HashSet<String> es = zks.getZKDatabase().getEphemerals(request.sessionId);
            synchronized (zks.outstandingChanges) {
                for (ChangeRecord c : zks.outstandingChanges) {
                    if (c.stat == null) {
                        // Doing a delete
                        es.remove(c.path);
                    } else if (c.stat.getEphemeralOwner() == request.sessionId) {
                        es.add(c.path);
                    }
                }
                for (String path2Delete : es) {
                    addChangeRecord(new ChangeRecord(request.hdr.getZxid(), path2Delete, null, 0, null));
                }
                zks.sessionTracker.setSessionClosing(request.sessionId);
            }
            LOG.info("Processed session termination for sessionid: 0x" + Long.toHexString(request.sessionId));
            break;
        case OpCode.check:
            zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            CheckVersionRequest checkVersionRequest = (CheckVersionRequest) record;
            if (deserialize)
                ByteBufferInputStream.byteBuffer2Record(request.request, checkVersionRequest);
            path = checkVersionRequest.getPath();
            validatePath(path, request.sessionId);
            nodeRecord = getRecordForPath(path);
            checkACL(zks, nodeRecord.acl, ZooDefs.Perms.READ, request.authInfo);
            version = checkVersionRequest.getVersion();
            currentVersion = nodeRecord.stat.getVersion();
            if (version != -1 && version != currentVersion) {
                throw new KeeperException.BadVersionException(path);
            }
            version = currentVersion + 1;
            request.txn = new CheckVersionTxn(path, version);
            break;
    }
}
Also used : CheckVersionRequest(org.apache.zookeeper.proto.CheckVersionRequest) CreateRequest(org.apache.zookeeper.proto.CreateRequest) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) CreateSessionTxn(org.apache.zookeeper.txn.CreateSessionTxn) BadArgumentsException(org.apache.zookeeper.KeeperException.BadArgumentsException) SetACLRequest(org.apache.zookeeper.proto.SetACLRequest) CheckVersionTxn(org.apache.zookeeper.txn.CheckVersionTxn) ACL(org.apache.zookeeper.data.ACL) SetDataRequest(org.apache.zookeeper.proto.SetDataRequest) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) CreateMode(org.apache.zookeeper.CreateMode) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn) StatPersisted(org.apache.zookeeper.data.StatPersisted) ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord) DeleteRequest(org.apache.zookeeper.proto.DeleteRequest) KeeperException(org.apache.zookeeper.KeeperException) TxnHeader(org.apache.zookeeper.txn.TxnHeader)

Example 13 with ChangeRecord

use of org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord in project fabric8 by jboss-fuse.

the class PrepRequestProcessor method rollbackPendingChanges.

/**
 * Rollback pending changes records from a failed multi-op.
 *
 * If a multi-op fails, we can't leave any invalid change records we created
 * around. We also need to restore their prior value (if any) if their prior
 * value is still valid.
 *
 * @param zxid
 * @param pendingChangeRecords
 */
void rollbackPendingChanges(long zxid, HashMap<String, ChangeRecord> pendingChangeRecords) {
    synchronized (zks.outstandingChanges) {
        // Grab a list iterator starting at the END of the list so we can iterate in reverse
        ListIterator<ChangeRecord> iter = zks.outstandingChanges.listIterator(zks.outstandingChanges.size());
        while (iter.hasPrevious()) {
            ChangeRecord c = iter.previous();
            if (c.zxid == zxid) {
                iter.remove();
                // Remove all outstanding changes for paths of this multi.
                // Previous records will be added back later.
                zks.outstandingChangesForPath.remove(c.path);
            } else {
                break;
            }
        }
        // we don't need to roll back any records because there is nothing left.
        if (zks.outstandingChanges.isEmpty()) {
            return;
        }
        long firstZxid = zks.outstandingChanges.get(0).zxid;
        for (ChangeRecord c : pendingChangeRecords.values()) {
            // once they are completed.
            if (c.zxid < firstZxid) {
                continue;
            }
            // add previously existing records back.
            zks.outstandingChangesForPath.put(c.path, c);
        }
    }
}
Also used : ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord)

Example 14 with ChangeRecord

use of org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord in project zookeeper by apache.

the class PrepRequestProcessor method pRequest2TxnCreate.

private void pRequest2TxnCreate(int type, Request request, Record record, boolean deserialize) throws IOException, KeeperException {
    if (deserialize) {
        ByteBufferInputStream.byteBuffer2Record(request.request, record);
    }
    int flags;
    String path;
    List<ACL> acl;
    byte[] data;
    long ttl;
    if (type == OpCode.createTTL) {
        CreateTTLRequest createTtlRequest = (CreateTTLRequest) record;
        flags = createTtlRequest.getFlags();
        path = createTtlRequest.getPath();
        acl = createTtlRequest.getAcl();
        data = createTtlRequest.getData();
        ttl = createTtlRequest.getTtl();
    } else {
        CreateRequest createRequest = (CreateRequest) record;
        flags = createRequest.getFlags();
        path = createRequest.getPath();
        acl = createRequest.getAcl();
        data = createRequest.getData();
        ttl = -1;
    }
    CreateMode createMode = CreateMode.fromFlag(flags);
    validateCreateRequest(path, createMode, request, ttl);
    String parentPath = validatePathForCreate(path, request.sessionId);
    List<ACL> listACL = fixupACL(path, request.authInfo, acl);
    ChangeRecord parentRecord = getRecordForPath(parentPath);
    zks.checkACL(request.cnxn, parentRecord.acl, ZooDefs.Perms.CREATE, request.authInfo, path, listACL);
    int parentCVersion = parentRecord.stat.getCversion();
    if (createMode.isSequential()) {
        path = path + String.format(Locale.ENGLISH, "%010d", parentCVersion);
    }
    validatePath(path, request.sessionId);
    try {
        if (getRecordForPath(path) != null) {
            throw new KeeperException.NodeExistsException(path);
        }
    } catch (KeeperException.NoNodeException e) {
    // ignore this one
    }
    boolean ephemeralParent = EphemeralType.get(parentRecord.stat.getEphemeralOwner()) == EphemeralType.NORMAL;
    if (ephemeralParent) {
        throw new KeeperException.NoChildrenForEphemeralsException(path);
    }
    int newCversion = parentRecord.stat.getCversion() + 1;
    zks.checkQuota(path, null, data, OpCode.create);
    if (type == OpCode.createContainer) {
        request.setTxn(new CreateContainerTxn(path, data, listACL, newCversion));
    } else if (type == OpCode.createTTL) {
        request.setTxn(new CreateTTLTxn(path, data, listACL, newCversion, ttl));
    } else {
        request.setTxn(new CreateTxn(path, data, listACL, createMode.isEphemeral(), newCversion));
    }
    TxnHeader hdr = request.getHdr();
    long ephemeralOwner = 0;
    if (createMode.isContainer()) {
        ephemeralOwner = EphemeralType.CONTAINER_EPHEMERAL_OWNER;
    } else if (createMode.isTTL()) {
        ephemeralOwner = EphemeralType.TTL.toEphemeralOwner(ttl);
    } else if (createMode.isEphemeral()) {
        ephemeralOwner = request.sessionId;
    }
    StatPersisted s = DataTree.createStat(hdr.getZxid(), hdr.getTime(), ephemeralOwner);
    parentRecord = parentRecord.duplicate(request.getHdr().getZxid());
    parentRecord.childCount++;
    parentRecord.stat.setCversion(newCversion);
    parentRecord.stat.setPzxid(request.getHdr().getZxid());
    parentRecord.precalculatedDigest = precalculateDigest(DigestOpCode.UPDATE, parentPath, parentRecord.data, parentRecord.stat);
    addChangeRecord(parentRecord);
    ChangeRecord nodeRecord = new ChangeRecord(request.getHdr().getZxid(), path, s, 0, listACL);
    nodeRecord.data = data;
    nodeRecord.precalculatedDigest = precalculateDigest(DigestOpCode.ADD, path, nodeRecord.data, s);
    setTxnDigest(request, nodeRecord.precalculatedDigest);
    addChangeRecord(nodeRecord);
}
Also used : CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) CreateRequest(org.apache.zookeeper.proto.CreateRequest) ACL(org.apache.zookeeper.data.ACL) CreateTTLRequest(org.apache.zookeeper.proto.CreateTTLRequest) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) CreateMode(org.apache.zookeeper.CreateMode) StatPersisted(org.apache.zookeeper.data.StatPersisted) ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord) KeeperException(org.apache.zookeeper.KeeperException) TxnHeader(org.apache.zookeeper.txn.TxnHeader)

Aggregations

ChangeRecord (org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord)14 KeeperException (org.apache.zookeeper.KeeperException)6 Op (org.apache.zookeeper.Op)6 TxnHeader (org.apache.zookeeper.txn.TxnHeader)6 BadArgumentsException (org.apache.zookeeper.KeeperException.BadArgumentsException)5 CheckVersionRequest (org.apache.zookeeper.proto.CheckVersionRequest)5 CreateRequest (org.apache.zookeeper.proto.CreateRequest)5 DeleteRequest (org.apache.zookeeper.proto.DeleteRequest)5 SetACLRequest (org.apache.zookeeper.proto.SetACLRequest)5 SetDataRequest (org.apache.zookeeper.proto.SetDataRequest)5 CheckVersionTxn (org.apache.zookeeper.txn.CheckVersionTxn)5 CreateSessionTxn (org.apache.zookeeper.txn.CreateSessionTxn)5 CreateTxn (org.apache.zookeeper.txn.CreateTxn)5 DeleteTxn (org.apache.zookeeper.txn.DeleteTxn)5 SetACLTxn (org.apache.zookeeper.txn.SetACLTxn)5 SetDataTxn (org.apache.zookeeper.txn.SetDataTxn)5 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3