/** * Convert Iterable of {@link ZKOp} we got into the ZooKeeper.Op instances to actually pass to * multi (need to do this in order to appendMetaData). */ private Iterable<Op> prepareZKMulti(Iterable<Op> ops) throws UnsupportedOperationException { if (ops == null) return null; List<Op> preparedOps = new LinkedList<Op>(); for (Op op : ops) { if (op.getType() == ZooDefs.OpCode.create) { CreateRequest create = (CreateRequest) op.toRequestRecord(); preparedOps.add( Op.create( create.getPath(), appendMetaData(create.getData()), create.getAcl(), create.getFlags())); } else if (op.getType() == ZooDefs.OpCode.delete) { // no need to appendMetaData for delete preparedOps.add(op); } else if (op.getType() == ZooDefs.OpCode.setData) { SetDataRequest setData = (SetDataRequest) op.toRequestRecord(); preparedOps.add( Op.setData(setData.getPath(), appendMetaData(setData.getData()), setData.getVersion())); } else { throw new UnsupportedOperationException("Unexpected ZKOp type: " + op.getClass().getName()); } } return preparedOps; }
@Test(timeout = 60000) public void testAllocation() throws Exception { String allocationPath = "/allocation1"; SimpleLedgerAllocator allocator = createAllocator(allocationPath); allocator.allocate(); ZKTransaction txn = newTxn(); LedgerHandle lh = FutureUtils.result(allocator.tryObtain(txn, NULL_LISTENER)); logger.info("Try obtaining ledger handle {}", lh.getId()); byte[] data = zkc.get().getData(allocationPath, false, null); assertEquals((Long) lh.getId(), Long.valueOf(new String(data, UTF_8))); txn.addOp(DefaultZKOp.of(Op.setData("/unexistedpath", "data".getBytes(UTF_8), -1))); try { FutureUtils.result(txn.execute()); fail("Should fail the transaction when setting unexisted path"); } catch (ZKException ke) { // expected logger.info("Should fail on executing transaction when setting unexisted path", ke); } data = zkc.get().getData(allocationPath, false, null); assertEquals((Long) lh.getId(), Long.valueOf(new String(data, UTF_8))); // Create new transaction to obtain the ledger again. txn = newTxn(); // we could obtain the ledger if it was obtained LedgerHandle newLh = FutureUtils.result(allocator.tryObtain(txn, NULL_LISTENER)); assertEquals(lh.getId(), newLh.getId()); FutureUtils.result(txn.execute()); data = zkc.get().getData(allocationPath, false, null); assertEquals(0, data.length); Utils.close(allocator); }
@Test(timeout = 60000) public void testCloseAllocatorAfterAbort() throws Exception { String allocationPath = "/allocation3"; SimpleLedgerAllocator allocator = createAllocator(allocationPath); allocator.allocate(); ZKTransaction txn = newTxn(); // close during obtaining ledger. LedgerHandle lh = FutureUtils.result(allocator.tryObtain(txn, NULL_LISTENER)); txn.addOp(DefaultZKOp.of(Op.setData("/unexistedpath", "data".getBytes(UTF_8), -1))); try { FutureUtils.result(txn.execute()); fail("Should fail the transaction when setting unexisted path"); } catch (ZKException ke) { // expected } Utils.close(allocator); byte[] data = zkc.get().getData(allocationPath, false, null); assertEquals((Long) lh.getId(), Long.valueOf(new String(data, UTF_8))); // the ledger is not deleted. bkc.get() .openLedger( lh.getId(), BookKeeper.DigestType.CRC32, dlConf.getBKDigestPW().getBytes(UTF_8)); }