Search in sources :

Example 6 with CreateTxn

use of org.apache.zookeeper.txn.CreateTxn 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 = 0;
    }
    CreateMode createMode = CreateMode.fromFlag(flags);
    validateCreateRequest(createMode, request);
    String parentPath = validatePathForCreate(path, request.sessionId);
    List<ACL> listACL = fixupACL(path, request.authInfo, acl);
    ChangeRecord parentRecord = getRecordForPath(parentPath);
    checkACL(zks, 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;
    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));
    }
    StatPersisted s = new StatPersisted();
    if (createMode.isEphemeral()) {
        s.setEphemeralOwner(request.sessionId);
    }
    parentRecord = parentRecord.duplicate(request.getHdr().getZxid());
    parentRecord.childCount++;
    parentRecord.stat.setCversion(newCversion);
    addChangeRecord(parentRecord);
    addChangeRecord(new ChangeRecord(request.getHdr().getZxid(), path, s, 0, listACL));
}
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)

Example 7 with CreateTxn

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

the class Zab1_0Test method testPopulatedLeaderConversation.

public void testPopulatedLeaderConversation(PopulatedLeaderConversation conversation, int ops) throws Exception {
    Socket[] pair = getSocketPair();
    Socket leaderSocket = pair[0];
    Socket followerSocket = pair[1];
    File tmpDir = File.createTempFile("test", "dir", testData);
    tmpDir.delete();
    tmpDir.mkdir();
    LeadThread leadThread = null;
    Leader leader = null;
    try {
        // Setup a database with two znodes
        FileTxnSnapLog snapLog = new FileTxnSnapLog(tmpDir, tmpDir);
        ZKDatabase zkDb = new ZKDatabase(snapLog);
        Assert.assertTrue(ops >= 1);
        long zxid = ZxidUtils.makeZxid(1, 0);
        for (int i = 1; i <= ops; i++) {
            zxid = ZxidUtils.makeZxid(1, i);
            String path = "/foo-" + i;
            zkDb.processTxn(new TxnHeader(13, 1000 + i, zxid, 30 + i, ZooDefs.OpCode.create), new CreateTxn(path, "fpjwasalsohere".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, false, 1));
            Stat stat = new Stat();
            Assert.assertEquals("fpjwasalsohere", new String(zkDb.getData(path, stat, null)));
        }
        Assert.assertTrue(zxid > ZxidUtils.makeZxid(1, 0));
        // Generate snapshot and close files.
        snapLog.save(zkDb.getDataTree(), zkDb.getSessionWithTimeOuts());
        snapLog.close();
        QuorumPeer peer = createQuorumPeer(tmpDir);
        leader = createLeader(tmpDir, peer);
        peer.leader = leader;
        // Set the last accepted epoch and current epochs to be 1
        peer.setAcceptedEpoch(1);
        peer.setCurrentEpoch(1);
        leadThread = new LeadThread(leader);
        leadThread.start();
        while (leader.cnxAcceptor == null || !leader.cnxAcceptor.isAlive()) {
            Thread.sleep(20);
        }
        LearnerHandler lh = new LearnerHandler(leaderSocket, leader);
        lh.start();
        leaderSocket.setSoTimeout(4000);
        InputArchive ia = BinaryInputArchive.getArchive(followerSocket.getInputStream());
        OutputArchive oa = BinaryOutputArchive.getArchive(followerSocket.getOutputStream());
        conversation.converseWithLeader(ia, oa, leader, zxid);
    } finally {
        if (leader != null) {
            leader.shutdown("end of test");
        }
        if (leadThread != null) {
            leadThread.interrupt();
            leadThread.join();
        }
        TestUtils.deleteFileRecursively(tmpDir);
    }
}
Also used : InputArchive(org.apache.jute.InputArchive) BinaryInputArchive(org.apache.jute.BinaryInputArchive) ZKDatabase(org.apache.zookeeper.server.ZKDatabase) FileTxnSnapLog(org.apache.zookeeper.server.persistence.FileTxnSnapLog) CreateTxn(org.apache.zookeeper.txn.CreateTxn) Stat(org.apache.zookeeper.data.Stat) BinaryOutputArchive(org.apache.jute.BinaryOutputArchive) OutputArchive(org.apache.jute.OutputArchive) File(java.io.File) ServerSocket(java.net.ServerSocket) Socket(java.net.Socket) TxnHeader(org.apache.zookeeper.txn.TxnHeader)

Example 8 with CreateTxn

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

CreateTxn (org.apache.zookeeper.txn.CreateTxn)8 TxnHeader (org.apache.zookeeper.txn.TxnHeader)5 Record (org.apache.jute.Record)4 DeleteTxn (org.apache.zookeeper.txn.DeleteTxn)4 File (java.io.File)3 BinaryInputArchive (org.apache.jute.BinaryInputArchive)3 BinaryOutputArchive (org.apache.jute.BinaryOutputArchive)3 CreateContainerTxn (org.apache.zookeeper.txn.CreateContainerTxn)3 CreateTTLTxn (org.apache.zookeeper.txn.CreateTTLTxn)3 MultiTxn (org.apache.zookeeper.txn.MultiTxn)3 SetDataTxn (org.apache.zookeeper.txn.SetDataTxn)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 EOFException (java.io.EOFException)2 IOException (java.io.IOException)2 Socket (java.net.Socket)2 ByteBuffer (java.nio.ByteBuffer)2 InputArchive (org.apache.jute.InputArchive)2 KeeperException (org.apache.zookeeper.KeeperException)2 ACL (org.apache.zookeeper.data.ACL)2