use of com.yahoo.pulsar.client.api.PulsarClientException in project pulsar by yahoo.
the class HttpClient method get.
public <T> CompletableFuture<T> get(String path, Class<T> clazz) {
final CompletableFuture<T> future = new CompletableFuture<>();
try {
String requestUrl = new URL(url, path).toString();
AuthenticationDataProvider authData = authentication.getAuthData();
BoundRequestBuilder builder = httpClient.prepareGet(requestUrl);
// Add headers for authentication if any
if (authData.hasDataForHttp()) {
for (Map.Entry<String, String> header : authData.getHttpHeaders()) {
builder.setHeader(header.getKey(), header.getValue());
}
}
final ListenableFuture<Response> responseFuture = builder.setHeader("Accept", "application/json").execute(new AsyncCompletionHandler<Response>() {
@Override
public Response onCompleted(Response response) throws Exception {
return response;
}
@Override
public void onThrowable(Throwable t) {
log.warn("[{}] Failed to perform http request: {}", requestUrl, t.getMessage());
future.completeExceptionally(new PulsarClientException(t));
}
});
responseFuture.addListener(() -> {
try {
Response response = responseFuture.get();
if (response.getStatusCode() != HttpURLConnection.HTTP_OK) {
log.warn("[{}] HTTP get request failed: {}", requestUrl, response.getStatusText());
future.completeExceptionally(new PulsarClientException("HTTP get request failed: " + response.getStatusText()));
return;
}
T data = ObjectMapperFactory.getThreadLocal().readValue(response.getResponseBodyAsBytes(), clazz);
future.complete(data);
} catch (Exception e) {
log.warn("[{}] Error during HTTP get request: {}", requestUrl, e.getMessage());
future.completeExceptionally(new PulsarClientException(e));
}
}, MoreExecutors.sameThreadExecutor());
} catch (Exception e) {
log.warn("[{}] Failed to get authentication data for lookup: {}", path, e.getMessage());
if (e instanceof PulsarClientException) {
future.completeExceptionally(e);
} else {
future.completeExceptionally(new PulsarClientException(e));
}
}
return future;
}
use of com.yahoo.pulsar.client.api.PulsarClientException in project pulsar by yahoo.
the class ProducerImpl method connectionOpened.
@Override
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
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), requestId).thenAccept(producerName -> {
synchronized (ProducerImpl.this) {
if (getState() == State.Closing || getState() == State.Closed) {
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 = DATE_FORMAT.format(Instant.now());
if (this.producerName == null) {
this.producerName = producerName;
}
if (!producerCreatedFuture.isDone() && isBatchMessagingEnabled()) {
client.timer().newTimeout(batchMessageAndSendTask, conf.getBatchingMaxPublishDelayMs(), TimeUnit.MILLISECONDS);
}
resendMessages(cnx);
}
}).exceptionally((e) -> {
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, e.getCause().getMessage());
if (e.getCause() 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 (e.getCause() instanceof PulsarClientException.ProducerBlockedQuotaExceededError) {
log.warn("[{}] [{}] Producer is blocked on creation because backlog exceeded on topic.", producerName, topic);
}
if (//
producerCreatedFuture.isDone() || (e.getCause() instanceof PulsarClientException && isRetriableError((PulsarClientException) e.getCause()) && 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(e.getCause());
} else {
setState(State.Failed);
producerCreatedFuture.completeExceptionally(e.getCause());
client.cleanupProducer(this);
}
return null;
});
}
use of com.yahoo.pulsar.client.api.PulsarClientException in project pulsar by yahoo.
the class ProducerImpl method sendAsync.
public void sendAsync(Message message, SendCallback callback) {
checkArgument(message instanceof MessageImpl);
if (!isValidProducerState(callback)) {
return;
}
if (!canEnqueueRequest(callback)) {
return;
}
MessageImpl msg = (MessageImpl) message;
MessageMetadata.Builder msgMetadata = msg.getMessageBuilder();
ByteBuf payload = msg.getDataBuffer();
// If compression is enabled, we are compressing, otherwise it will simply use the same buffer
int uncompressedSize = payload.readableBytes();
ByteBuf compressedPayload = payload;
// batch will be compressed when closed
if (!isBatchMessagingEnabled()) {
compressedPayload = compressor.encode(payload);
payload.release();
}
if (!msg.isReplicated() && msgMetadata.hasProducerName()) {
callback.sendComplete(new PulsarClientException.InvalidMessageException("Cannot re-use the same message"));
compressedPayload.release();
return;
}
try {
synchronized (this) {
long sequenceId = msgIdGeneratorUpdater.getAndIncrement(this);
if (!msgMetadata.hasPublishTime()) {
msgMetadata.setPublishTime(System.currentTimeMillis());
checkArgument(!msgMetadata.hasProducerName());
checkArgument(!msgMetadata.hasSequenceId());
msgMetadata.setProducerName(producerName);
msgMetadata.setSequenceId(sequenceId);
if (conf.getCompressionType() != CompressionType.NONE) {
msgMetadata.setCompression(convertCompressionType(conf.getCompressionType()));
msgMetadata.setUncompressedSize(uncompressedSize);
}
}
if (isBatchMessagingEnabled()) {
// batch size and/or max message size
if (batchMessageContainer.hasSpaceInBatch(msg)) {
batchMessageContainer.add(msg, callback);
payload.release();
if (batchMessageContainer.numMessagesInBatch == maxNumMessagesInBatch || batchMessageContainer.currentBatchSizeBytes >= BatchMessageContainer.MAX_MESSAGE_BATCH_SIZE_BYTES) {
batchMessageAndSend();
}
} else {
doBatchSendAndAdd(msg, callback, payload);
}
} else {
ByteBuf cmd = sendMessage(producerId, sequenceId, 1, msgMetadata.build(), compressedPayload);
msgMetadata.recycle();
final OpSendMsg op = OpSendMsg.create(msg, cmd, sequenceId, callback);
op.setNumMessagesInBatch(1);
op.setBatchSizeByte(payload.readableBytes());
pendingMessages.put(op);
// Read the connection before validating if it's still connected, so that we avoid reading a null
// value
ClientCnx cnx = cnx();
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(op.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();
callback.sendComplete(new PulsarClientException(ie));
} catch (Throwable t) {
semaphore.release();
callback.sendComplete(new PulsarClientException(t));
}
}
use of com.yahoo.pulsar.client.api.PulsarClientException in project pulsar by yahoo.
the class ProducerImpl method run.
/**
* Process sendTimeout events
*/
@Override
public void run(Timeout timeout) throws Exception {
if (timeout.isCancelled()) {
return;
}
long timeToWaitMs;
synchronized (this) {
OpSendMsg firstMsg = pendingMessages.peek();
if (firstMsg == null) {
// If there are no pending messages, reset the timeout to the configured value.
timeToWaitMs = conf.getSendTimeoutMs();
} else {
// If there is at least one message, calculate the diff between the message timeout and the current
// time.
long diff = (firstMsg.createdAt + conf.getSendTimeoutMs()) - System.currentTimeMillis();
if (diff <= 0) {
// The diff is less than or equal to zero, meaning that the message has been timed out.
// Set the callback to timeout on every message, then clear the pending queue.
log.info("[{}] [{}] Message send timed out. Failing {} messages", topic, producerName, pendingMessages.size());
PulsarClientException te = new PulsarClientException.TimeoutException("Could not send message to broker within given timeout");
failPendingMessages(cnx(), te);
stats.incrementSendFailed(pendingMessages.size());
// Since the pending queue is cleared now, set timer to expire after configured value.
timeToWaitMs = conf.getSendTimeoutMs();
} else {
// The diff is greater than zero, set the timeout to the diff value
timeToWaitMs = diff;
}
}
}
sendTimeout = client.timer().newTimeout(this, timeToWaitMs, TimeUnit.MILLISECONDS);
}
use of com.yahoo.pulsar.client.api.PulsarClientException in project pulsar by yahoo.
the class ContinuousProducer method main.
public static void main(String[] args) throws PulsarClientException, InterruptedException, IOException {
PulsarClient pulsarClient = PulsarClient.create("http://127.0.0.1:8080");
Producer producer = pulsarClient.createProducer("persistent://my-property/use/my-ns/my-topic");
while (true) {
try {
producer.send("my-message".getBytes());
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
pulsarClient.close();
}
Aggregations