Search in sources :

Example 16 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class ProducerImpl method connectionOpened.

@Override
public void connectionOpened(final ClientCnx cnx) {
    // we set the cnx reference before registering the producer on the cnx, so if the cnx breaks before creating the
    // producer, it will try to grab a new cnx
    connectionHandler.setClientCnx(cnx);
    cnx.registerProducer(producerId, this);
    log.info("[{}] [{}] Creating producer on cnx {}", topic, producerName, cnx.ctx().channel());
    long requestId = client.newRequestId();
    cnx.sendRequestWithId(Commands.newProducer(topic, producerId, requestId, producerName, conf.isEncryptionEnabled(), metadata), requestId).thenAccept(pair -> {
        String producerName = pair.getLeft();
        long lastSequenceId = pair.getRight();
        // set the cnx pointer so that new messages will be sent immediately
        synchronized (ProducerImpl.this) {
            if (getState() == State.Closing || getState() == State.Closed) {
                // Producer was closed while reconnecting, close the connection to make sure the broker
                // drops the producer on its side
                cnx.removeProducer(producerId);
                cnx.channel().close();
                return;
            }
            resetBackoff();
            log.info("[{}] [{}] Created producer on cnx {}", topic, producerName, cnx.ctx().channel());
            connectionId = cnx.ctx().channel().toString();
            connectedSince = DateFormatter.now();
            if (this.producerName == null) {
                this.producerName = producerName;
            }
            if (this.lastSequenceIdPublished == -1 && conf.getInitialSequenceId() == null) {
                this.lastSequenceIdPublished = lastSequenceId;
                this.msgIdGenerator = lastSequenceId + 1;
            }
            if (!producerCreatedFuture.isDone() && isBatchMessagingEnabled()) {
                // schedule the first batch message task
                client.timer().newTimeout(batchMessageAndSendTask, conf.getBatchingMaxPublishDelayMicros(), TimeUnit.MICROSECONDS);
            }
            resendMessages(cnx);
        }
    }).exceptionally((e) -> {
        Throwable cause = e.getCause();
        cnx.removeProducer(producerId);
        if (getState() == State.Closing || getState() == State.Closed) {
            // Producer was closed while reconnecting, close the connection to make sure the broker
            // drops the producer on its side
            cnx.channel().close();
            return null;
        }
        log.error("[{}] [{}] Failed to create producer: {}", topic, producerName, cause.getMessage());
        if (cause instanceof PulsarClientException.ProducerBlockedQuotaExceededException) {
            synchronized (this) {
                log.warn("[{}] [{}] Topic backlog quota exceeded. Throwing Exception on producer.", topic, producerName);
                if (log.isDebugEnabled()) {
                    log.debug("[{}] [{}] Pending messages: {}", topic, producerName, pendingMessages.size());
                }
                PulsarClientException bqe = new PulsarClientException.ProducerBlockedQuotaExceededException("Could not send pending messages as backlog exceeded");
                failPendingMessages(cnx(), bqe);
            }
        } else if (cause instanceof PulsarClientException.ProducerBlockedQuotaExceededError) {
            log.warn("[{}] [{}] Producer is blocked on creation because backlog exceeded on topic.", producerName, topic);
        }
        if (cause instanceof PulsarClientException.TopicTerminatedException) {
            setState(State.Terminated);
            failPendingMessages(cnx(), (PulsarClientException) cause);
            producerCreatedFuture.completeExceptionally(cause);
            client.cleanupProducer(this);
        } else if (// 
        producerCreatedFuture.isDone() || (cause instanceof PulsarClientException && connectionHandler.isRetriableError((PulsarClientException) cause) && System.currentTimeMillis() < createProducerTimeout)) {
            // Either we had already created the producer once (producerCreatedFuture.isDone()) or we are
            // still within the initial timeout budget and we are dealing with a retriable error
            reconnectLater(cause);
        } else {
            setState(State.Failed);
            producerCreatedFuture.completeExceptionally(cause);
            client.cleanupProducer(this);
        }
        return null;
    });
}
Also used : PulsarApi(org.apache.pulsar.common.api.proto.PulsarApi) CompressionCodec(org.apache.pulsar.common.compression.CompressionCodec) Commands.hasChecksum(org.apache.pulsar.common.api.Commands.hasChecksum) ByteBufPair(org.apache.pulsar.common.api.ByteBufPair) ScheduledFuture(io.netty.util.concurrent.ScheduledFuture) Producer(org.apache.pulsar.client.api.Producer) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ProtocolVersion(org.apache.pulsar.common.api.proto.PulsarApi.ProtocolVersion) Message(org.apache.pulsar.client.api.Message) ChecksumType(org.apache.pulsar.common.api.Commands.ChecksumType) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) DateFormatter(org.apache.pulsar.common.util.DateFormatter) ByteBuf(io.netty.buffer.ByteBuf) Handle(io.netty.util.Recycler.Handle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) CompressionCodecProvider(org.apache.pulsar.common.compression.CompressionCodecProvider) TimerTask(io.netty.util.TimerTask) MessageMetadata(org.apache.pulsar.common.api.proto.PulsarApi.MessageMetadata) Crc32cIntChecksum.resumeChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum.resumeChecksum) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) Crc32cIntChecksum.computeChecksum(com.scurrilous.circe.checksum.Crc32cIntChecksum.computeChecksum) PulsarDecoder(org.apache.pulsar.common.api.PulsarDecoder) CryptoException(org.apache.pulsar.client.api.PulsarClientException.CryptoException) Commands(org.apache.pulsar.common.api.Commands) Timeout(io.netty.util.Timeout) Logger(org.slf4j.Logger) Semaphore(java.util.concurrent.Semaphore) CompressionType(org.apache.pulsar.client.api.CompressionType) ProducerCryptoFailureAction(org.apache.pulsar.client.api.ProducerCryptoFailureAction) IOException(java.io.IOException) BlockingQueue(java.util.concurrent.BlockingQueue) AtomicLongFieldUpdater(java.util.concurrent.atomic.AtomicLongFieldUpdater) String.format(java.lang.String.format) ProducerConfigurationData(org.apache.pulsar.client.impl.conf.ProducerConfigurationData) Schema(org.apache.pulsar.client.api.Schema) Recycler(io.netty.util.Recycler) Commands.readChecksum(org.apache.pulsar.common.api.Commands.readChecksum) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Queues(com.google.common.collect.Queues) MessageId(org.apache.pulsar.client.api.MessageId) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) Collections(java.util.Collections) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException)

