use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class TimelineService method createTimeline.
public void createTimeline(final String eventTypeName, final String storageId) throws AccessDeniedException, TimelineException, TopicRepositoryException, InconsistentStateException, RepositoryProblemException, DbWriteOperationsBlockedException {
if (featureToggleService.isFeatureEnabled(FeatureToggleService.Feature.DISABLE_DB_WRITE_OPERATIONS)) {
throw new DbWriteOperationsBlockedException("Cannot create timeline: write operations on DB " + "are blocked by feature flag.");
}
try {
final EventType eventType = eventTypeCache.getEventType(eventTypeName);
if (!adminService.isAdmin(AuthorizationService.Operation.WRITE)) {
final Resource resource = new EventTypeResource(eventTypeName, eventType.getAuthorization());
throw new AccessDeniedException(AuthorizationService.Operation.ADMIN, resource);
}
final Storage storage = storageDbRepository.getStorage(storageId).orElseThrow(() -> new UnableProcessException("No storage with id: " + storageId));
final Timeline activeTimeline = getActiveTimeline(eventType);
final TopicRepository currentTopicRepo = topicRepositoryHolder.getTopicRepository(activeTimeline.getStorage());
final TopicRepository nextTopicRepo = topicRepositoryHolder.getTopicRepository(storage);
final List<PartitionStatistics> partitionStatistics = currentTopicRepo.loadTopicStatistics(Collections.singleton(activeTimeline));
final String newTopic = nextTopicRepo.createTopic(partitionStatistics.size(), eventType.getOptions().getRetentionTime());
final Timeline nextTimeline = Timeline.createTimeline(activeTimeline.getEventType(), activeTimeline.getOrder() + 1, storage, newTopic, new Date());
switchTimelines(activeTimeline, nextTimeline);
} catch (final TopicCreationException | ServiceUnavailableException | InternalNakadiException e) {
throw new TimelineException("Internal service error", e);
} catch (final NoSuchEventTypeException e) {
throw new NotFoundException("EventType \"" + eventTypeName + "\" does not exist", e);
}
}
use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class EventTypeCacheTest method testEventTypesPreloaded.
@Test
public void testEventTypesPreloaded() throws Exception {
final EventTypeRepository etRepo = Mockito.mock(EventTypeRepository.class);
final TimelineDbRepository timelineRepository = Mockito.mock(TimelineDbRepository.class);
final ZooKeeperHolder zkHolder = Mockito.mock(ZooKeeperHolder.class);
final TimelineSync timelineSync = Mockito.mock(TimelineSync.class);
final EventType et = TestUtils.buildDefaultEventType();
Mockito.when(etRepo.list()).thenReturn(Collections.singletonList(et));
final Timeline timeline = TestUtils.buildTimeline(et.getName());
final List<Timeline> timelines = Collections.singletonList(timeline);
Mockito.when(timelineRepository.listTimelinesOrdered()).thenReturn(timelines);
Mockito.when(timelineSync.registerTimelineChangeListener(Matchers.eq(et.getName()), Mockito.any())).thenReturn(() -> {
});
final EventTypeCache eventTypeCache = new EventTypeCache(etRepo, timelineRepository, zkHolder, null, timelineSync) {
@Override
public void created(final String name) throws Exception {
// ignore this call, because mocking is too complex
}
};
Assert.assertSame(et, eventTypeCache.getEventType(et.getName()));
Mockito.verify(etRepo, Mockito.times(0)).findByName(Mockito.any());
Mockito.verify(etRepo, Mockito.times(1)).list();
Assert.assertEquals(timelines, eventTypeCache.getTimelinesOrdered(et.getName()));
Mockito.verify(timelineRepository, Mockito.times(0)).listTimelinesOrdered(Mockito.any());
Mockito.verify(timelineRepository, Mockito.times(1)).listTimelinesOrdered();
}
use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class NakadiKafkaConsumerTest method whenReadEventsThenGetRightEvents.
@Test
@SuppressWarnings("unchecked")
public void whenReadEventsThenGetRightEvents() {
// ARRANGE //
final byte[] event1 = randomString().getBytes();
final byte[] event2 = randomString().getBytes();
final int event1Offset = randomUInt();
final int event2Offset = randomUInt();
final ConsumerRecords<byte[], byte[]> consumerRecords = new ConsumerRecords<>(ImmutableMap.of(new TopicPartition(TOPIC, PARTITION), ImmutableList.of(new ConsumerRecord<>(TOPIC, PARTITION, event1Offset, "k1".getBytes(), event1), new ConsumerRecord<>(TOPIC, PARTITION, event2Offset, "k2".getBytes(), event2))));
final Timeline timeline = buildTimeline(TOPIC, TOPIC, CREATED_AT);
final ConsumerRecords<byte[], byte[]> emptyRecords = new ConsumerRecords<>(ImmutableMap.of());
final KafkaConsumer<byte[], byte[]> kafkaConsumerMock = mock(KafkaConsumer.class);
final ArgumentCaptor<Long> pollTimeoutCaptor = ArgumentCaptor.forClass(Long.class);
when(kafkaConsumerMock.poll(pollTimeoutCaptor.capture())).thenReturn(consumerRecords, emptyRecords);
// we mock KafkaConsumer anyway, so the cursors we pass are not really important
final List<KafkaCursor> cursors = ImmutableList.of(kafkaCursor(TOPIC, PARTITION, 0));
// ACT //
final NakadiKafkaConsumer consumer = new NakadiKafkaConsumer(kafkaConsumerMock, cursors, createTpTimelineMap(), POLL_TIMEOUT);
final List<ConsumedEvent> consumedEvents = consumer.readEvents();
// ASSERT //
assertThat("The event we read first should not be empty", consumedEvents.size(), equalTo(2));
assertThat("The event we read first should have the same data as first mocked ConsumerRecord", consumedEvents.get(0), equalTo(new ConsumedEvent(event1, new KafkaCursor(TOPIC, PARTITION, event1Offset).toNakadiCursor(timeline))));
assertThat("The event we read second should have the same data as second mocked ConsumerRecord", consumedEvents.get(1), equalTo(new ConsumedEvent(event2, new KafkaCursor(TOPIC, PARTITION, event2Offset).toNakadiCursor(timeline))));
assertThat("The kafka poll should be called with timeout we defined", pollTimeoutCaptor.getValue(), equalTo(POLL_TIMEOUT));
}
use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class CursorOperationsServiceTest method shiftCursorBackToPreviousTimeline.
@Test
public void shiftCursorBackToPreviousTimeline() throws Exception {
final Timeline initialTimeline = mockTimeline(0, 10L);
final Timeline intermediaryTimeline = mockTimeline(1, 9L);
final Timeline finalTimeline = mockTimeline(2, 9L);
mockTimelines(initialTimeline, intermediaryTimeline, finalTimeline);
final ShiftedNakadiCursor shiftedCursor = new ShiftedNakadiCursor(finalTimeline, "0", "000000000000000003", -15L);
final NakadiCursor cursor = service.unshiftCursor(shiftedCursor);
assertThat(cursor.getTimeline().getOrder(), equalTo(0));
assertThat(cursor.getOffset(), equalTo("000000000000000009"));
}
use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class CursorOperationsServiceTest method shiftCursorForwardInTheSameTimelineOpen.
@Test
public void shiftCursorForwardInTheSameTimelineOpen() {
final Timeline initialTimeline = mockTimeline(0, 10L);
final ShiftedNakadiCursor shiftedCursor = new ShiftedNakadiCursor(initialTimeline, "0", "000000000000000003", 3L);
final NakadiCursor cursor = service.unshiftCursor(shiftedCursor);
assertThat(cursor.getOffset(), equalTo("000000000000000006"));
}
Aggregations