Search in sources :

Example 11 with PartitionStatistics

use of org.zalando.nakadi.domain.PartitionStatistics in project nakadi by zalando.

the class PartitionsController method listPartitions.

@RequestMapping(value = "/event-types/{name}/partitions", method = RequestMethod.GET)
public ResponseEntity<?> listPartitions(@PathVariable("name") final String eventTypeName, final NativeWebRequest request) {
    LOG.trace("Get partitions endpoint for event-type '{}' is called", eventTypeName);
    try {
        final EventType eventType = eventTypeRepository.findByName(eventTypeName);
        authorizationValidator.authorizeStreamRead(eventType);
        final List<Timeline> timelines = timelineService.getActiveTimelinesOrdered(eventTypeName);
        final List<PartitionStatistics> firstStats = timelineService.getTopicRepository(timelines.get(0)).loadTopicStatistics(Collections.singletonList(timelines.get(0)));
        final List<PartitionStatistics> lastStats;
        if (timelines.size() == 1) {
            lastStats = firstStats;
        } else {
            lastStats = timelineService.getTopicRepository(timelines.get(timelines.size() - 1)).loadTopicStatistics(Collections.singletonList(timelines.get(timelines.size() - 1)));
        }
        final List<EventTypePartitionView> result = firstStats.stream().map(first -> {
            final PartitionStatistics last = lastStats.stream().filter(l -> l.getPartition().equals(first.getPartition())).findAny().get();
            return new EventTypePartitionView(eventTypeName, first.getPartition(), cursorConverter.convert(first.getFirst()).getOffset(), cursorConverter.convert(last.getLast()).getOffset());
        }).collect(Collectors.toList());
        return ok().body(result);
    } catch (final NoSuchEventTypeException e) {
        return create(Problem.valueOf(NOT_FOUND, "topic not found"), request);
    } catch (final NakadiException e) {
        LOG.error("Could not list partitions. Respond with SERVICE_UNAVAILABLE.", e);
        return create(e.asProblem(), request);
    }
}
Also used : PathVariable(org.springframework.web.bind.annotation.PathVariable) RequestParam(org.springframework.web.bind.annotation.RequestParam) MoreStatus(org.zalando.problem.MoreStatus) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) LoggerFactory(org.slf4j.LoggerFactory) NotFoundException(org.zalando.nakadi.exceptions.NotFoundException) Autowired(org.springframework.beans.factory.annotation.Autowired) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) NakadiException(org.zalando.nakadi.exceptions.NakadiException) Cursor(org.zalando.nakadi.view.Cursor) MyNakadiRuntimeException1(org.zalando.nakadi.exceptions.runtime.MyNakadiRuntimeException1) Responses.create(org.zalando.problem.spring.web.advice.Responses.create) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) InvalidCursorOperation(org.zalando.nakadi.exceptions.runtime.InvalidCursorOperation) NativeWebRequest(org.springframework.web.context.request.NativeWebRequest) Lists(com.google.common.collect.Lists) NakadiCursorLag(org.zalando.nakadi.domain.NakadiCursorLag) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) Problem(org.zalando.problem.Problem) ExceptionHandler(org.springframework.web.bind.annotation.ExceptionHandler) TimelineService(org.zalando.nakadi.service.timeline.TimelineService) Nullable(javax.annotation.Nullable) EventType(org.zalando.nakadi.domain.EventType) Logger(org.slf4j.Logger) NOT_FOUND(javax.ws.rs.core.Response.Status.NOT_FOUND) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) ResponseEntity.ok(org.springframework.http.ResponseEntity.ok) RequestMethod(org.springframework.web.bind.annotation.RequestMethod) Responses(org.zalando.problem.spring.web.advice.Responses) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) RestController(org.springframework.web.bind.annotation.RestController) Collectors(java.util.stream.Collectors) AuthorizationValidator(org.zalando.nakadi.service.AuthorizationValidator) List(java.util.List) CursorLag(org.zalando.nakadi.view.CursorLag) EventTypePartitionView(org.zalando.nakadi.view.EventTypePartitionView) Response(javax.ws.rs.core.Response) Timeline(org.zalando.nakadi.domain.Timeline) EventTypeRepository(org.zalando.nakadi.repository.EventTypeRepository) Optional(java.util.Optional) ResponseEntity(org.springframework.http.ResponseEntity) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) Collections(java.util.Collections) CursorConverter(org.zalando.nakadi.service.CursorConverter) CursorOperationsService(org.zalando.nakadi.service.CursorOperationsService) Timeline(org.zalando.nakadi.domain.Timeline) EventType(org.zalando.nakadi.domain.EventType) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) EventTypePartitionView(org.zalando.nakadi.view.EventTypePartitionView) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) NakadiException(org.zalando.nakadi.exceptions.NakadiException) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 12 with PartitionStatistics

