Search in sources :

Example 16 with InvalidCursorException

use of org.zalando.nakadi.exceptions.InvalidCursorException in project nakadi by zalando.

the class KafkaTopicRepositoryTest method invalidateInvalidCursors.

@Test
@SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
public void invalidateInvalidCursors() throws NakadiException {
    final Cursor outOfBoundOffset = cursor("0", "38");
    try {
        kafkaTopicRepository.createEventConsumer(KAFKA_CLIENT_ID, asTopicPosition(MY_TOPIC, asList(outOfBoundOffset)));
    } catch (final InvalidCursorException e) {
        assertThat(e.getError(), equalTo(CursorError.UNAVAILABLE));
    }
    final Cursor nonExistingPartition = cursor("99", "100");
    try {
        kafkaTopicRepository.createEventConsumer(KAFKA_CLIENT_ID, asTopicPosition(MY_TOPIC, asList(nonExistingPartition)));
    } catch (final InvalidCursorException e) {
        assertThat(e.getError(), equalTo(CursorError.PARTITION_NOT_FOUND));
    }
    final Cursor wrongOffset = cursor("0", "blah");
    try {
        kafkaTopicRepository.createEventConsumer(KAFKA_CLIENT_ID, asTopicPosition(MY_TOPIC, asList(wrongOffset)));
    } catch (final InvalidCursorException e) {
        assertThat(e.getError(), equalTo(CursorError.INVALID_FORMAT));
    }
}
Also used : InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) Cursor(org.zalando.nakadi.view.Cursor) Test(org.junit.Test)

Example 17 with InvalidCursorException

use of org.zalando.nakadi.exceptions.InvalidCursorException in project nakadi by zalando.

the class EventStreamControllerTest method whenInvalidCursorsThenPreconditionFailed.

@Test
public void whenInvalidCursorsThenPreconditionFailed() throws Exception {
    final NakadiCursor cursor = NakadiCursor.of(timeline, "0", "000000000000000000");
    when(eventTypeRepository.findByName(TEST_EVENT_TYPE_NAME)).thenReturn(EVENT_TYPE);
    when(timelineService.createEventConsumer(eq(KAFKA_CLIENT_ID), any())).thenThrow(new InvalidCursorException(CursorError.UNAVAILABLE, cursor));
    final StreamingResponseBody responseBody = createStreamingResponseBody(1, 0, 0, 0, 0, "[{\"partition\":\"0\",\"offset\":\"00000000000000000\"}]");
    final Problem expectedProblem = Problem.valueOf(PRECONDITION_FAILED, "offset 000000000000000000 for partition 0 is unavailable");
    assertThat(responseToString(responseBody), TestUtils.JSON_TEST_HELPER.matchesObject(expectedProblem));
}
Also used : NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) StreamingResponseBody(org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) Problem(org.zalando.problem.Problem) Test(org.junit.Test)

Example 18 with InvalidCursorException

use of org.zalando.nakadi.exceptions.InvalidCursorException in project nakadi by zalando.

the class CursorsService method validateStreamId.

private void validateStreamId(final List<NakadiCursor> cursors, final String streamId, final ZkSubscriptionClient subscriptionClient) throws ServiceUnavailableException, InvalidCursorException, InvalidStreamIdException {
    if (!uuidGenerator.isUUID(streamId)) {
        throw new InvalidStreamIdException(String.format("Stream id has to be valid UUID, but `%s was provided", streamId), streamId);
    }
    if (!subscriptionClient.isActiveSession(streamId)) {
        throw new InvalidStreamIdException("Session with stream id " + streamId + " not found", streamId);
    }
    final Map<EventTypePartition, String> partitionSessions = Stream.of(subscriptionClient.getTopology().getPartitions()).collect(Collectors.toMap(Partition::getKey, Partition::getSession));
    for (final NakadiCursor cursor : cursors) {
        final EventTypePartition etPartition = cursor.getEventTypePartition();
        final String partitionSession = partitionSessions.get(etPartition);
        if (partitionSession == null) {
            throw new InvalidCursorException(CursorError.PARTITION_NOT_FOUND, cursor);
        }
        if (!streamId.equals(partitionSession)) {
            throw new InvalidStreamIdException("Cursor " + cursor + " cannot be committed with stream id " + streamId, streamId);
        }
    }
}
Also used : NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) EventTypePartition(org.zalando.nakadi.domain.EventTypePartition) InvalidStreamIdException(org.zalando.nakadi.exceptions.InvalidStreamIdException)

