Search in sources :

Example 1 with Txn

use of org.apache.zookeeper.txn.Txn in project fabric8 by jboss-fuse.

the class PrepRequestProcessor method pRequest.

/**
 * This method will be called inside the ProcessRequestThread, which is a
 * singleton, so there will be a single thread calling this code.
 *
 * @param request
 */
@SuppressWarnings("unchecked")
protected void pRequest(Request request) throws RequestProcessorException {
    // LOG.info("Prep>>> cxid = " + request.cxid + " type = " +
    // request.type + " id = 0x" + Long.toHexString(request.sessionId));
    request.hdr = null;
    request.txn = null;
    try {
        switch(request.type) {
            case OpCode.create:
                CreateRequest createRequest = new CreateRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, createRequest, true);
                break;
            case OpCode.delete:
                DeleteRequest deleteRequest = new DeleteRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, deleteRequest, true);
                break;
            case OpCode.setData:
                SetDataRequest setDataRequest = new SetDataRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, setDataRequest, true);
                break;
            case OpCode.setACL:
                SetACLRequest setAclRequest = new SetACLRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, setAclRequest, true);
                break;
            case OpCode.check:
                CheckVersionRequest checkRequest = new CheckVersionRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, checkRequest, true);
                break;
            case OpCode.multi:
                MultiTransactionRecord multiRequest = new MultiTransactionRecord();
                try {
                    ByteBufferInputStream.byteBuffer2Record(request.request, multiRequest);
                } catch (IOException e) {
                    request.hdr = new TxnHeader(request.sessionId, request.cxid, zks.getNextZxid(), zks.getTime(), OpCode.multi);
                    throw e;
                }
                List<Txn> txns = new ArrayList<Txn>();
                // Each op in a multi-op must have the same zxid!
                long zxid = zks.getNextZxid();
                KeeperException ke = null;
                // Store off current pending change records in case we need to rollback
                HashMap<String, ChangeRecord> pendingChanges = getPendingChanges(multiRequest);
                int index = 0;
                for (Op op : multiRequest) {
                    Record subrequest = op.toRequestRecord();
                    /* If we've already failed one of the ops, don't bother
                     * trying the rest as we know it's going to fail and it
                     * would be confusing in the logfiles.
                     */
                    if (ke != null) {
                        request.hdr.setType(OpCode.error);
                        request.txn = new ErrorTxn(Code.RUNTIMEINCONSISTENCY.intValue());
                    } else /* Prep the request and convert to a Txn */
                    {
                        try {
                            pRequest2Txn(op.getType(), zxid, request, subrequest, false);
                        } catch (KeeperException e) {
                            if (ke == null) {
                                ke = e;
                            }
                            request.hdr.setType(OpCode.error);
                            request.txn = new ErrorTxn(e.code().intValue());
                            if (!(request.type == OpCode.exists)) {
                                // INFO log only if we're not asking for existence of a node
                                // as this is absolutely normal to ask if a node exists and it doesn't exist
                                LOG.info("Got user-level KeeperException when processing " + request.toString() + " aborting remaining multi ops." + " Error Path:" + e.getPath() + " Error:" + e.getMessage());
                            }
                            request.setException(e);
                            /* Rollback change records from failed multi-op */
                            rollbackPendingChanges(zxid, pendingChanges);
                        }
                    }
                    // FIXME: I don't want to have to serialize it here and then
                    // immediately deserialize in next processor. But I'm
                    // not sure how else to get the txn stored into our list.
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
                    request.txn.serialize(boa, "request");
                    ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
                    txns.add(new Txn(request.hdr.getType(), bb.array()));
                    index++;
                }
                request.hdr = new TxnHeader(request.sessionId, request.cxid, zxid, zks.getTime(), request.type);
                request.txn = new MultiTxn(txns);
                break;
            // create/close session don't require request record
            case OpCode.createSession:
            case OpCode.closeSession:
                pRequest2Txn(request.type, zks.getNextZxid(), request, null, true);
                break;
            // All the rest don't need to create a Txn - just verify session
            case OpCode.sync:
            case OpCode.exists:
            case OpCode.getData:
            case OpCode.getACL:
            case OpCode.getChildren:
            case OpCode.getChildren2:
            case OpCode.ping:
            case OpCode.setWatches:
                zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
                break;
        }
    } catch (KeeperException e) {
        if (request.hdr != null) {
            request.hdr.setType(OpCode.error);
            request.txn = new ErrorTxn(e.code().intValue());
        }
        LOG.info("Got user-level KeeperException when processing " + request.toString() + " Error Path:" + e.getPath() + " Error:" + e.getMessage());
        request.setException(e);
    } catch (Exception e) {
        // log at error level as we are returning a marshalling
        // error to the user
        LOG.error("Failed to process " + request, e);
        StringBuilder sb = new StringBuilder();
        ByteBuffer bb = request.request;
        if (bb != null) {
            bb.rewind();
            while (bb.hasRemaining()) {
                sb.append(Integer.toHexString(bb.get() & 0xff));
            }
        } else {
            sb.append("request buffer is null");
        }
        LOG.error("Dumping request buffer: 0x" + sb.toString());
        if (request.hdr != null) {
            request.hdr.setType(OpCode.error);
            request.txn = new ErrorTxn(Code.MARSHALLINGERROR.intValue());
        }
    }
    request.zxid = zks.getZxid();
    nextProcessor.processRequest(request);
}
Also used : Op(org.apache.zookeeper.Op) BinaryOutputArchive(org.apache.jute.BinaryOutputArchive) CheckVersionRequest(org.apache.zookeeper.proto.CheckVersionRequest) MultiTxn(org.apache.zookeeper.txn.MultiTxn) CreateRequest(org.apache.zookeeper.proto.CreateRequest) ArrayList(java.util.ArrayList) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CheckVersionTxn(org.apache.zookeeper.txn.CheckVersionTxn) CreateSessionTxn(org.apache.zookeeper.txn.CreateSessionTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) Txn(org.apache.zookeeper.txn.Txn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) MultiTransactionRecord(org.apache.zookeeper.MultiTransactionRecord) Record(org.apache.jute.Record) ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord) SetACLRequest(org.apache.zookeeper.proto.SetACLRequest) SetDataRequest(org.apache.zookeeper.proto.SetDataRequest) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ByteBuffer(java.nio.ByteBuffer) XidRolloverException(org.apache.zookeeper.server.quorum.Leader.XidRolloverException) BadArgumentsException(org.apache.zookeeper.KeeperException.BadArgumentsException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) MultiTransactionRecord(org.apache.zookeeper.MultiTransactionRecord) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) DeleteRequest(org.apache.zookeeper.proto.DeleteRequest) ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord) KeeperException(org.apache.zookeeper.KeeperException) TxnHeader(org.apache.zookeeper.txn.TxnHeader)