use of org.zalando.nakadi.domain.PartitionStatistics in project nakadi by zalando.

the class KafkaTopicRepositoryTest method canLoadPartitionStatistics.

@Test
public void canLoadPartitionStatistics() throws Exception {
    final Timeline t1 = mock(Timeline.class);
    when(t1.getTopic()).thenReturn(MY_TOPIC);
    final Timeline t2 = mock(Timeline.class);
    when(t2.getTopic()).thenReturn(ANOTHER_TOPIC);
    final ImmutableList<Timeline> timelines = ImmutableList.of(t1, t2);
    final List<PartitionStatistics> stats = kafkaTopicRepository.loadTopicStatistics(timelines);
    final Set<PartitionStatistics> expected = PARTITIONS.stream().map(p -> {
        final Timeline timeline = p.topic.equals(MY_TOPIC) ? t1 : t2;
        return new KafkaPartitionStatistics(timeline, p.partition, p.earliestOffset, p.latestOffset - 1);
    }).collect(Collectors.toSet());
    assertThat(newHashSet(stats), equalTo(expected));
}
Also used : EventPublishingException(org.zalando.nakadi.exceptions.EventPublishingException) GetChildrenBuilder(org.apache.curator.framework.api.GetChildrenBuilder) KafkaException(org.apache.kafka.common.KafkaException) NakadiException(org.zalando.nakadi.exceptions.NakadiException) Assert.assertThat(org.junit.Assert.assertThat) Future(java.util.concurrent.Future) Arrays.asList(java.util.Arrays.asList) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) Assert.fail(org.junit.Assert.fail) Matchers.anyVararg(org.mockito.Matchers.anyVararg) Consumer(org.apache.kafka.clients.consumer.Consumer) ZooKeeperHolder(org.zalando.nakadi.repository.zookeeper.ZooKeeperHolder) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) Set(java.util.Set) PartitionInfo(org.apache.kafka.common.PartitionInfo) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) Collectors(java.util.stream.Collectors) Matchers.any(org.mockito.Matchers.any) List(java.util.List) CuratorFramework(org.apache.curator.framework.CuratorFramework) TestUtils.buildTimelineWithTopic(org.zalando.nakadi.utils.TestUtils.buildTimelineWithTopic) Timeline(org.zalando.nakadi.domain.Timeline) ZookeeperSettings(org.zalando.nakadi.repository.zookeeper.ZookeeperSettings) Matchers.containsInAnyOrder(org.hamcrest.Matchers.containsInAnyOrder) Matchers.equalTo(org.hamcrest.Matchers.equalTo) BatchItem(org.zalando.nakadi.domain.BatchItem) Node(org.apache.kafka.common.Node) Matchers.is(org.hamcrest.Matchers.is) Callback(org.apache.kafka.clients.producer.Callback) Mockito.mock(org.mockito.Mockito.mock) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) NakadiSettings(org.zalando.nakadi.config.NakadiSettings) Cursor(org.zalando.nakadi.view.Cursor) Matchers.anyString(org.mockito.Matchers.anyString) ArrayList(java.util.ArrayList) UUIDGenerator(org.zalando.nakadi.util.UUIDGenerator) HashSet(java.util.HashSet) KafkaProducer(org.apache.kafka.clients.producer.KafkaProducer) ImmutableList(com.google.common.collect.ImmutableList) LinkedList(java.util.LinkedList) TimeoutException(org.apache.kafka.common.errors.TimeoutException) PartitionEndStatistics(org.zalando.nakadi.domain.PartitionEndStatistics) Test(org.junit.Test) BufferExhaustedException(org.apache.kafka.clients.producer.BufferExhaustedException) Mockito.when(org.mockito.Mockito.when) Mockito(org.mockito.Mockito) Collectors.toList(java.util.stream.Collectors.toList) EventPublishingStatus(org.zalando.nakadi.domain.EventPublishingStatus) CursorError(org.zalando.nakadi.domain.CursorError) Assert(org.junit.Assert) Collections(java.util.Collections) Timeline(org.zalando.nakadi.domain.Timeline) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) Test(org.junit.Test)

Example 13 with PartitionStatistics

