use of org.zalando.nakadi.exceptions.EventPublishingException in project nakadi by zalando.
the class KafkaTopicRepository method syncPostBatch.
@Override
public void syncPostBatch(final String topicId, final List<BatchItem> batch) throws EventPublishingException {
final Producer<String, String> producer = kafkaFactory.takeProducer();
try {
final Map<String, String> partitionToBroker = producer.partitionsFor(topicId).stream().collect(Collectors.toMap(p -> String.valueOf(p.partition()), p -> String.valueOf(p.leader().id())));
batch.forEach(item -> {
Preconditions.checkNotNull(item.getPartition(), "BatchItem partition can't be null at the moment of publishing!");
item.setBrokerId(partitionToBroker.get(item.getPartition()));
});
int shortCircuited = 0;
final Map<BatchItem, CompletableFuture<Exception>> sendFutures = new HashMap<>();
for (final BatchItem item : batch) {
item.setStep(EventPublishingStep.PUBLISHING);
final HystrixKafkaCircuitBreaker circuitBreaker = circuitBreakers.computeIfAbsent(item.getBrokerId(), brokerId -> new HystrixKafkaCircuitBreaker(brokerId));
if (circuitBreaker.allowRequest()) {
sendFutures.put(item, publishItem(producer, topicId, item, circuitBreaker));
} else {
shortCircuited++;
item.updateStatusAndDetail(EventPublishingStatus.FAILED, "short circuited");
}
}
if (shortCircuited > 0) {
LOG.warn("Short circuiting request to Kafka {} time(s) due to timeout for topic {}", shortCircuited, topicId);
}
final CompletableFuture<Void> multiFuture = CompletableFuture.allOf(sendFutures.values().toArray(new CompletableFuture<?>[sendFutures.size()]));
multiFuture.get(createSendTimeout(), TimeUnit.MILLISECONDS);
// Now lets check for errors
final Optional<Exception> needReset = sendFutures.entrySet().stream().filter(entry -> isExceptionShouldLeadToReset(entry.getValue().getNow(null))).map(entry -> entry.getValue().getNow(null)).findAny();
if (needReset.isPresent()) {
LOG.info("Terminating producer while publishing to topic {} because of unrecoverable exception", topicId, needReset.get());
kafkaFactory.terminateProducer(producer);
}
} catch (final TimeoutException ex) {
failUnpublished(batch, "timed out");
throw new EventPublishingException("Error publishing message to kafka", ex);
} catch (final ExecutionException ex) {
failUnpublished(batch, "internal error");
throw new EventPublishingException("Error publishing message to kafka", ex);
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
failUnpublished(batch, "interrupted");
throw new EventPublishingException("Error publishing message to kafka", ex);
} finally {
kafkaFactory.releaseProducer(producer);
}
final boolean atLeastOneFailed = batch.stream().anyMatch(item -> item.getResponse().getPublishingStatus() == EventPublishingStatus.FAILED);
if (atLeastOneFailed) {
failUnpublished(batch, "internal error");
throw new EventPublishingException("Error publishing message to kafka");
}
}
use of org.zalando.nakadi.exceptions.EventPublishingException in project nakadi by zalando.
the class EventPublisher method publishInternal.
EventPublishResult publishInternal(final String events, final String eventTypeName, final boolean useAuthz) throws NoSuchEventTypeException, InternalNakadiException, EventTypeTimeoutException, AccessDeniedException, ServiceTemporarilyUnavailableException {
Closeable publishingCloser = null;
final List<BatchItem> batch = BatchFactory.from(events);
try {
publishingCloser = timelineSync.workWithEventType(eventTypeName, nakadiSettings.getTimelineWaitTimeoutMs());
final EventType eventType = eventTypeCache.getEventType(eventTypeName);
if (useAuthz) {
authValidator.authorizeEventTypeWrite(eventType);
}
validate(batch, eventType);
partition(batch, eventType);
enrich(batch, eventType);
submit(batch, eventType);
return ok(batch);
} catch (final EventValidationException e) {
LOG.debug("Event validation error: {}", e.getMessage());
return aborted(EventPublishingStep.VALIDATING, batch);
} catch (final PartitioningException e) {
LOG.debug("Event partition error: {}", e.getMessage());
return aborted(EventPublishingStep.PARTITIONING, batch);
} catch (final EnrichmentException e) {
LOG.debug("Event enrichment error: {}", e.getMessage());
return aborted(EventPublishingStep.ENRICHING, batch);
} catch (final EventPublishingException e) {
LOG.error("error publishing event", e);
return failed(batch);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
LOG.error("Failed to wait for timeline switch", e);
throw new EventTypeTimeoutException("Event type is currently in maintenance, please repeat request");
} catch (final TimeoutException e) {
LOG.error("Failed to wait for timeline switch", e);
throw new EventTypeTimeoutException("Event type is currently in maintenance, please repeat request");
} finally {
try {
if (publishingCloser != null) {
publishingCloser.close();
}
} catch (final IOException e) {
LOG.error("Exception occurred when releasing usage of event-type", e);
}
}
}
Aggregations