Example 19 with InvalidCursorException

use of org.zalando.nakadi.exceptions.InvalidCursorException 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)

Example 20 with InvalidCursorException

use of org.zalando.nakadi.exceptions.InvalidCursorException in project nakadi by zalando.

the class SubscriptionValidationService method validateInitialCursors.

private void validateInitialCursors(final SubscriptionBase subscription, final List<EventTypePartition> allPartitions) throws WrongInitialCursorsException, RepositoryProblemException {
    final boolean cursorsMissing = allPartitions.stream().anyMatch(p -> !subscription.getInitialCursors().stream().anyMatch(p::ownsCursor));
    if (cursorsMissing) {
        throw new WrongInitialCursorsException("initial_cursors should contain cursors for all partitions of subscription");
    }
    final boolean hasCursorForWrongPartition = subscription.getInitialCursors().stream().anyMatch(c -> !allPartitions.contains(new EventTypePartition(c.getEventType(), c.getPartition())));
    if (hasCursorForWrongPartition) {
        throw new WrongInitialCursorsException("initial_cursors should contain cursors only for partitions of this subscription");
    }
    if (subscription.getInitialCursors().size() > allPartitions.size()) {
        throw new WrongInitialCursorsException("there should be no more than 1 cursor for each partition in initial_cursors");
    }
    try {
        for (final SubscriptionCursorWithoutToken cursor : subscription.getInitialCursors()) {
            final NakadiCursor nakadiCursor = cursorConverter.convert(cursor);
            if (nakadiCursor.getTimeline().isDeleted()) {
                throw new InvalidCursorException(UNAVAILABLE, nakadiCursor);
            }
            timelineService.getTopicRepository(nakadiCursor.getTimeline()).validateReadCursors(Collections.singletonList(nakadiCursor));
        }
    } catch (final InvalidCursorException ex) {
        throw new WrongInitialCursorsException(ex.getMessage(), ex);
    } catch (final NakadiException ex) {
        throw new RepositoryProblemException("Topic repository problem occurred when validating cursors", ex);
    }
}
Also used : Map(java.util.Map) SubscriptionCursorWithoutToken(org.zalando.nakadi.view.SubscriptionCursorWithoutToken) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) WrongInitialCursorsException(org.zalando.nakadi.exceptions.runtime.WrongInitialCursorsException) RepositoryProblemException(org.zalando.nakadi.exceptions.runtime.RepositoryProblemException) EventTypePartition(org.zalando.nakadi.domain.EventTypePartition) NakadiException(org.zalando.nakadi.exceptions.NakadiException) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException)

Aggregations

InvalidCursorException (org.zalando.nakadi.exceptions.InvalidCursorException)21 NakadiCursor (org.zalando.nakadi.domain.NakadiCursor)15 Timeline (org.zalando.nakadi.domain.Timeline)9 Map (java.util.Map)8 NakadiException (org.zalando.nakadi.exceptions.NakadiException)8 ServiceUnavailableException (org.zalando.nakadi.exceptions.ServiceUnavailableException)8 List (java.util.List)7 Collectors (java.util.stream.Collectors)7 InternalNakadiException (org.zalando.nakadi.exceptions.InternalNakadiException)7 Optional (java.util.Optional)6 EventTypePartition (org.zalando.nakadi.domain.EventTypePartition)6 PartitionStatistics (org.zalando.nakadi.domain.PartitionStatistics)6 ArrayList (java.util.ArrayList)5 Collections (java.util.Collections)5 HashMap (java.util.HashMap)5 Test (org.junit.Test)5 LoggerFactory (org.slf4j.LoggerFactory)5 NoSuchEventTypeException (org.zalando.nakadi.exceptions.NoSuchEventTypeException)5 IOException (java.io.IOException)4 CursorError (org.zalando.nakadi.domain.CursorError)4