Example 2 with Txn

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

the class TxnLogToolkit method getFormattedTxnStr.

/**
 * get the formatted string from the txn.
 * @param txn transaction log data
 * @return the formatted string
 */
private static String getFormattedTxnStr(Record txn) throws IOException {
    StringBuilder txnData = new StringBuilder();
    if (txn == null) {
        return txnData.toString();
    }
    if (txn instanceof CreateTxn) {
        CreateTxn createTxn = ((CreateTxn) txn);
        txnData.append(createTxn.getPath() + "," + checkNullToEmpty(createTxn.getData())).append("," + createTxn.getAcl() + "," + createTxn.getEphemeral()).append("," + createTxn.getParentCVersion());
    } else if (txn instanceof SetDataTxn) {
        SetDataTxn setDataTxn = ((SetDataTxn) txn);
        txnData.append(setDataTxn.getPath() + "," + checkNullToEmpty(setDataTxn.getData())).append("," + setDataTxn.getVersion());
    } else if (txn instanceof CreateContainerTxn) {
        CreateContainerTxn createContainerTxn = ((CreateContainerTxn) txn);
        txnData.append(createContainerTxn.getPath() + "," + checkNullToEmpty(createContainerTxn.getData())).append("," + createContainerTxn.getAcl() + "," + createContainerTxn.getParentCVersion());
    } else if (txn instanceof CreateTTLTxn) {
        CreateTTLTxn createTTLTxn = ((CreateTTLTxn) txn);
        txnData.append(createTTLTxn.getPath() + "," + checkNullToEmpty(createTTLTxn.getData())).append("," + createTTLTxn.getAcl() + "," + createTTLTxn.getParentCVersion()).append("," + createTTLTxn.getTtl());
    } else if (txn instanceof MultiTxn) {
        MultiTxn multiTxn = ((MultiTxn) txn);
        List<Txn> txnList = multiTxn.getTxns();
        for (int i = 0; i < txnList.size(); i++) {
            Txn t = txnList.get(i);
            if (i == 0) {
                txnData.append(Request.op2String(t.getType()) + ":" + checkNullToEmpty(t.getData()));
            } else {
                txnData.append(";" + Request.op2String(t.getType()) + ":" + checkNullToEmpty(t.getData()));
            }
        }
    } else {
        txnData.append(txn.toString());
    }
    return txnData.toString();
}
Also used : CreateTxn(org.apache.zookeeper.txn.CreateTxn) CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) Txn(org.apache.zookeeper.txn.Txn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn)

