Search in sources :

Example 1 with DeleteTxn

use of org.apache.zookeeper.txn.DeleteTxn in project zookeeper by apache.

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
     */
protected void pRequest2Txn(int type, long zxid, Request request, Record record, boolean deserialize) throws KeeperException, IOException, RequestProcessorException {
    request.setHdr(new TxnHeader(request.sessionId, request.cxid, zxid, Time.currentWallTime(), type));
    switch(type) {
        case OpCode.create:
        case OpCode.create2:
        case OpCode.createTTL:
        case OpCode.createContainer:
            {
                pRequest2TxnCreate(type, request, record, deserialize);
                break;
            }
        case OpCode.deleteContainer:
            {
                String path = new String(request.request.array());
                String parentPath = getParentPathAndValidate(path);
                ChangeRecord parentRecord = getRecordForPath(parentPath);
                ChangeRecord nodeRecord = getRecordForPath(path);
                if (nodeRecord.childCount > 0) {
                    throw new KeeperException.NotEmptyException(path);
                }
                if (EphemeralType.get(nodeRecord.stat.getEphemeralOwner()) == EphemeralType.NORMAL) {
                    throw new KeeperException.BadVersionException(path);
                }
                request.setTxn(new DeleteTxn(path));
                parentRecord = parentRecord.duplicate(request.getHdr().getZxid());
                parentRecord.childCount--;
                addChangeRecord(parentRecord);
                addChangeRecord(new ChangeRecord(request.getHdr().getZxid(), path, null, -1, null));
                break;
            }
        case OpCode.delete:
            zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            DeleteRequest deleteRequest = (DeleteRequest) record;
            if (deserialize)
                ByteBufferInputStream.byteBuffer2Record(request.request, deleteRequest);
            String path = deleteRequest.getPath();
            String parentPath = getParentPathAndValidate(path);
            ChangeRecord parentRecord = getRecordForPath(parentPath);
            ChangeRecord nodeRecord = getRecordForPath(path);
            checkACL(zks, request.cnxn, parentRecord.acl, ZooDefs.Perms.DELETE, request.authInfo, path, null);
            checkAndIncVersion(nodeRecord.stat.getVersion(), deleteRequest.getVersion(), path);
            if (nodeRecord.childCount > 0) {
                throw new KeeperException.NotEmptyException(path);
            }
            request.setTxn(new DeleteTxn(path));
            parentRecord = parentRecord.duplicate(request.getHdr().getZxid());
            parentRecord.childCount--;
            addChangeRecord(parentRecord);
            addChangeRecord(new ChangeRecord(request.getHdr().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, request.cnxn, nodeRecord.acl, ZooDefs.Perms.WRITE, request.authInfo, path, null);
            int newVersion = checkAndIncVersion(nodeRecord.stat.getVersion(), setDataRequest.getVersion(), path);
            request.setTxn(new SetDataTxn(path, setDataRequest.getData(), newVersion));
            nodeRecord = nodeRecord.duplicate(request.getHdr().getZxid());
            nodeRecord.stat.setVersion(newVersion);
            addChangeRecord(nodeRecord);
            break;
        case OpCode.reconfig:
            if (!QuorumPeerConfig.isReconfigEnabled()) {
                LOG.error("Reconfig operation requested but reconfig feature is disabled.");
                throw new KeeperException.ReconfigDisabledException();
            }
            if (skipACL) {
                LOG.warn("skipACL is set, reconfig operation will skip ACL checks!");
            }
            zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
            ReconfigRequest reconfigRequest = (ReconfigRequest) record;
            LeaderZooKeeperServer lzks;
            try {
                lzks = (LeaderZooKeeperServer) zks;
            } catch (ClassCastException e) {
                // standalone mode - reconfiguration currently not supported
                throw new KeeperException.UnimplementedException();
            }
            QuorumVerifier lastSeenQV = lzks.self.getLastSeenQuorumVerifier();
            // check that there's no reconfig in progress
            if (lastSeenQV.getVersion() != lzks.self.getQuorumVerifier().getVersion()) {
                throw new KeeperException.ReconfigInProgress();
            }
            long configId = reconfigRequest.getCurConfigId();
            if (configId != -1 && configId != lzks.self.getLastSeenQuorumVerifier().getVersion()) {
                String msg = "Reconfiguration from version " + configId + " failed -- last seen version is " + lzks.self.getLastSeenQuorumVerifier().getVersion();
                throw new KeeperException.BadVersionException(msg);
            }
            String newMembers = reconfigRequest.getNewMembers();
            if (newMembers != null) {
                //non-incremental membership change                  
                LOG.info("Non-incremental reconfig");
                // Input may be delimited by either commas or newlines so convert to common newline separated format
                newMembers = newMembers.replaceAll(",", "\n");
                try {
                    Properties props = new Properties();
                    props.load(new StringReader(newMembers));
                    request.qv = QuorumPeerConfig.parseDynamicConfig(props, lzks.self.getElectionType(), true, false);
                    request.qv.setVersion(request.getHdr().getZxid());
                } catch (IOException e) {
                    throw new KeeperException.BadArgumentsException(e.getMessage());
                } catch (ConfigException e) {
                    throw new KeeperException.BadArgumentsException(e.getMessage());
                }
            } else {
                //incremental change - must be a majority quorum system   
                LOG.info("Incremental reconfig");
                List<String> joiningServers = null;
                String joiningServersString = reconfigRequest.getJoiningServers();
                if (joiningServersString != null) {
                    joiningServers = StringUtils.split(joiningServersString, ",");
                }
                List<String> leavingServers = null;
                String leavingServersString = reconfigRequest.getLeavingServers();
                if (leavingServersString != null) {
                    leavingServers = StringUtils.split(leavingServersString, ",");
                }
                if (!(lastSeenQV instanceof QuorumMaj)) {
                    String msg = "Incremental reconfiguration requested but last configuration seen has a non-majority quorum system";
                    LOG.warn(msg);
                    throw new KeeperException.BadArgumentsException(msg);
                }
                Map<Long, QuorumServer> nextServers = new HashMap<Long, QuorumServer>(lastSeenQV.getAllMembers());
                try {
                    if (leavingServers != null) {
                        for (String leaving : leavingServers) {
                            long sid = Long.parseLong(leaving);
                            nextServers.remove(sid);
                        }
                    }
                    if (joiningServers != null) {
                        for (String joiner : joiningServers) {
                            // joiner should have the following format: server.x = server_spec;client_spec               
                            String[] parts = StringUtils.split(joiner, "=").toArray(new String[0]);
                            if (parts.length != 2) {
                                throw new KeeperException.BadArgumentsException("Wrong format of server string");
                            }
                            // extract server id x from first part of joiner: server.x
                            Long sid = Long.parseLong(parts[0].substring(parts[0].lastIndexOf('.') + 1));
                            QuorumServer qs = new QuorumServer(sid, parts[1]);
                            if (qs.clientAddr == null || qs.electionAddr == null || qs.addr == null) {
                                throw new KeeperException.BadArgumentsException("Wrong format of server string - each server should have 3 ports specified");
                            }
                            // check duplication of addresses and ports
                            for (QuorumServer nqs : nextServers.values()) {
                                if (qs.id == nqs.id) {
                                    continue;
                                }
                                qs.checkAddressDuplicate(nqs);
                            }
                            nextServers.remove(qs.id);
                            nextServers.put(Long.valueOf(qs.id), qs);
                        }
                    }
                } catch (ConfigException e) {
                    throw new KeeperException.BadArgumentsException("Reconfiguration failed");
                }
                request.qv = new QuorumMaj(nextServers);
                request.qv.setVersion(request.getHdr().getZxid());
            }
            if (QuorumPeerConfig.isStandaloneEnabled() && request.qv.getVotingMembers().size() < 2) {
                String msg = "Reconfig failed - new configuration must include at least 2 followers";
                LOG.warn(msg);
                throw new KeeperException.BadArgumentsException(msg);
            } else if (request.qv.getVotingMembers().size() < 1) {
                String msg = "Reconfig failed - new configuration must include at least 1 follower";
                LOG.warn(msg);
                throw new KeeperException.BadArgumentsException(msg);
            }
            if (!lzks.getLeader().isQuorumSynced(request.qv)) {
                String msg2 = "Reconfig failed - there must be a connected and synced quorum in new configuration";
                LOG.warn(msg2);
                throw new KeeperException.NewConfigNoQuorum();
            }
            nodeRecord = getRecordForPath(ZooDefs.CONFIG_NODE);
            checkACL(zks, request.cnxn, nodeRecord.acl, ZooDefs.Perms.WRITE, request.authInfo, null, null);
            request.setTxn(new SetDataTxn(ZooDefs.CONFIG_NODE, request.qv.toString().getBytes(), -1));
            nodeRecord = nodeRecord.duplicate(request.getHdr().getZxid());
            nodeRecord.stat.setVersion(-1);
            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);
            List<ACL> listACL = fixupACL(path, request.authInfo, setAclRequest.getAcl());
            nodeRecord = getRecordForPath(path);
            checkACL(zks, request.cnxn, nodeRecord.acl, ZooDefs.Perms.ADMIN, request.authInfo, path, listACL);
            newVersion = checkAndIncVersion(nodeRecord.stat.getAversion(), setAclRequest.getVersion(), path);
            request.setTxn(new SetACLTxn(path, listACL, newVersion));
            nodeRecord = nodeRecord.duplicate(request.getHdr().getZxid());
            nodeRecord.stat.setAversion(newVersion);
            addChangeRecord(nodeRecord);
            break;
        case OpCode.createSession:
            request.request.rewind();
            int to = request.request.getInt();
            request.setTxn(new CreateSessionTxn(to));
            request.request.rewind();
            if (request.isLocalSession()) {
                // This will add to local session tracker if it is enabled
                zks.sessionTracker.addSession(request.sessionId, to);
            } else {
                // Explicitly add to global session if the flag is not set
                zks.sessionTracker.addGlobalSession(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());
            Set<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.getHdr().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, request.cnxn, nodeRecord.acl, ZooDefs.Perms.READ, request.authInfo, path, null);
            request.setTxn(new CheckVersionTxn(path, checkAndIncVersion(nodeRecord.stat.getVersion(), checkVersionRequest.getVersion(), path)));
            break;
        default:
            LOG.warn("unknown type " + type);
            break;
    }
}
Also used : CheckVersionRequest(org.apache.zookeeper.proto.CheckVersionRequest) HashMap(java.util.HashMap) QuorumServer(org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer) QuorumMaj(org.apache.zookeeper.server.quorum.flexible.QuorumMaj) ConfigException(org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException) Properties(java.util.Properties) ReconfigRequest(org.apache.zookeeper.proto.ReconfigRequest) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) CreateSessionTxn(org.apache.zookeeper.txn.CreateSessionTxn) BadArgumentsException(org.apache.zookeeper.KeeperException.BadArgumentsException) StringReader(java.io.StringReader) 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) IOException(java.io.IOException) QuorumVerifier(org.apache.zookeeper.server.quorum.flexible.QuorumVerifier) BadArgumentsException(org.apache.zookeeper.KeeperException.BadArgumentsException) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn) ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord) DeleteRequest(org.apache.zookeeper.proto.DeleteRequest) KeeperException(org.apache.zookeeper.KeeperException) TxnHeader(org.apache.zookeeper.txn.TxnHeader) LeaderZooKeeperServer(org.apache.zookeeper.server.quorum.LeaderZooKeeperServer)

