use of org.zalando.nakadi.exceptions.EventPublishingException in project nakadi by zalando.
the class KafkaTopicRepositoryTest method whenPostEventTimesOutThenUpdateItemStatus.
@Test
public void whenPostEventTimesOutThenUpdateItemStatus() throws Exception {
final BatchItem item = new BatchItem("{}", BatchItem.EmptyInjectionConfiguration.build(1, true), new BatchItem.InjectionConfiguration[BatchItem.Injection.values().length], Collections.emptyList());
item.setPartition("1");
final List<BatchItem> batch = new ArrayList<>();
batch.add(item);
when(kafkaProducer.partitionsFor(EXPECTED_PRODUCER_RECORD.topic())).thenReturn(ImmutableList.of(new PartitionInfo(EXPECTED_PRODUCER_RECORD.topic(), 1, new Node(1, "host", 9091), null, null)));
when(nakadiSettings.getKafkaSendTimeoutMs()).thenReturn((long) 100);
Mockito.doReturn(mock(Future.class)).when(kafkaProducer).send(any(), any());
try {
kafkaTopicRepository.syncPostBatch(EXPECTED_PRODUCER_RECORD.topic(), batch);
fail();
} catch (final EventPublishingException e) {
assertThat(item.getResponse().getPublishingStatus(), equalTo(EventPublishingStatus.FAILED));
assertThat(item.getResponse().getDetail(), equalTo("timed out"));
}
}
use of org.zalando.nakadi.exceptions.EventPublishingException in project nakadi by zalando.
the class KafkaTopicRepository method publishItem.
private static CompletableFuture<Exception> publishItem(final Producer<String, String> producer, final String topicId, final BatchItem item, final HystrixKafkaCircuitBreaker circuitBreaker) throws EventPublishingException {
try {
final CompletableFuture<Exception> result = new CompletableFuture<>();
final ProducerRecord<String, String> kafkaRecord = new ProducerRecord<>(topicId, KafkaCursor.toKafkaPartition(item.getPartition()), item.getPartition(), item.dumpEventToString());
circuitBreaker.markStart();
producer.send(kafkaRecord, ((metadata, exception) -> {
if (null != exception) {
LOG.warn("Failed to publish to kafka topic {}", topicId, exception);
item.updateStatusAndDetail(EventPublishingStatus.FAILED, "internal error");
if (hasKafkaConnectionException(exception)) {
circuitBreaker.markFailure();
} else {
circuitBreaker.markSuccessfully();
}
result.complete(exception);
} else {
item.updateStatusAndDetail(EventPublishingStatus.SUBMITTED, "");
circuitBreaker.markSuccessfully();
result.complete(null);
}
}));
return result;
} catch (final InterruptException e) {
Thread.currentThread().interrupt();
circuitBreaker.markSuccessfully();
item.updateStatusAndDetail(EventPublishingStatus.FAILED, "internal error");
throw new EventPublishingException("Error publishing message to kafka", e);
} catch (final RuntimeException e) {
circuitBreaker.markSuccessfully();
item.updateStatusAndDetail(EventPublishingStatus.FAILED, "internal error");
throw new EventPublishingException("Error publishing message to kafka", e);
}
}
use of org.zalando.nakadi.exceptions.EventPublishingException in project nakadi by zalando.
the class KafkaTopicRepositoryTest method whenPostEventOverflowsBufferThenUpdateItemStatus.
@Test
public void whenPostEventOverflowsBufferThenUpdateItemStatus() throws Exception {
final BatchItem item = new BatchItem("{}", BatchItem.EmptyInjectionConfiguration.build(1, true), new BatchItem.InjectionConfiguration[BatchItem.Injection.values().length], Collections.emptyList());
item.setPartition("1");
final List<BatchItem> batch = new ArrayList<>();
batch.add(item);
when(kafkaProducer.partitionsFor(EXPECTED_PRODUCER_RECORD.topic())).thenReturn(ImmutableList.of(new PartitionInfo(EXPECTED_PRODUCER_RECORD.topic(), 1, new Node(1, "host", 9091), null, null)));
Mockito.doThrow(BufferExhaustedException.class).when(kafkaProducer).send(any(), any());
try {
kafkaTopicRepository.syncPostBatch(EXPECTED_PRODUCER_RECORD.topic(), batch);
fail();
} catch (final EventPublishingException e) {
assertThat(item.getResponse().getPublishingStatus(), equalTo(EventPublishingStatus.FAILED));
assertThat(item.getResponse().getDetail(), equalTo("internal error"));
}
}
use of org.zalando.nakadi.exceptions.EventPublishingException in project nakadi by zalando.
the class KafkaTopicRepositoryTest method whenKafkaPublishTimeoutThenCircuitIsOpened.
@Test
public void whenKafkaPublishTimeoutThenCircuitIsOpened() throws Exception {
when(nakadiSettings.getKafkaSendTimeoutMs()).thenReturn(1000L);
when(kafkaProducer.partitionsFor(EXPECTED_PRODUCER_RECORD.topic())).thenReturn(ImmutableList.of(new PartitionInfo(EXPECTED_PRODUCER_RECORD.topic(), 1, new Node(1, "host", 9091), null, null)));
when(kafkaProducer.send(any(), any())).thenAnswer(invocation -> {
final Callback callback = (Callback) invocation.getArguments()[1];
callback.onCompletion(null, new TimeoutException());
return null;
});
final List<BatchItem> batches = new LinkedList<>();
for (int i = 0; i < 1000; i++) {
try {
final BatchItem batchItem = new BatchItem("{}", BatchItem.EmptyInjectionConfiguration.build(1, true), new BatchItem.InjectionConfiguration[BatchItem.Injection.values().length], Collections.emptyList());
batchItem.setPartition("1");
batches.add(batchItem);
kafkaTopicRepository.syncPostBatch(EXPECTED_PRODUCER_RECORD.topic(), ImmutableList.of(batchItem));
fail();
} catch (final EventPublishingException e) {
}
}
Assert.assertTrue(batches.stream().filter(item -> item.getResponse().getPublishingStatus() == EventPublishingStatus.FAILED && item.getResponse().getDetail().equals("short circuited")).count() >= 1);
}
use of org.zalando.nakadi.exceptions.EventPublishingException in project nakadi by zalando.
the class KafkaTopicRepositoryTest method whenKafkaPublishCallbackWithExceptionThenEventPublishingException.
@Test
public void whenKafkaPublishCallbackWithExceptionThenEventPublishingException() throws Exception {
final BatchItem firstItem = new BatchItem("{}", BatchItem.EmptyInjectionConfiguration.build(1, true), new BatchItem.InjectionConfiguration[BatchItem.Injection.values().length], Collections.emptyList());
firstItem.setPartition("1");
final BatchItem secondItem = new BatchItem("{}", BatchItem.EmptyInjectionConfiguration.build(1, true), new BatchItem.InjectionConfiguration[BatchItem.Injection.values().length], Collections.emptyList());
secondItem.setPartition("2");
final List<BatchItem> batch = ImmutableList.of(firstItem, secondItem);
when(kafkaProducer.partitionsFor(EXPECTED_PRODUCER_RECORD.topic())).thenReturn(ImmutableList.of(new PartitionInfo(EXPECTED_PRODUCER_RECORD.topic(), 1, new Node(1, "host", 9091), null, null), new PartitionInfo(EXPECTED_PRODUCER_RECORD.topic(), 2, new Node(1, "host", 9091), null, null)));
when(kafkaProducer.send(any(), any())).thenAnswer(invocation -> {
final ProducerRecord record = (ProducerRecord) invocation.getArguments()[0];
final Callback callback = (Callback) invocation.getArguments()[1];
if (record.partition() == 2) {
// return exception only for second event
callback.onCompletion(null, new Exception());
} else {
callback.onCompletion(null, null);
}
return null;
});
try {
kafkaTopicRepository.syncPostBatch(EXPECTED_PRODUCER_RECORD.topic(), batch);
fail();
} catch (final EventPublishingException e) {
assertThat(firstItem.getResponse().getPublishingStatus(), equalTo(EventPublishingStatus.SUBMITTED));
assertThat(firstItem.getResponse().getDetail(), equalTo(""));
assertThat(secondItem.getResponse().getPublishingStatus(), equalTo(EventPublishingStatus.FAILED));
assertThat(secondItem.getResponse().getDetail(), equalTo("internal error"));
}
}
Aggregations