Example 3 with Txn

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

the class PrepRequestProcessor method pRequestHelper.

/**
 * This method is a helper to pRequest method
 *
 * @param request
 */
private void pRequestHelper(Request request) throws RequestProcessorException {
    try {
        switch(request.type) {
            case OpCode.createContainer:
            case OpCode.create:
            case OpCode.create2:
                CreateRequest create2Request = new CreateRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, create2Request, true);
                break;
            case OpCode.createTTL:
                CreateTTLRequest createTtlRequest = new CreateTTLRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, createTtlRequest, true);
                break;
            case OpCode.deleteContainer:
            case OpCode.delete:
                DeleteRequest deleteRequest = new DeleteRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, deleteRequest, true);
                break;
            case OpCode.setData:
                SetDataRequest setDataRequest = new SetDataRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, setDataRequest, true);
                break;
            case OpCode.reconfig:
                ReconfigRequest reconfigRequest = new ReconfigRequest();
                ByteBufferInputStream.byteBuffer2Record(request.request, reconfigRequest);
                pRequest2Txn(request.type, zks.getNextZxid(), request, reconfigRequest, true);
                break;
            case OpCode.setACL:
                SetACLRequest setAclRequest = new SetACLRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, setAclRequest, true);
                break;
            case OpCode.check:
                CheckVersionRequest checkRequest = new CheckVersionRequest();
                pRequest2Txn(request.type, zks.getNextZxid(), request, checkRequest, true);
                break;
            case OpCode.multi:
                MultiOperationRecord multiRequest = new MultiOperationRecord();
                try {
                    ByteBufferInputStream.byteBuffer2Record(request.request, multiRequest);
                } catch (IOException e) {
                    request.setHdr(new TxnHeader(request.sessionId, request.cxid, zks.getNextZxid(), Time.currentWallTime(), OpCode.multi));
                    throw e;
                }
                List<Txn> txns = new ArrayList<Txn>();
                // Each op in a multi-op must have the same zxid!
                long zxid = zks.getNextZxid();
                KeeperException ke = null;
                // Store off current pending change records in case we need to rollback
                Map<String, ChangeRecord> pendingChanges = getPendingChanges(multiRequest);
                request.setHdr(new TxnHeader(request.sessionId, request.cxid, zxid, Time.currentWallTime(), request.type));
                for (Op op : multiRequest) {
                    Record subrequest = op.toRequestRecord();
                    int type;
                    Record txn;
                    /* If we've already failed one of the ops, don't bother
                     * trying the rest as we know it's going to fail and it
                     * would be confusing in the logfiles.
                     */
                    if (ke != null) {
                        type = OpCode.error;
                        txn = new ErrorTxn(Code.RUNTIMEINCONSISTENCY.intValue());
                    } else {
                        /* Prep the request and convert to a Txn */
                        try {
                            pRequest2Txn(op.getType(), zxid, request, subrequest, false);
                            type = op.getType();
                            txn = request.getTxn();
                        } catch (KeeperException e) {
                            ke = e;
                            type = OpCode.error;
                            txn = new ErrorTxn(e.code().intValue());
                            if (e.code().intValue() > Code.APIERROR.intValue()) {
                                LOG.info("Got user-level KeeperException when processing {} aborting" + " remaining multi ops. Error Path:{} Error:{}", request.toString(), e.getPath(), e.getMessage());
                            }
                            request.setException(e);
                            /* Rollback change records from failed multi-op */
                            rollbackPendingChanges(zxid, pendingChanges);
                        }
                    }
                    // not sure how else to get the txn stored into our list.
                    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
                        txn.serialize(boa, "request");
                        ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
                        txns.add(new Txn(type, bb.array()));
                    }
                }
                request.setTxn(new MultiTxn(txns));
                if (digestEnabled) {
                    setTxnDigest(request);
                }
                break;
            // create/close session don't require request record
            case OpCode.createSession:
            case OpCode.closeSession:
                if (!request.isLocalSession()) {
                    pRequest2Txn(request.type, zks.getNextZxid(), request, null, true);
                }
                break;
            // All the rest don't need to create a Txn - just verify session
            case OpCode.sync:
            case OpCode.exists:
            case OpCode.getData:
            case OpCode.getACL:
            case OpCode.getChildren:
            case OpCode.getAllChildrenNumber:
            case OpCode.getChildren2:
            case OpCode.ping:
            case OpCode.setWatches:
            case OpCode.setWatches2:
            case OpCode.checkWatches:
            case OpCode.removeWatches:
            case OpCode.getEphemerals:
            case OpCode.multiRead:
            case OpCode.addWatch:
            case OpCode.whoAmI:
                zks.sessionTracker.checkSession(request.sessionId, request.getOwner());
                break;
            default:
                LOG.warn("unknown type {}", request.type);
                break;
        }
    } catch (KeeperException e) {
        if (request.getHdr() != null) {
            request.getHdr().setType(OpCode.error);
            request.setTxn(new ErrorTxn(e.code().intValue()));
        }
        if (e.code().intValue() > Code.APIERROR.intValue()) {
            LOG.info("Got user-level KeeperException when processing {} Error Path:{} Error:{}", request.toString(), e.getPath(), e.getMessage());
        }
        request.setException(e);
    } catch (Exception e) {
        // log at error level as we are returning a marshalling
        // error to the user
        LOG.error("Failed to process {}", request, e);
        StringBuilder sb = new StringBuilder();
        ByteBuffer bb = request.request;
        if (bb != null) {
            bb.rewind();
            while (bb.hasRemaining()) {
                sb.append(String.format("%02x", (0xff & bb.get())));
            }
        } else {
            sb.append("request buffer is null");
        }
        LOG.error("Dumping request buffer for request type {}: 0x{}", Request.op2String(request.type), sb);
        if (request.getHdr() != null) {
            request.getHdr().setType(OpCode.error);
            request.setTxn(new ErrorTxn(Code.MARSHALLINGERROR.intValue()));
        }
    }
}
Also used : Op(org.apache.zookeeper.Op) BinaryOutputArchive(org.apache.jute.BinaryOutputArchive) CheckVersionRequest(org.apache.zookeeper.proto.CheckVersionRequest) MultiTxn(org.apache.zookeeper.txn.MultiTxn) CreateRequest(org.apache.zookeeper.proto.CreateRequest) ArrayList(java.util.ArrayList) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CreateSessionTxn(org.apache.zookeeper.txn.CreateSessionTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn) CheckVersionTxn(org.apache.zookeeper.txn.CheckVersionTxn) Txn(org.apache.zookeeper.txn.Txn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) CloseSessionTxn(org.apache.zookeeper.txn.CloseSessionTxn) ReconfigRequest(org.apache.zookeeper.proto.ReconfigRequest) CreateTTLRequest(org.apache.zookeeper.proto.CreateTTLRequest) MultiOperationRecord(org.apache.zookeeper.MultiOperationRecord) Record(org.apache.jute.Record) ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord) MultiOperationRecord(org.apache.zookeeper.MultiOperationRecord) SetACLRequest(org.apache.zookeeper.proto.SetACLRequest) SetDataRequest(org.apache.zookeeper.proto.SetDataRequest) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ByteBuffer(java.nio.ByteBuffer) BadArgumentsException(org.apache.zookeeper.KeeperException.BadArgumentsException) ConfigException(org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) DeleteRequest(org.apache.zookeeper.proto.DeleteRequest) ChangeRecord(org.apache.zookeeper.server.ZooKeeperServer.ChangeRecord) KeeperException(org.apache.zookeeper.KeeperException) TxnHeader(org.apache.zookeeper.txn.TxnHeader)

