@Override public void asyncCreateLedger(int ensSize, int writeQuorumSize, int ackQuorumSize, final DigestType digestType, final byte[] passwd, final CreateCallback cb, final Object ctx, Map<String, byte[]> properties) { getProgrammedFailure().thenComposeAsync((res) -> { try { long id = sequence.getAndIncrement(); log.info("Creating ledger {}", id); PulsarMockLedgerHandle lh = new PulsarMockLedgerHandle(PulsarMockBookKeeper.this, id, digestType, passwd); ledgers.put(id, lh); return FutureUtils.value(lh); } catch (Throwable t) { return FutureUtils.exception(t); } }, executor).whenCompleteAsync((lh, exception) -> { if (exception != null) { cb.createComplete(getExceptionCode(exception), null, ctx); } else { cb.createComplete(BKException.Code.OK, lh, ctx); } }, executor); }
/** * There are 3 digest types that can be used for verification. The CRC32 is * cheap to compute but does not protect against byzantine bookies (i.e., a * bookie might report fake bytes and a matching CRC32). The MAC code is more * expensive to compute, but is protected by a password, i.e., a bookie can't * report fake bytes with a mathching MAC unless it knows the password. * The CRC32C, which use SSE processor instruction, has better performance than CRC32. * Legacy DigestType for backward compatibility. If we want to add new DigestType, * we should add it in here, client.api.DigestType and DigestType in DataFormats.proto. * If the digest type is set/passed in as DUMMY, a dummy digest is added/checked. * This DUMMY digest is mostly for test purposes or in situations/use-cases * where digest is considered a overhead. */ public enum DigestType { MAC, CRC32, CRC32C, DUMMY; public static DigestType fromApiDigestType(org.apache.bookkeeper.client.api.DigestType digestType) { switch (digestType) { case MAC: return DigestType.MAC; case CRC32: return DigestType.CRC32; case CRC32C: return DigestType.CRC32C; case DUMMY: return DigestType.DUMMY; default: throw new IllegalArgumentException("Unable to convert digest type " + digestType); } }
try { if (closed) { cb.createComplete(BKException.Code.ClientClosedException, null, ctx); return;
try { if (closed) { cb.createComplete(BKException.Code.ClientClosedException, null, ctx); return;
/** * Create ledger async and schedule a timeout task to check ledger-creation is complete else it fails the callback * with TimeoutException. * * @param bookKeeper * @param config * @param digestType * @param cb * @param emptyMap */ protected void asyncCreateLedger(BookKeeper bookKeeper, ManagedLedgerConfig config, DigestType digestType, CreateCallback cb, Map<Object, Object> emptyMap) { AtomicBoolean ledgerCreated = new AtomicBoolean(false); bookKeeper.asyncCreateLedger(config.getEnsembleSize(), config.getWriteQuorumSize(), config.getAckQuorumSize(), digestType, config.getPassword(), cb, ledgerCreated, Collections.emptyMap()); scheduledExecutor.schedule(() -> { if (!ledgerCreated.get()) { ledgerCreated.set(true); cb.createComplete(BKException.Code.TimeoutException, null, null); } }, config.getMetadataOperationsTimeoutSeconds(), TimeUnit.SECONDS); }
private void create(CreateCallback cb) { if (!validate()) { cb.createComplete(BKException.Code.IncorrectParameterException, null, null); return; } LedgerCreateOp op = new LedgerCreateOp(bk, builderEnsembleSize, builderWriteQuorumSize, builderAckQuorumSize, DigestType.fromApiDigestType(builderDigestType), builderPassword, cb, null, builderCustomMetadata, builderWriteFlags, bk.getClientCtx().getClientStats()); ReentrantReadWriteLock closeLock = bk.getCloseLock(); closeLock.readLock().lock(); try { if (bk.isClosed()) { cb.createComplete(BKException.Code.ClientClosedException, null, null); return; } op.initiate(); } finally { closeLock.readLock().unlock(); } } }
private void create(CreateCallback cb) { if (!validate()) { cb.createComplete(BKException.Code.IncorrectParameterException, null, null); return; } LedgerCreateOp op = new LedgerCreateOp(parent.bk, parent.builderEnsembleSize, parent.builderWriteQuorumSize, parent.builderAckQuorumSize, DigestType.fromApiDigestType(parent.builderDigestType), parent.builderPassword, cb, null, parent.builderCustomMetadata, parent.builderWriteFlags, parent.bk.getClientCtx().getClientStats()); ReentrantReadWriteLock closeLock = parent.bk.getCloseLock(); closeLock.readLock().lock(); try { if (parent.bk.isClosed()) { cb.createComplete(BKException.Code.ClientClosedException, null, null); return; } op.initiateAdv(builderLedgerId == null ? -1L : builderLedgerId); } finally { closeLock.readLock().unlock(); } } }
private void createComplete(int rc, LedgerHandle lh) { // Opened a new ledger if (BKException.Code.OK != rc) { createOpLogger.registerFailedEvent(MathUtils.elapsedNanos(startTime), TimeUnit.NANOSECONDS); } else { createOpLogger.registerSuccessfulEvent(MathUtils.elapsedNanos(startTime), TimeUnit.NANOSECONDS); } cb.createComplete(rc, lh, ctx); }
/** * Create ledger async and schedule a timeout task to check ledger-creation is complete else it fails the callback * with TimeoutException. * * @param bookKeeper * @param config * @param digestType * @param cb * @param emptyMap */ protected void asyncCreateLedger(BookKeeper bookKeeper, ManagedLedgerConfig config, DigestType digestType, CreateCallback cb, Map<Object, Object> emptyMap) { AtomicBoolean ledgerCreated = new AtomicBoolean(false); bookKeeper.asyncCreateLedger(config.getEnsembleSize(), config.getWriteQuorumSize(), config.getAckQuorumSize(), digestType, config.getPassword(), cb, ledgerCreated, Collections.emptyMap()); scheduledExecutor.schedule(() -> { if (!ledgerCreated.get()) { ledgerCreated.set(true); cb.createComplete(BKException.Code.TimeoutException, null, null); } }, config.getMetadataOperationsTimeoutSeconds(), TimeUnit.SECONDS); }