Example 2 with DeleteTxn

use of org.apache.zookeeper.txn.DeleteTxn in project exhibitor by soabase.

the class IndexBuilder method indexRecord.

private void indexRecord(TxnHeader header, Record record, AtomicInteger count, AtomicLong from, AtomicLong to) throws IOException {
    if (record instanceof CreateTxn) {
        CreateTxn createTxn = (CreateTxn) record;
        EntryTypes type = createTxn.getEphemeral() ? EntryTypes.CREATE_EPHEMERAL : EntryTypes.CREATE_PERSISTENT;
        Document document = makeDocument(header, type, count, from, to);
        addPath(document, createTxn.getPath());
        addData(document, createTxn.getData());
        writer.addDocument(document);
    } else if (record instanceof DeleteTxn) {
        DeleteTxn deleteTxn = (DeleteTxn) record;
        Document document = makeDocument(header, EntryTypes.DELETE, count, from, to);
        addPath(document, deleteTxn.getPath());
        writer.addDocument(document);
    } else if (record instanceof SetDataTxn) {
        SetDataTxn setDataTxn = (SetDataTxn) record;
        NumericField versionField = new NumericField(FieldNames.VERSION, Field.Store.YES, true);
        versionField.setIntValue(setDataTxn.getVersion());
        Document document = makeDocument(header, EntryTypes.SET_DATA, count, from, to);
        addPath(document, setDataTxn.getPath());
        addData(document, setDataTxn.getData());
        document.add(versionField);
        writer.addDocument(document);
    }
}
Also used : CreateTxn(org.apache.zookeeper.txn.CreateTxn) NumericField(org.apache.lucene.document.NumericField) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) Document(org.apache.lucene.document.Document) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn)