Example 4 with Txn

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

the class DataTree method processTxn.

public ProcessTxnResult processTxn(TxnHeader header, Record txn, boolean isSubTxn) {
    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.TTL.toEphemeralOwner(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:
                long sessionId = header.getClientId();
                if (txn != null) {
                    killSession(sessionId, header.getZxid(), ephemerals.remove(sessionId), ((CloseSessionTxn) txn).getPaths2Delete());
                } else {
                    killSession(sessionId, 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);
                    }
                    assert !failed || (subtxn.getType() == OpCode.error);
                    TxnHeader subHdr = new TxnHeader(header.getClientId(), header.getCxid(), header.getZxid(), header.getTime(), subtxn.getType());
                    ProcessTxnResult subRc = processTxn(subHdr, record, true);
                    rc.multiResult.add(subRc);
                    if (subRc.err != 0 && rc.err == 0) {
                        rc.err = subRc.err;
                    }
                }
                break;
        }
    } catch (KeeperException e) {
        LOG.debug("Failed: {}:{}", header, txn, e);
        rc.err = e.code().intValue();
    } catch (IOException e) {
        LOG.debug("Failed: {}:{}", header, txn, e);
    }
    /*
         * Snapshots are taken lazily. When serializing a node, it's data
         * and children copied in a synchronization block on that node,
         * which means newly created node won't be in the snapshot, so
         * we won't have mismatched cversion and pzxid when replaying the
         * createNode txn.
         *
         * But there is a tricky scenario that if the child is deleted due
         * to session close and re-created in a different global session
         * after that the parent is serialized, then when replay the txn
         * because the node is belonging to a different session, replay the
         * closeSession txn won't delete it anymore, and we'll get NODEEXISTS
         * error when replay the createNode txn. In this case, we need to
         * update the cversion and pzxid to the new value.
         *
         * 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: {} path: {} err: {}", header.getType(), rc.path, 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: {} : error: {}", header.getType(), rc.err);
    }
    /*
         * Things we can only update after the whole txn is applied to data
         * tree.
         *
         * If we update the lastProcessedZxid with the first sub txn in multi
         * and there is a snapshot in progress, it's possible that the zxid
         * associated with the snapshot only include partial of the multi op.
         *
         * When loading snapshot, it will only load the txns after the zxid
         * associated with snapshot file, which could cause data inconsistency
         * due to missing sub txns.
         *
         * To avoid this, we only update the lastProcessedZxid when the whole
         * multi-op txn is applied to DataTree.
         */
    if (!isSubTxn) {
        /*
             * 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;
        }
        if (digestFromLoadedSnapshot != null) {
            compareSnapshotDigests(rc.zxid);
        } else {
            // only start recording digest when we're not in fuzzy state
            logZxidDigest(rc.zxid, getTreeDigest());
        }
    }
    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) SetDataTxn(org.apache.zookeeper.txn.SetDataTxn) CreateTxn(org.apache.zookeeper.txn.CreateTxn) CreateTTLTxn(org.apache.zookeeper.txn.CreateTTLTxn) DeleteTxn(org.apache.zookeeper.txn.DeleteTxn) CreateContainerTxn(org.apache.zookeeper.txn.CreateContainerTxn) SetACLTxn(org.apache.zookeeper.txn.SetACLTxn) CheckVersionTxn(org.apache.zookeeper.txn.CheckVersionTxn) Txn(org.apache.zookeeper.txn.Txn) MultiTxn(org.apache.zookeeper.txn.MultiTxn) ErrorTxn(org.apache.zookeeper.txn.ErrorTxn) CloseSessionTxn(org.apache.zookeeper.txn.CloseSessionTxn) 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)

Example 5 with Txn

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

the class LoadFromLogNoServerTest 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: {} for {}", childStr, parentName);
    LOG.info("(cverions, pzxid): {}, {}", prevCversion, prevPzxid);
    Record txn = null;
    TxnHeader txnHeader = null;
    if (type == ZooDefs.OpCode.delete) {
        txn = new DeleteTxn(path);
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), ZooDefs.OpCode.delete);
    } else if (type == ZooDefs.OpCode.create) {
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), ZooDefs.OpCode.create);
        txn = new CreateTxn(path, new byte[0], null, false, cversion);
    } else if (type == ZooDefs.OpCode.multi) {
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), ZooDefs.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(ZooDefs.OpCode.create, bb.array());
        txnList.add(txact);
        txn = new MultiTxn(txnList);
        txnHeader = new TxnHeader(0xabcd, 0x123, prevPzxid + 1, Time.currentElapsedTime(), ZooDefs.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: {} for {}", childStr, parentName);
    LOG.info("(cverions, pzxid): {}, {}", newCversion, newPzxid);
    assertTrue((newCversion == prevCversion + 1 && newPzxid == prevPzxid + 1), type + " <cversion, pzxid> verification failed. Expected: <" + (prevCversion + 1) + ", " + (prevPzxid + 1) + ">, found: <" + newCversion + ", " + newPzxid + ">");
}
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)

Aggregations

CreateTxn (org.apache.zookeeper.txn.CreateTxn)8 MultiTxn (org.apache.zookeeper.txn.MultiTxn)8 Txn (org.apache.zookeeper.txn.Txn)8 ByteBuffer (java.nio.ByteBuffer)7 Record (org.apache.jute.Record)7 DeleteTxn (org.apache.zookeeper.txn.DeleteTxn)7 TxnHeader (org.apache.zookeeper.txn.TxnHeader)7 SetDataTxn (org.apache.zookeeper.txn.SetDataTxn)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)5 IOException (java.io.IOException)5 ArrayList (java.util.ArrayList)5 BinaryOutputArchive (org.apache.jute.BinaryOutputArchive)5 KeeperException (org.apache.zookeeper.KeeperException)5 CheckVersionTxn (org.apache.zookeeper.txn.CheckVersionTxn)5 CreateContainerTxn (org.apache.zookeeper.txn.CreateContainerTxn)5 CreateTTLTxn (org.apache.zookeeper.txn.CreateTTLTxn)5 ErrorTxn (org.apache.zookeeper.txn.ErrorTxn)5 SetACLTxn (org.apache.zookeeper.txn.SetACLTxn)5 BadArgumentsException (org.apache.zookeeper.KeeperException.BadArgumentsException)3 Op (org.apache.zookeeper.Op)3