Example 17 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class ProducerImpl method batchMessageAndSend.

// must acquire semaphore before enqueuing
private void batchMessageAndSend() {
    if (log.isDebugEnabled()) {
        log.debug("[{}] [{}] Batching the messages from the batch container with {} messages", topic, producerName, batchMessageContainer.numMessagesInBatch);
    }
    OpSendMsg op = null;
    int numMessagesInBatch = 0;
    try {
        if (!batchMessageContainer.isEmpty()) {
            numMessagesInBatch = batchMessageContainer.numMessagesInBatch;
            ByteBuf compressedPayload = batchMessageContainer.getCompressedBatchMetadataAndPayload();
            long sequenceId = batchMessageContainer.sequenceId;
            ByteBuf encryptedPayload = encryptMessage(batchMessageContainer.messageMetadata, compressedPayload);
            ByteBufPair cmd = sendMessage(producerId, sequenceId, batchMessageContainer.numMessagesInBatch, batchMessageContainer.setBatchAndBuild(), encryptedPayload);
            op = OpSendMsg.create(batchMessageContainer.messages, cmd, sequenceId, batchMessageContainer.firstCallback);
            op.setNumMessagesInBatch(batchMessageContainer.numMessagesInBatch);
            op.setBatchSizeByte(batchMessageContainer.currentBatchSizeBytes);
            batchMessageContainer.clear();
            pendingMessages.put(op);
            if (isConnected()) {
                // If we do have a connection, the message is sent immediately, otherwise we'll try again once a new
                // connection is established
                cmd.retain();
                cnx().ctx().channel().eventLoop().execute(WriteInEventLoopCallback.create(this, cnx(), op));
                stats.updateNumMsgsSent(numMessagesInBatch, op.batchSizeByte);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("[{}] [{}] Connection is not ready -- sequenceId {}", topic, producerName, sequenceId);
                }
            }
        }
    } catch (InterruptedException ie) {
        Thread.currentThread().interrupt();
        semaphore.release(numMessagesInBatch);
        if (op != null) {
            op.callback.sendComplete(new PulsarClientException(ie));
        }
    } catch (PulsarClientException e) {
        Thread.currentThread().interrupt();
        semaphore.release(numMessagesInBatch);
        if (op != null) {
            op.callback.sendComplete(e);
        }
    } catch (Throwable t) {
        semaphore.release(numMessagesInBatch);
        log.warn("[{}] [{}] error while closing out batch -- {}", topic, producerName, t);
        if (op != null) {
            op.callback.sendComplete(new PulsarClientException(t));
        }
    }
}
Also used : PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ByteBuf(io.netty.buffer.ByteBuf) ByteBufPair(org.apache.pulsar.common.api.ByteBufPair)