Example 3 with DeleteTxn

use of org.apache.zookeeper.txn.DeleteTxn in project zookeeper by apache.

the class SerializeUtils method deserializeTxn.

public static Record deserializeTxn(byte[] txnBytes, TxnHeader hdr) throws IOException {
    final ByteArrayInputStream bais = new ByteArrayInputStream(txnBytes);
    InputArchive ia = BinaryInputArchive.getArchive(bais);
    hdr.deserialize(ia, "hdr");
    bais.mark(bais.available());
    Record txn = null;
    switch(hdr.getType()) {
        case OpCode.createSession:
            // This isn't really an error txn; it just has the same
            // format. The error represents the timeout
            txn = new CreateSessionTxn();
            break;
        case OpCode.closeSession:
            return null;
        case OpCode.create:
        case OpCode.create2:
            txn = new CreateTxn();
            break;
        case OpCode.createTTL:
            txn = new CreateTTLTxn();
            break;
        case OpCode.createContainer:
            txn = new CreateContainerTxn();
            break;
        case OpCode.delete:
        case OpCode.deleteContainer:
            txn = new DeleteTxn();
            break;
        case OpCode.reconfig:
        case OpCode.setData:
            txn = new SetDataTxn();
            break;
        case OpCode.setACL:
            txn = new SetACLTxn();
            break;
        case OpCode.error:
            txn = new ErrorTxn();
            break;
        case OpCode.multi:
            txn = new MultiTxn();
            break;
        default:
            throw new IOException("Unsupported Txn with type=%d" + hdr.getType());
    }
    if (txn != null) {
        try {
            txn.deserialize(ia, "txn");
        } catch (EOFException e) {
            // perhaps this is a V0 Create
            if (hdr.getType() == OpCode.create) {
                CreateTxn create = (CreateTxn) txn;
                bais.reset();
                CreateTxnV0 createv0 = new CreateTxnV0();
                createv0.deserialize(ia, "txn");
                // cool now make it V1. a -1 parentCVersion will
                // trigger fixup processing in processTxn
                create.setPath(createv0.getPath());
                create.setData(createv0.getData());
                create.setAcl(createv0.getAcl());
                create.setEphemeral(createv0.getEphemeral());
                create.setParentCVersion(-1);
            } else {
                throw e;
            }
        }
    }
    return txn;
}
Also used : CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) InputArchive(org.apache.jute.InputArchive) BinaryInputArchive(org.apache.jute.BinaryInputArchive) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) IOException(java.io.IOException) CreateTxnV0(org.apache.zookeeper.txn.CreateTxnV0) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) CreateSessionTxn(org.apache.zookeeper.txn.CreateSessionTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) ByteArrayInputStream(java.io.ByteArrayInputStream) EOFException(java.io.EOFException) Record(org.apache.jute.Record) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn)