use of org.zalando.nakadi.domain.PartitionStatistics 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);
    }
}
Also used : AccessDeniedException(org.zalando.nakadi.exceptions.runtime.AccessDeniedException) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) EventType(org.zalando.nakadi.domain.EventType) Resource(org.zalando.nakadi.plugin.api.authz.Resource) EventTypeResource(org.zalando.nakadi.domain.EventTypeResource) EventTypeResource(org.zalando.nakadi.domain.EventTypeResource) TopicCreationException(org.zalando.nakadi.exceptions.TopicCreationException) NotFoundException(org.zalando.nakadi.exceptions.NotFoundException) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) Date(java.util.Date) TimelineException(org.zalando.nakadi.exceptions.TimelineException) DuplicatedTimelineException(org.zalando.nakadi.exceptions.runtime.DuplicatedTimelineException) Timeline(org.zalando.nakadi.domain.Timeline) DefaultStorage(org.zalando.nakadi.domain.DefaultStorage) Storage(org.zalando.nakadi.domain.Storage) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) TopicRepository(org.zalando.nakadi.repository.TopicRepository) DbWriteOperationsBlockedException(org.zalando.nakadi.exceptions.runtime.DbWriteOperationsBlockedException) UnableProcessException(org.zalando.nakadi.exceptions.UnableProcessException) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException)

Example 14 with PartitionStatistics

use of org.zalando.nakadi.domain.PartitionStatistics in project nakadi by zalando.

the class EventStreamControllerTest method whenNoCursorsThenLatestOffsetsAreUsed.