Example 18 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class MessageCrypto method encrypt.

/*
     * Encrypt the payload using the data key and update message metadata with the keyname & encrypted data key
     *
     * @param encKeys One or more public keys to encrypt data key
     *
     * @param msgMetadata Message Metadata
     *
     * @param payload Message which needs to be encrypted
     *
     * @return encryptedData if success
     */
public synchronized ByteBuf encrypt(Set<String> encKeys, CryptoKeyReader keyReader, MessageMetadata.Builder msgMetadata, ByteBuf payload) throws PulsarClientException {
    if (encKeys.isEmpty()) {
        return payload;
    }
    // Update message metadata with encrypted data key
    for (String keyName : encKeys) {
        if (encryptedDataKeyMap.get(keyName) == null) {
            // Attempt to load the key. This will allow us to load keys as soon as
            // a new key is added to producer config
            addPublicKeyCipher(keyName, keyReader);
        }
        EncryptionKeyInfo keyInfo = encryptedDataKeyMap.get(keyName);
        if (keyInfo != null) {
            if (keyInfo.getMetadata() != null && !keyInfo.getMetadata().isEmpty()) {
                List<KeyValue> kvList = new ArrayList<KeyValue>();
                keyInfo.getMetadata().forEach((key, value) -> {
                    kvList.add(KeyValue.newBuilder().setKey(key).setValue(value).build());
                });
                msgMetadata.addEncryptionKeys(EncryptionKeys.newBuilder().setKey(keyName).setValue(ByteString.copyFrom(keyInfo.getKey())).addAllMetadata(kvList).build());
            } else {
                msgMetadata.addEncryptionKeys(EncryptionKeys.newBuilder().setKey(keyName).setValue(ByteString.copyFrom(keyInfo.getKey())).build());
            }
        } else {
            // We should never reach here.
            log.error("{} Failed to find encrypted Data key for key {}.", logCtx, keyName);
        }
    }
    // Create gcm param
    // TODO: Replace random with counter and periodic refreshing based on timer/counter value
    secureRandom.nextBytes(iv);
    GCMParameterSpec gcmParam = new GCMParameterSpec(tagLen, iv);
    // Update message metadata with encryption param
    msgMetadata.setEncryptionParam(ByteString.copyFrom(iv));
    ByteBuf targetBuf = null;
    try {
        // Encrypt the data
        cipher.init(Cipher.ENCRYPT_MODE, dataKey, gcmParam);
        ByteBuffer sourceNioBuf = payload.nioBuffer(payload.readerIndex(), payload.readableBytes());
        int maxLength = cipher.getOutputSize(payload.readableBytes());
        targetBuf = PooledByteBufAllocator.DEFAULT.buffer(maxLength, maxLength);
        ByteBuffer targetNioBuf = targetBuf.nioBuffer(0, maxLength);
        int bytesStored = cipher.doFinal(sourceNioBuf, targetNioBuf);
        targetBuf.writerIndex(bytesStored);
    } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | ShortBufferException e) {
        targetBuf.release();
        log.error("{} Failed to encrypt message. {}", logCtx, e);
        throw new PulsarClientException.CryptoException(e.getMessage());
    }
    payload.release();
    return targetBuf;
}
Also used : KeyValue(org.apache.pulsar.common.api.proto.PulsarApi.KeyValue) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) ArrayList(java.util.ArrayList) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) ByteString(com.google.protobuf.ByteString) EncryptionKeyInfo(org.apache.pulsar.client.api.EncryptionKeyInfo) GCMParameterSpec(javax.crypto.spec.GCMParameterSpec) BadPaddingException(javax.crypto.BadPaddingException) ByteBuf(io.netty.buffer.ByteBuf) InvalidKeyException(java.security.InvalidKeyException) ByteBuffer(java.nio.ByteBuffer) CryptoException(org.apache.pulsar.client.api.PulsarClientException.CryptoException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) ShortBufferException(javax.crypto.ShortBufferException)