Example 4 with DeleteTxn

use of org.apache.zookeeper.txn.DeleteTxn in project zookeeper by apache.

the class LoadFromLogTest method doOp.

/*
     * Does create/delete depending on the type and verifies
     * if cversion before the operation is 1 less than cversion afer.
     */
private void doOp(FileTxnSnapLog logFile, int type, String path, DataTree dt, DataNode parent, int cversion) throws Exception {
    int lastSlash = path.lastIndexOf('/');
    String parentName = path.substring(0, lastSlash);
    int prevCversion = parent.stat.getCversion();
    long prevPzxid = parent.stat.getPzxid();
    List<String> child = dt.getChildren(parentName, null, null);
    StringBuilder childStr = new StringBuilder();
    for (String s : child) {
        childStr.append(s).append(" ");
    }
    LOG.info("Children: " + childStr + " for " + parentName);
    LOG.info("(cverions, pzxid): " + prevCversion + ", " + prevPzxid);
    Record txn = null;
    TxnHeader txnHeader = null;
    if (type == OpCode.delete) {
        txn = new DeleteTxn(path);
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), OpCode.delete);
    } else if (type == OpCode.create) {
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), OpCode.create);
        txn = new CreateTxn(path, new byte[0], null, false, cversion);
    } else if (type == OpCode.multi) {
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), OpCode.create);
        txn = new CreateTxn(path, new byte[0], null, false, cversion);
        List<Txn> txnList = new ArrayList<Txn>();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
        txn.serialize(boa, "request");
        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
        Txn txact = new Txn(OpCode.create, bb.array());
        txnList.add(txact);
        txn = new MultiTxn(txnList);
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), OpCode.multi);
    }
    logFile.processTransaction(txnHeader, dt, null, txn);
    int newCversion = parent.stat.getCversion();
    long newPzxid = parent.stat.getPzxid();
    child = dt.getChildren(parentName, null, null);
    childStr = new StringBuilder();
    for (String s : child) {
        childStr.append(s).append(" ");
    }
    LOG.info("Children: " + childStr + " for " + parentName);
    LOG.info("(cverions, pzxid): " + newCversion + ", " + newPzxid);
    Assert.assertTrue(type + " <cversion, pzxid> verification failed. Expected: <" + (prevCversion + 1) + ", " + (prevPzxid + 1) + ">, found: <" + newCversion + ", " + newPzxid + ">", (newCversion == prevCversion + 1 && newPzxid == prevPzxid + 1));
}
Also used : BinaryOutputArchive(org.apache.jute.BinaryOutputArchive) MultiTxn(org.apache.zookeeper.txn.MultiTxn) ArrayList(java.util.ArrayList) CreateTxn(org.apache.zookeeper.txn.CreateTxn) Txn(org.apache.zookeeper.txn.Txn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ByteBuffer(java.nio.ByteBuffer) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) Record(org.apache.jute.Record) TxnHeader(org.apache.zookeeper.txn.TxnHeader)