@Test
public void whenNoCursorsThenLatestOffsetsAreUsed() throws NakadiException, IOException, InvalidCursorException {
    when(eventTypeRepository.findByName(TEST_EVENT_TYPE_NAME)).thenReturn(EVENT_TYPE);
    final List<PartitionStatistics> tps2 = ImmutableList.of(new KafkaPartitionStatistics(timeline, 0, 0, 87), new KafkaPartitionStatistics(timeline, 1, 0, 34));
    when(timelineService.getActiveTimeline(any(EventType.class))).thenReturn(timeline);
    when(topicRepositoryMock.loadTopicStatistics(eq(Collections.singletonList(timeline)))).thenReturn(tps2);
    final ArgumentCaptor<EventStreamConfig> configCaptor = ArgumentCaptor.forClass(EventStreamConfig.class);
    final EventStream eventStreamMock = mock(EventStream.class);
    when(eventStreamFactoryMock.createEventStream(any(), any(), configCaptor.capture(), any())).thenReturn(eventStreamMock);
    final StreamingResponseBody responseBody = createStreamingResponseBody(1, 0, 1, 1, 0, null);
    responseBody.writeTo(new ByteArrayOutputStream());
    final EventStreamConfig streamConfig = configCaptor.getValue();
    assertThat(streamConfig.getCursors(), equalTo(tps2.stream().map(PartitionStatistics::getLast).collect(Collectors.toList())));
}
Also used : EventStreamConfig(org.zalando.nakadi.service.EventStreamConfig) StreamingResponseBody(org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody) KafkaPartitionStatistics(org.zalando.nakadi.repository.kafka.KafkaPartitionStatistics) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) EventType(org.zalando.nakadi.domain.EventType) KafkaPartitionStatistics(org.zalando.nakadi.repository.kafka.KafkaPartitionStatistics) EventStream(org.zalando.nakadi.service.EventStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Test(org.junit.Test)

Example 15 with PartitionStatistics

use of org.zalando.nakadi.domain.PartitionStatistics in project nakadi by zalando.

the class KafkaTopicRepository method convertToKafkaCursors.

private Map<NakadiCursor, KafkaCursor> convertToKafkaCursors(final List<NakadiCursor> cursors) throws ServiceUnavailableException, InvalidCursorException {
    final List<Timeline> timelines = cursors.stream().map(NakadiCursor::getTimeline).distinct().collect(toList());
    final List<PartitionStatistics> statistics = loadTopicStatistics(timelines);
    final Map<NakadiCursor, KafkaCursor> result = new HashMap<>();
    for (final NakadiCursor position : cursors) {
        validateCursorForNulls(position);
        final Optional<PartitionStatistics> partition = statistics.stream().filter(t -> Objects.equals(t.getPartition(), position.getPartition())).filter(t -> Objects.equals(t.getTimeline().getTopic(), position.getTopic())).findAny();
        if (!partition.isPresent()) {
            throw new InvalidCursorException(PARTITION_NOT_FOUND, position);
        }
        final KafkaCursor toCheck = position.asKafkaCursor();
        // Checking oldest position
        final KafkaCursor oldestCursor = KafkaCursor.fromNakadiCursor(partition.get().getBeforeFirst());
        if (toCheck.compareTo(oldestCursor) < 0) {
            throw new InvalidCursorException(UNAVAILABLE, position);
        }
        // checking newest position
        final KafkaCursor newestPosition = KafkaCursor.fromNakadiCursor(partition.get().getLast());
        if (toCheck.compareTo(newestPosition) > 0) {
            throw new InvalidCursorException(UNAVAILABLE, position);
        } else {
            result.put(position, toCheck);
        }
    }
    return result;
}
Also used : EventPublishingException(org.zalando.nakadi.exceptions.EventPublishingException) NotLeaderForPartitionException(org.apache.kafka.common.errors.NotLeaderForPartitionException) Collections.unmodifiableList(java.util.Collections.unmodifiableList) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) TopicRepositoryException(org.zalando.nakadi.exceptions.runtime.TopicRepositoryException) PARTITION_NOT_FOUND(org.zalando.nakadi.domain.CursorError.PARTITION_NOT_FOUND) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) Map(java.util.Map) RetryForSpecifiedTimeStrategy(org.echocat.jomon.runtime.concurrent.RetryForSpecifiedTimeStrategy) Consumer(org.apache.kafka.clients.consumer.Consumer) ZooKeeperHolder(org.zalando.nakadi.repository.zookeeper.ZooKeeperHolder) TopicPartition(org.apache.kafka.common.TopicPartition) TopicRepository(org.zalando.nakadi.repository.TopicRepository) Retryer(org.echocat.jomon.runtime.concurrent.Retryer) Collection(java.util.Collection) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) ConfigType(kafka.server.ConfigType) PartitionInfo(org.apache.kafka.common.PartitionInfo) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) Collectors(java.util.stream.Collectors) TopicDeletionException(org.zalando.nakadi.exceptions.TopicDeletionException) Objects(java.util.Objects) ZkUtils(kafka.utils.ZkUtils) TopicExistsException(org.apache.kafka.common.errors.TopicExistsException) List(java.util.List) Stream(java.util.stream.Stream) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) Timeline(org.zalando.nakadi.domain.Timeline) ZookeeperSettings(org.zalando.nakadi.repository.zookeeper.ZookeeperSettings) NULL_OFFSET(org.zalando.nakadi.domain.CursorError.NULL_OFFSET) BatchItem(org.zalando.nakadi.domain.BatchItem) Optional(java.util.Optional) UnknownTopicOrPartitionException(org.apache.kafka.common.errors.UnknownTopicOrPartitionException) AdminUtils(kafka.admin.AdminUtils) IntStream(java.util.stream.IntStream) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) NetworkException(org.apache.kafka.common.errors.NetworkException) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) NakadiSettings(org.zalando.nakadi.config.NakadiSettings) TopicCreationException(org.zalando.nakadi.exceptions.TopicCreationException) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) TopicConfigException(org.zalando.nakadi.exceptions.runtime.TopicConfigException) UnknownServerException(org.apache.kafka.common.errors.UnknownServerException) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) UUIDGenerator(org.zalando.nakadi.util.UUIDGenerator) InterruptException(org.apache.kafka.common.errors.InterruptException) EventPublishingStep(org.zalando.nakadi.domain.EventPublishingStep) Nullable(javax.annotation.Nullable) UNAVAILABLE(org.zalando.nakadi.domain.CursorError.UNAVAILABLE) NULL_PARTITION(org.zalando.nakadi.domain.CursorError.NULL_PARTITION) Logger(org.slf4j.Logger) Properties(java.util.Properties) Producer(org.apache.kafka.clients.producer.Producer) PartitionEndStatistics(org.zalando.nakadi.domain.PartitionEndStatistics) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) EventConsumer(org.zalando.nakadi.repository.EventConsumer) Collectors.toList(java.util.stream.Collectors.toList) EventPublishingStatus(org.zalando.nakadi.domain.EventPublishingStatus) Preconditions(com.google.common.base.Preconditions) Collections(java.util.Collections) RackAwareMode(kafka.admin.RackAwareMode) Timeline(org.zalando.nakadi.domain.Timeline) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException)

Aggregations

PartitionStatistics (org.zalando.nakadi.domain.PartitionStatistics)15 NakadiCursor (org.zalando.nakadi.domain.NakadiCursor)12 Timeline (org.zalando.nakadi.domain.Timeline)12 TopicRepository (org.zalando.nakadi.repository.TopicRepository)10 List (java.util.List)8 Collectors (java.util.stream.Collectors)8 ServiceUnavailableException (org.zalando.nakadi.exceptions.ServiceUnavailableException)8 Collections (java.util.Collections)7 InvalidCursorException (org.zalando.nakadi.exceptions.InvalidCursorException)7 ArrayList (java.util.ArrayList)6 Test (org.junit.Test)6 Storage (org.zalando.nakadi.domain.Storage)6 Map (java.util.Map)5 Optional (java.util.Optional)5 Logger (org.slf4j.Logger)5 LoggerFactory (org.slf4j.LoggerFactory)5 PartitionEndStatistics (org.zalando.nakadi.domain.PartitionEndStatistics)5 TimelineService (org.zalando.nakadi.service.timeline.TimelineService)5 HashMap (java.util.HashMap)4 Set (java.util.Set)4