Example 19 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class TopicsConsumerImpl method doAcknowledge.

@Override
protected CompletableFuture<Void> doAcknowledge(MessageId messageId, AckType ackType, Map<String, Long> properties) {
    checkArgument(messageId instanceof TopicMessageIdImpl);
    TopicMessageIdImpl messageId1 = (TopicMessageIdImpl) messageId;
    if (getState() != State.Ready) {
        return FutureUtil.failedFuture(new PulsarClientException("Consumer already closed"));
    }
    if (ackType == AckType.Cumulative) {
        return FutureUtil.failedFuture(new PulsarClientException.NotSupportedException("Cumulative acknowledge not supported for topics consumer"));
    } else {
        ConsumerImpl<T> consumer = consumers.get(messageId1.getTopicName());
        MessageId innerId = messageId1.getInnerMessageId();
        return consumer.doAcknowledge(innerId, ackType, properties).thenRun(() -> unAckedMessageTracker.remove(messageId1));
    }
}
Also used : PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) MessageId(org.apache.pulsar.client.api.MessageId)

Example 20 with PulsarClientException

use of org.apache.pulsar.client.api.PulsarClientException in project incubator-pulsar by apache.

the class TopicsConsumerImpl method internalReceive.

@Override
protected Message<T> internalReceive(int timeout, TimeUnit unit) throws PulsarClientException {
    Message<T> message;
    try {
        message = incomingMessages.poll(timeout, unit);
        if (message != null) {
            checkArgument(message instanceof TopicMessageImpl);
            unAckedMessageTracker.add(message.getMessageId());
        }
        resumeReceivingFromPausedConsumersIfNeeded();
        return message;
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new PulsarClientException(e);
    }
}
Also used : PulsarClientException(org.apache.pulsar.client.api.PulsarClientException)

Aggregations

PulsarClientException (org.apache.pulsar.client.api.PulsarClientException)65 Test (org.testng.annotations.Test)24 CompletableFuture (java.util.concurrent.CompletableFuture)17 Message (org.apache.pulsar.client.api.Message)15 IOException (java.io.IOException)14 PulsarClient (org.apache.pulsar.client.api.PulsarClient)13 ExecutionException (java.util.concurrent.ExecutionException)12 Consumer (org.apache.pulsar.client.api.Consumer)12 MessageId (org.apache.pulsar.client.api.MessageId)12 Producer (org.apache.pulsar.client.api.Producer)12 ByteBuf (io.netty.buffer.ByteBuf)11 List (java.util.List)8 ConsumerConfiguration (org.apache.pulsar.client.api.ConsumerConfiguration)8 ProducerConfiguration (org.apache.pulsar.client.api.ProducerConfiguration)7 ArrayList (java.util.ArrayList)6 HashSet (java.util.HashSet)6 Map (java.util.Map)6 Logger (org.slf4j.Logger)6 LoggerFactory (org.slf4j.LoggerFactory)6 TimeUnit (java.util.concurrent.TimeUnit)5