Search in sources :

Example 1 with CreateSessionTxn

use of org.apache.zookeeper.txn.CreateSessionTxn 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 CreateSessionTxn

use of org.apache.zookeeper.txn.CreateSessionTxn 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 3 with CreateSessionTxn

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

the class FileTxnSnapLog method processTransaction.

/**
     * process the transaction on the datatree
     * @param hdr the hdr of the transaction
     * @param dt the datatree to apply transaction to
     * @param sessions the sessions to be restored
     * @param txn the transaction to be applied
     */
public void processTransaction(TxnHeader hdr, DataTree dt, Map<Long, Integer> sessions, Record txn) throws KeeperException.NoNodeException {
    ProcessTxnResult rc;
    switch(hdr.getType()) {
        case OpCode.createSession:
            sessions.put(hdr.getClientId(), ((CreateSessionTxn) txn).getTimeOut());
            if (LOG.isTraceEnabled()) {
                ZooTrace.logTraceMessage(LOG, ZooTrace.SESSION_TRACE_MASK, "playLog --- create session in log: 0x" + Long.toHexString(hdr.getClientId()) + " with timeout: " + ((CreateSessionTxn) txn).getTimeOut());
            }
            // give dataTree a chance to sync its lastProcessedZxid
            rc = dt.processTxn(hdr, txn);
            break;
        case OpCode.closeSession:
            sessions.remove(hdr.getClientId());
            if (LOG.isTraceEnabled()) {
                ZooTrace.logTraceMessage(LOG, ZooTrace.SESSION_TRACE_MASK, "playLog --- close session in log: 0x" + Long.toHexString(hdr.getClientId()));
            }
            rc = dt.processTxn(hdr, txn);
            break;
        default:
            rc = dt.processTxn(hdr, txn);
    }
    /**
         * Snapshots are lazily created. So when a snapshot is in progress,
         * there is a chance for later transactions to make into the
         * snapshot. Then when the snapshot is restored, NONODE/NODEEXISTS
         * errors could occur. It should be safe to ignore these.
         */
    if (rc.err != Code.OK.intValue()) {
        LOG.debug("Ignoring processTxn failure hdr: {}, error: {}, path: {}", hdr.getType(), rc.err, rc.path);
    }
}
Also used : CreateSessionTxn(org.apache.zookeeper.txn.CreateSessionTxn) ProcessTxnResult(org.apache.zookeeper.server.DataTree.ProcessTxnResult)

Example 4 with CreateSessionTxn

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

the class ZooKeeperServer method processTxn.

private ProcessTxnResult processTxn(Request request, TxnHeader hdr, Record txn) {
    ProcessTxnResult rc;
    int opCode = request != null ? request.type : hdr.getType();
    long sessionId = request != null ? request.sessionId : hdr.getClientId();
    if (hdr != null) {
        rc = getZKDatabase().processTxn(hdr, txn);
    } else {
        rc = new ProcessTxnResult();
    }
    if (opCode == OpCode.createSession) {
        if (hdr != null && txn instanceof CreateSessionTxn) {
            CreateSessionTxn cst = (CreateSessionTxn) txn;
            sessionTracker.addGlobalSession(sessionId, cst.getTimeOut());
        } else if (request != null && request.isLocalSession()) {
            request.request.rewind();
            int timeout = request.request.getInt();
            request.request.rewind();
            sessionTracker.addSession(request.sessionId, timeout);
        } else {
            LOG.warn("*****>>>>> Got " + txn.getClass() + " " + txn.toString());
        }
    } else if (opCode == OpCode.closeSession) {
        sessionTracker.removeSession(sessionId);
    }
    return rc;
}
Also used : CreateSessionTxn(org.apache.zookeeper.txn.CreateSessionTxn) ProcessTxnResult(org.apache.zookeeper.server.DataTree.ProcessTxnResult)

Aggregations

CreateSessionTxn (org.apache.zookeeper.txn.CreateSessionTxn)4 IOException (java.io.IOException)2 ProcessTxnResult (org.apache.zookeeper.server.DataTree.ProcessTxnResult)2 DeleteTxn (org.apache.zookeeper.txn.DeleteTxn)2 SetACLTxn (org.apache.zookeeper.txn.SetACLTxn)2 SetDataTxn (org.apache.zookeeper.txn.SetDataTxn)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 EOFException (java.io.EOFException)1 StringReader (java.io.StringReader)1 HashMap (java.util.HashMap)1 Properties (java.util.Properties)1 BinaryInputArchive (org.apache.jute.BinaryInputArchive)1 InputArchive (org.apache.jute.InputArchive)1 Record (org.apache.jute.Record)1 KeeperException (org.apache.zookeeper.KeeperException)1 BadArgumentsException (org.apache.zookeeper.KeeperException.BadArgumentsException)1 ACL (org.apache.zookeeper.data.ACL)1 CheckVersionRequest (org.apache.zookeeper.proto.CheckVersionRequest)1 DeleteRequest (org.apache.zookeeper.proto.DeleteRequest)1 ReconfigRequest (org.apache.zookeeper.proto.ReconfigRequest)1