Example 5 with DeleteTxn

use of org.apache.zookeeper.txn.DeleteTxn in project zookeeper by apache.

the class DataTree method processTxn.

public ProcessTxnResult processTxn(TxnHeader header, Record txn) {
    ProcessTxnResult rc = new ProcessTxnResult();
    try {
        rc.clientId = header.getClientId();
        rc.cxid = header.getCxid();
        rc.zxid = header.getZxid();
        rc.type = header.getType();
        rc.err = 0;
        rc.multiResult = null;
        switch(header.getType()) {
            case OpCode.create:
                CreateTxn createTxn = (CreateTxn) txn;
                rc.path = createTxn.getPath();
                createNode(createTxn.getPath(), createTxn.getData(), createTxn.getAcl(), createTxn.getEphemeral() ? header.getClientId() : 0, createTxn.getParentCVersion(), header.getZxid(), header.getTime(), null);
                break;
            case OpCode.create2:
                CreateTxn create2Txn = (CreateTxn) txn;
                rc.path = create2Txn.getPath();
                Stat stat = new Stat();
                createNode(create2Txn.getPath(), create2Txn.getData(), create2Txn.getAcl(), create2Txn.getEphemeral() ? header.getClientId() : 0, create2Txn.getParentCVersion(), header.getZxid(), header.getTime(), stat);
                rc.stat = stat;
                break;
            case OpCode.createTTL:
                CreateTTLTxn createTtlTxn = (CreateTTLTxn) txn;
                rc.path = createTtlTxn.getPath();
                stat = new Stat();
                createNode(createTtlTxn.getPath(), createTtlTxn.getData(), createTtlTxn.getAcl(), EphemeralType.ttlToEphemeralOwner(createTtlTxn.getTtl()), createTtlTxn.getParentCVersion(), header.getZxid(), header.getTime(), stat);
                rc.stat = stat;
                break;
            case OpCode.createContainer:
                CreateContainerTxn createContainerTxn = (CreateContainerTxn) txn;
                rc.path = createContainerTxn.getPath();
                stat = new Stat();
                createNode(createContainerTxn.getPath(), createContainerTxn.getData(), createContainerTxn.getAcl(), EphemeralType.CONTAINER_EPHEMERAL_OWNER, createContainerTxn.getParentCVersion(), header.getZxid(), header.getTime(), stat);
                rc.stat = stat;
                break;
            case OpCode.delete:
            case OpCode.deleteContainer:
                DeleteTxn deleteTxn = (DeleteTxn) txn;
                rc.path = deleteTxn.getPath();
                deleteNode(deleteTxn.getPath(), header.getZxid());
                break;
            case OpCode.reconfig:
            case OpCode.setData:
                SetDataTxn setDataTxn = (SetDataTxn) txn;
                rc.path = setDataTxn.getPath();
                rc.stat = setData(setDataTxn.getPath(), setDataTxn.getData(), setDataTxn.getVersion(), header.getZxid(), header.getTime());
                break;
            case OpCode.setACL:
                SetACLTxn setACLTxn = (SetACLTxn) txn;
                rc.path = setACLTxn.getPath();
                rc.stat = setACL(setACLTxn.getPath(), setACLTxn.getAcl(), setACLTxn.getVersion());
                break;
            case OpCode.closeSession:
                killSession(header.getClientId(), header.getZxid());
                break;
            case OpCode.error:
                ErrorTxn errTxn = (ErrorTxn) txn;
                rc.err = errTxn.getErr();
                break;
            case OpCode.check:
                CheckVersionTxn checkTxn = (CheckVersionTxn) txn;
                rc.path = checkTxn.getPath();
                break;
            case OpCode.multi:
                MultiTxn multiTxn = (MultiTxn) txn;
                List<Txn> txns = multiTxn.getTxns();
                rc.multiResult = new ArrayList<ProcessTxnResult>();
                boolean failed = false;
                for (Txn subtxn : txns) {
                    if (subtxn.getType() == OpCode.error) {
                        failed = true;
                        break;
                    }
                }
                boolean post_failed = false;
                for (Txn subtxn : txns) {
                    ByteBuffer bb = ByteBuffer.wrap(subtxn.getData());
                    Record record = null;
                    switch(subtxn.getType()) {
                        case OpCode.create:
                            record = new CreateTxn();
                            break;
                        case OpCode.createTTL:
                            record = new CreateTTLTxn();
                            break;
                        case OpCode.createContainer:
                            record = new CreateContainerTxn();
                            break;
                        case OpCode.delete:
                        case OpCode.deleteContainer:
                            record = new DeleteTxn();
                            break;
                        case OpCode.setData:
                            record = new SetDataTxn();
                            break;
                        case OpCode.error:
                            record = new ErrorTxn();
                            post_failed = true;
                            break;
                        case OpCode.check:
                            record = new CheckVersionTxn();
                            break;
                        default:
                            throw new IOException("Invalid type of op: " + subtxn.getType());
                    }
                    assert (record != null);
                    ByteBufferInputStream.byteBuffer2Record(bb, record);
                    if (failed && subtxn.getType() != OpCode.error) {
                        int ec = post_failed ? Code.RUNTIMEINCONSISTENCY.intValue() : Code.OK.intValue();
                        subtxn.setType(OpCode.error);
                        record = new ErrorTxn(ec);
                    }
                    if (failed) {
                        assert (subtxn.getType() == OpCode.error);
                    }
                    TxnHeader subHdr = new TxnHeader(header.getClientId(), header.getCxid(), header.getZxid(), header.getTime(), subtxn.getType());
                    ProcessTxnResult subRc = processTxn(subHdr, record);
                    rc.multiResult.add(subRc);
                    if (subRc.err != 0 && rc.err == 0) {
                        rc.err = subRc.err;
                    }
                }
                break;
        }
    } catch (KeeperException e) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Failed: " + header + ":" + txn, e);
        }
        rc.err = e.code().intValue();
    } catch (IOException e) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Failed: " + header + ":" + txn, e);
        }
    }
    /*
         * A snapshot might be in progress while we are modifying the data
         * tree. If we set lastProcessedZxid prior to making corresponding
         * change to the tree, then the zxid associated with the snapshot
         * file will be ahead of its contents. Thus, while restoring from
         * the snapshot, the restore method will not apply the transaction
         * for zxid associated with the snapshot file, since the restore
         * method assumes that transaction to be present in the snapshot.
         *
         * To avoid this, we first apply the transaction and then modify
         * lastProcessedZxid.  During restore, we correctly handle the
         * case where the snapshot contains data ahead of the zxid associated
         * with the file.
         */
    if (rc.zxid > lastProcessedZxid) {
        lastProcessedZxid = rc.zxid;
    }
    /*
         * Snapshots are taken lazily. It can happen that the child
         * znodes of a parent are created after the parent
         * is serialized. Therefore, while replaying logs during restore, a
         * create might fail because the node was already
         * created.
         *
         * After seeing this failure, we should increment
         * the cversion of the parent znode since the parent was serialized
         * before its children.
         *
         * Note, such failures on DT should be seen only during
         * restore.
         */
    if (header.getType() == OpCode.create && rc.err == Code.NODEEXISTS.intValue()) {
        LOG.debug("Adjusting parent cversion for Txn: " + header.getType() + " path:" + rc.path + " err: " + rc.err);
        int lastSlash = rc.path.lastIndexOf('/');
        String parentName = rc.path.substring(0, lastSlash);
        CreateTxn cTxn = (CreateTxn) txn;
        try {
            setCversionPzxid(parentName, cTxn.getParentCVersion(), header.getZxid());
        } catch (KeeperException.NoNodeException e) {
            LOG.error("Failed to set parent cversion for: " + parentName, e);
            rc.err = e.code().intValue();
        }
    } else if (rc.err != Code.OK.intValue()) {
        LOG.debug("Ignoring processTxn failure hdr: " + header.getType() + " : error: " + rc.err);
    }
    return rc;
}
Also used : CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) CheckVersionTxn(org.apache.zookeeper.txn.CheckVersionTxn) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CheckVersionTxn(org.apache.zookeeper.txn.CheckVersionTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) Txn(org.apache.zookeeper.txn.Txn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) Stat(org.apache.zookeeper.data.Stat) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn) Record(org.apache.jute.Record) KeeperException(org.apache.zookeeper.KeeperException) TxnHeader(org.apache.zookeeper.txn.TxnHeader)

Aggregations

DeleteTxn (org.apache.zookeeper.txn.DeleteTxn)5 CreateTxn (org.apache.zookeeper.txn.CreateTxn)4 SetDataTxn (org.apache.zookeeper.txn.SetDataTxn)4 IOException (java.io.IOException)3 Record (org.apache.jute.Record)3 MultiTxn (org.apache.zookeeper.txn.MultiTxn)3 SetACLTxn (org.apache.zookeeper.txn.SetACLTxn)3 TxnHeader (org.apache.zookeeper.txn.TxnHeader)3 ByteBuffer (java.nio.ByteBuffer)2 KeeperException (org.apache.zookeeper.KeeperException)2 CheckVersionTxn (org.apache.zookeeper.txn.CheckVersionTxn)2 CreateContainerTxn (org.apache.zookeeper.txn.CreateContainerTxn)2 CreateSessionTxn (org.apache.zookeeper.txn.CreateSessionTxn)2 CreateTTLTxn (org.apache.zookeeper.txn.CreateTTLTxn)2 ErrorTxn (org.apache.zookeeper.txn.ErrorTxn)2 Txn (org.apache.zookeeper.txn.Txn)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 EOFException (java.io.EOFException)1 StringReader (java.io.StringReader)1