Search in sources :

Example 11 with InvalidCursorException

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

the class CursorOperationsController method getDistance.

@RequestMapping(path = "/event-types/{eventTypeName}/cursor-distances", method = RequestMethod.POST)
public ResponseEntity<?> getDistance(@PathVariable("eventTypeName") final String eventTypeName, @Valid @RequestBody final ValidListWrapper<CursorDistance> queries) throws InternalNakadiException, NoSuchEventTypeException {
    final EventType eventType = eventTypeRepository.findByName(eventTypeName);
    authorizationValidator.authorizeStreamRead(eventType);
    queries.getList().forEach(query -> {
        try {
            final NakadiCursor initialCursor = cursorConverter.convert(eventTypeName, query.getInitialCursor());
            final NakadiCursor finalCursor = cursorConverter.convert(eventTypeName, query.getFinalCursor());
            final Long distance = cursorOperationsService.calculateDistance(initialCursor, finalCursor);
            query.setDistance(distance);
        } catch (InternalNakadiException | ServiceUnavailableException e) {
            throw new MyNakadiRuntimeException1("problem calculating cursors distance", e);
        } catch (final NoSuchEventTypeException e) {
            throw new NotFoundException("event type not found", e);
        } catch (final InvalidCursorException e) {
            throw new CursorConversionException("problem converting cursors", e);
        }
    });
    return status(OK).body(queries.getList());
}
Also used : CursorConversionException(org.zalando.nakadi.exceptions.runtime.CursorConversionException) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) ShiftedNakadiCursor(org.zalando.nakadi.domain.ShiftedNakadiCursor) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) MyNakadiRuntimeException1(org.zalando.nakadi.exceptions.runtime.MyNakadiRuntimeException1) EventType(org.zalando.nakadi.domain.EventType) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) NotFoundException(org.zalando.nakadi.exceptions.NotFoundException) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 12 with InvalidCursorException

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

the class EventStreamController method streamEvents.

@RequestMapping(value = "/event-types/{name}/events", method = RequestMethod.GET)
public StreamingResponseBody streamEvents(@PathVariable("name") final String eventTypeName, @Nullable @RequestParam(value = "batch_limit", required = false) final Integer batchLimit, @Nullable @RequestParam(value = "stream_limit", required = false) final Integer streamLimit, @Nullable @RequestParam(value = "batch_flush_timeout", required = false) final Integer batchTimeout, @Nullable @RequestParam(value = "stream_timeout", required = false) final Integer streamTimeout, @Nullable @RequestParam(value = "stream_keep_alive_limit", required = false) final Integer streamKeepAliveLimit, @Nullable @RequestHeader(name = "X-nakadi-cursors", required = false) final String cursorsStr, final HttpServletRequest request, final HttpServletResponse response, final Client client) {
    final String flowId = FlowIdUtils.peek();
    return outputStream -> {
        FlowIdUtils.push(flowId);
        if (blacklistService.isConsumptionBlocked(eventTypeName, client.getClientId())) {
            writeProblemResponse(response, outputStream, Problem.valueOf(Response.Status.FORBIDDEN, "Application or event type is blocked"));
            return;
        }
        final AtomicBoolean connectionReady = closedConnectionsCrutch.listenForConnectionClose(request);
        Counter consumerCounter = null;
        EventStream eventStream = null;
        List<ConnectionSlot> connectionSlots = ImmutableList.of();
        final AtomicBoolean needCheckAuthorization = new AtomicBoolean(false);
        LOG.info("[X-NAKADI-CURSORS] \"{}\" {}", eventTypeName, Optional.ofNullable(cursorsStr).orElse("-"));
        try (Closeable ignore = eventTypeChangeListener.registerListener(et -> needCheckAuthorization.set(true), Collections.singletonList(eventTypeName))) {
            final EventType eventType = eventTypeRepository.findByName(eventTypeName);
            authorizeStreamRead(eventTypeName);
            // validate parameters
            final EventStreamConfig streamConfig = EventStreamConfig.builder().withBatchLimit(batchLimit).withStreamLimit(streamLimit).withBatchTimeout(batchTimeout).withStreamTimeout(streamTimeout).withStreamKeepAliveLimit(streamKeepAliveLimit).withEtName(eventTypeName).withConsumingClient(client).withCursors(getStreamingStart(eventType, cursorsStr)).withMaxMemoryUsageBytes(maxMemoryUsageBytes).build();
            // acquire connection slots to limit the number of simultaneous connections from one client
            if (featureToggleService.isFeatureEnabled(LIMIT_CONSUMERS_NUMBER)) {
                final List<String> partitions = streamConfig.getCursors().stream().map(NakadiCursor::getPartition).collect(Collectors.toList());
                connectionSlots = consumerLimitingService.acquireConnectionSlots(client.getClientId(), eventTypeName, partitions);
            }
            consumerCounter = metricRegistry.counter(metricNameFor(eventTypeName, CONSUMERS_COUNT_METRIC_NAME));
            consumerCounter.inc();
            final String kafkaQuotaClientId = getKafkaQuotaClientId(eventTypeName, client);
            response.setStatus(HttpStatus.OK.value());
            response.setHeader("Warning", "299 - nakadi - the Low-level API is deprecated and will " + "be removed from a future release. Please consider migrating to the Subscriptions API.");
            response.setContentType("application/x-json-stream");
            final EventConsumer eventConsumer = timelineService.createEventConsumer(kafkaQuotaClientId, streamConfig.getCursors());
            final String bytesFlushedMetricName = MetricUtils.metricNameForLoLAStream(client.getClientId(), eventTypeName);
            final Meter bytesFlushedMeter = this.streamMetrics.meter(bytesFlushedMetricName);
            eventStream = eventStreamFactory.createEventStream(outputStream, eventConsumer, streamConfig, bytesFlushedMeter);
            // Flush status code to client
            outputStream.flush();
            eventStream.streamEvents(connectionReady, () -> {
                if (needCheckAuthorization.getAndSet(false)) {
                    authorizeStreamRead(eventTypeName);
                }
            });
        } catch (final UnparseableCursorException e) {
            LOG.debug("Incorrect syntax of X-nakadi-cursors header: {}. Respond with BAD_REQUEST.", e.getCursors(), e);
            writeProblemResponse(response, outputStream, BAD_REQUEST, e.getMessage());
        } catch (final NoSuchEventTypeException e) {
            writeProblemResponse(response, outputStream, NOT_FOUND, "topic not found");
        } catch (final NoConnectionSlotsException e) {
            LOG.debug("Connection creation failed due to exceeding max connection count");
            writeProblemResponse(response, outputStream, e.asProblem());
        } catch (final NakadiException e) {
            LOG.error("Error while trying to stream events.", e);
            writeProblemResponse(response, outputStream, e.asProblem());
        } catch (final InvalidCursorException e) {
            writeProblemResponse(response, outputStream, PRECONDITION_FAILED, e.getMessage());
        } catch (final AccessDeniedException e) {
            writeProblemResponse(response, outputStream, FORBIDDEN, e.explain());
        } catch (final Exception e) {
            LOG.error("Error while trying to stream events. Respond with INTERNAL_SERVER_ERROR.", e);
            writeProblemResponse(response, outputStream, INTERNAL_SERVER_ERROR, e.getMessage());
        } finally {
            connectionReady.set(false);
            consumerLimitingService.releaseConnectionSlots(connectionSlots);
            if (consumerCounter != null) {
                consumerCounter.dec();
            }
            if (eventStream != null) {
                eventStream.close();
            }
            try {
                outputStream.flush();
            } finally {
                outputStream.close();
            }
        }
    };
}
Also used : PathVariable(org.springframework.web.bind.annotation.PathVariable) RequestParam(org.springframework.web.bind.annotation.RequestParam) FlowIdUtils(org.zalando.nakadi.util.FlowIdUtils) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) NakadiException(org.zalando.nakadi.exceptions.NakadiException) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) Problem(org.zalando.problem.Problem) Map(java.util.Map) Counter(com.codahale.metrics.Counter) TimelineService(org.zalando.nakadi.service.timeline.TimelineService) TypeReference(com.fasterxml.jackson.core.type.TypeReference) FeatureToggleService(org.zalando.nakadi.service.FeatureToggleService) EventTypeChangeListener(org.zalando.nakadi.service.EventTypeChangeListener) BAD_REQUEST(javax.ws.rs.core.Response.Status.BAD_REQUEST) ConsumerLimitingService(org.zalando.nakadi.service.ConsumerLimitingService) TopicRepository(org.zalando.nakadi.repository.TopicRepository) ConnectionSlot(org.zalando.nakadi.service.ConnectionSlot) NOT_FOUND(javax.ws.rs.core.Response.Status.NOT_FOUND) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) RequestMethod(org.springframework.web.bind.annotation.RequestMethod) StreamingResponseBody(org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) BlacklistService(org.zalando.nakadi.service.BlacklistService) RestController(org.springframework.web.bind.annotation.RestController) Collectors(java.util.stream.Collectors) List(java.util.List) Response(javax.ws.rs.core.Response) Timeline(org.zalando.nakadi.domain.Timeline) ServiceTemporarilyUnavailableException(org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException) Optional(java.util.Optional) RequestHeader(org.springframework.web.bind.annotation.RequestHeader) UnparseableCursorException(org.zalando.nakadi.exceptions.UnparseableCursorException) Client(org.zalando.nakadi.security.Client) Storage(org.zalando.nakadi.domain.Storage) ClosedConnectionsCrutch(org.zalando.nakadi.service.ClosedConnectionsCrutch) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Cursor(org.zalando.nakadi.view.Cursor) ArrayList(java.util.ArrayList) Value(org.springframework.beans.factory.annotation.Value) Meter(com.codahale.metrics.Meter) HttpServletRequest(javax.servlet.http.HttpServletRequest) ImmutableList(com.google.common.collect.ImmutableList) EventStreamFactory(org.zalando.nakadi.service.EventStreamFactory) Qualifier(org.springframework.beans.factory.annotation.Qualifier) PRECONDITION_FAILED(javax.ws.rs.core.Response.Status.PRECONDITION_FAILED) Nullable(javax.annotation.Nullable) OutputStream(java.io.OutputStream) AccessDeniedException(org.zalando.nakadi.exceptions.runtime.AccessDeniedException) EventType(org.zalando.nakadi.domain.EventType) MetricRegistry(com.codahale.metrics.MetricRegistry) Logger(org.slf4j.Logger) INTERNAL_SERVER_ERROR(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) HttpServletResponse(javax.servlet.http.HttpServletResponse) MetricUtils.metricNameFor(org.zalando.nakadi.metrics.MetricUtils.metricNameFor) IOException(java.io.IOException) FORBIDDEN(javax.ws.rs.core.Response.Status.FORBIDDEN) EventStream(org.zalando.nakadi.service.EventStream) AuthorizationValidator(org.zalando.nakadi.service.AuthorizationValidator) HttpStatus(org.springframework.http.HttpStatus) EventConsumer(org.zalando.nakadi.repository.EventConsumer) EventTypeRepository(org.zalando.nakadi.repository.EventTypeRepository) Closeable(java.io.Closeable) NoConnectionSlotsException(org.zalando.nakadi.exceptions.NoConnectionSlotsException) LIMIT_CONSUMERS_NUMBER(org.zalando.nakadi.service.FeatureToggleService.Feature.LIMIT_CONSUMERS_NUMBER) CursorError(org.zalando.nakadi.domain.CursorError) VisibleForTesting(com.google.common.annotations.VisibleForTesting) MetricUtils(org.zalando.nakadi.metrics.MetricUtils) EventStreamConfig(org.zalando.nakadi.service.EventStreamConfig) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) Collections(java.util.Collections) CursorConverter(org.zalando.nakadi.service.CursorConverter) AccessDeniedException(org.zalando.nakadi.exceptions.runtime.AccessDeniedException) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) EventType(org.zalando.nakadi.domain.EventType) Meter(com.codahale.metrics.Meter) Closeable(java.io.Closeable) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) UnparseableCursorException(org.zalando.nakadi.exceptions.UnparseableCursorException) NakadiException(org.zalando.nakadi.exceptions.NakadiException) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) ServiceTemporarilyUnavailableException(org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException) UnparseableCursorException(org.zalando.nakadi.exceptions.UnparseableCursorException) AccessDeniedException(org.zalando.nakadi.exceptions.runtime.AccessDeniedException) IOException(java.io.IOException) NoConnectionSlotsException(org.zalando.nakadi.exceptions.NoConnectionSlotsException) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) NakadiException(org.zalando.nakadi.exceptions.NakadiException) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EventStreamConfig(org.zalando.nakadi.service.EventStreamConfig) EventConsumer(org.zalando.nakadi.repository.EventConsumer) Counter(com.codahale.metrics.Counter) EventStream(org.zalando.nakadi.service.EventStream) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) NoConnectionSlotsException(org.zalando.nakadi.exceptions.NoConnectionSlotsException) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 13 with InvalidCursorException

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

the class EventStreamController method getStreamingStart.

@VisibleForTesting
List<NakadiCursor> getStreamingStart(final EventType eventType, final String cursorsStr) throws UnparseableCursorException, ServiceUnavailableException, InvalidCursorException, InternalNakadiException, NoSuchEventTypeException {
    List<Cursor> cursors = null;
    if (cursorsStr != null) {
        try {
            cursors = jsonMapper.readValue(cursorsStr, new TypeReference<ArrayList<Cursor>>() {
            });
        } catch (final IOException ex) {
            throw new UnparseableCursorException("incorrect syntax of X-nakadi-cursors header", ex, cursorsStr);
        }
        // Unfortunately, In order to have consistent exception checking, one can not just call validator
        for (final Cursor cursor : cursors) {
            if (null == cursor.getPartition()) {
                throw new InvalidCursorException(CursorError.NULL_PARTITION, cursor);
            } else if (null == cursor.getOffset()) {
                throw new InvalidCursorException(CursorError.NULL_OFFSET, cursor);
            }
        }
    }
    final Timeline latestTimeline = timelineService.getActiveTimeline(eventType);
    if (null != cursors) {
        if (cursors.isEmpty()) {
            throw new InvalidCursorException(CursorError.INVALID_FORMAT);
        }
        final List<NakadiCursor> result = new ArrayList<>();
        for (final Cursor c : cursors) {
            result.add(cursorConverter.convert(eventType.getName(), c));
        }
        for (final NakadiCursor c : result) {
            if (c.getTimeline().isDeleted()) {
                throw new InvalidCursorException(CursorError.UNAVAILABLE, c);
            }
        }
        final Map<Storage, List<NakadiCursor>> groupedCursors = result.stream().collect(Collectors.groupingBy(c -> c.getTimeline().getStorage()));
        for (final Map.Entry<Storage, List<NakadiCursor>> entry : groupedCursors.entrySet()) {
            timelineService.getTopicRepository(entry.getKey()).validateReadCursors(entry.getValue());
        }
        return result;
    } else {
        final TopicRepository latestTopicRepository = timelineService.getTopicRepository(latestTimeline);
        // if no cursors provided - read from the newest available events
        return latestTopicRepository.loadTopicStatistics(Collections.singletonList(latestTimeline)).stream().map(PartitionStatistics::getLast).collect(Collectors.toList());
    }
}
Also used : PathVariable(org.springframework.web.bind.annotation.PathVariable) RequestParam(org.springframework.web.bind.annotation.RequestParam) FlowIdUtils(org.zalando.nakadi.util.FlowIdUtils) LoggerFactory(org.slf4j.LoggerFactory) Autowired(org.springframework.beans.factory.annotation.Autowired) NakadiException(org.zalando.nakadi.exceptions.NakadiException) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) Problem(org.zalando.problem.Problem) Map(java.util.Map) Counter(com.codahale.metrics.Counter) TimelineService(org.zalando.nakadi.service.timeline.TimelineService) TypeReference(com.fasterxml.jackson.core.type.TypeReference) FeatureToggleService(org.zalando.nakadi.service.FeatureToggleService) EventTypeChangeListener(org.zalando.nakadi.service.EventTypeChangeListener) BAD_REQUEST(javax.ws.rs.core.Response.Status.BAD_REQUEST) ConsumerLimitingService(org.zalando.nakadi.service.ConsumerLimitingService) TopicRepository(org.zalando.nakadi.repository.TopicRepository) ConnectionSlot(org.zalando.nakadi.service.ConnectionSlot) NOT_FOUND(javax.ws.rs.core.Response.Status.NOT_FOUND) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) RequestMethod(org.springframework.web.bind.annotation.RequestMethod) StreamingResponseBody(org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) BlacklistService(org.zalando.nakadi.service.BlacklistService) RestController(org.springframework.web.bind.annotation.RestController) Collectors(java.util.stream.Collectors) List(java.util.List) Response(javax.ws.rs.core.Response) Timeline(org.zalando.nakadi.domain.Timeline) ServiceTemporarilyUnavailableException(org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException) Optional(java.util.Optional) RequestHeader(org.springframework.web.bind.annotation.RequestHeader) UnparseableCursorException(org.zalando.nakadi.exceptions.UnparseableCursorException) Client(org.zalando.nakadi.security.Client) Storage(org.zalando.nakadi.domain.Storage) ClosedConnectionsCrutch(org.zalando.nakadi.service.ClosedConnectionsCrutch) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Cursor(org.zalando.nakadi.view.Cursor) ArrayList(java.util.ArrayList) Value(org.springframework.beans.factory.annotation.Value) Meter(com.codahale.metrics.Meter) HttpServletRequest(javax.servlet.http.HttpServletRequest) ImmutableList(com.google.common.collect.ImmutableList) EventStreamFactory(org.zalando.nakadi.service.EventStreamFactory) Qualifier(org.springframework.beans.factory.annotation.Qualifier) PRECONDITION_FAILED(javax.ws.rs.core.Response.Status.PRECONDITION_FAILED) Nullable(javax.annotation.Nullable) OutputStream(java.io.OutputStream) AccessDeniedException(org.zalando.nakadi.exceptions.runtime.AccessDeniedException) EventType(org.zalando.nakadi.domain.EventType) MetricRegistry(com.codahale.metrics.MetricRegistry) Logger(org.slf4j.Logger) INTERNAL_SERVER_ERROR(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) HttpServletResponse(javax.servlet.http.HttpServletResponse) MetricUtils.metricNameFor(org.zalando.nakadi.metrics.MetricUtils.metricNameFor) IOException(java.io.IOException) FORBIDDEN(javax.ws.rs.core.Response.Status.FORBIDDEN) EventStream(org.zalando.nakadi.service.EventStream) AuthorizationValidator(org.zalando.nakadi.service.AuthorizationValidator) HttpStatus(org.springframework.http.HttpStatus) EventConsumer(org.zalando.nakadi.repository.EventConsumer) EventTypeRepository(org.zalando.nakadi.repository.EventTypeRepository) Closeable(java.io.Closeable) NoConnectionSlotsException(org.zalando.nakadi.exceptions.NoConnectionSlotsException) LIMIT_CONSUMERS_NUMBER(org.zalando.nakadi.service.FeatureToggleService.Feature.LIMIT_CONSUMERS_NUMBER) CursorError(org.zalando.nakadi.domain.CursorError) VisibleForTesting(com.google.common.annotations.VisibleForTesting) MetricUtils(org.zalando.nakadi.metrics.MetricUtils) EventStreamConfig(org.zalando.nakadi.service.EventStreamConfig) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException) Collections(java.util.Collections) CursorConverter(org.zalando.nakadi.service.CursorConverter) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) UnparseableCursorException(org.zalando.nakadi.exceptions.UnparseableCursorException) ArrayList(java.util.ArrayList) IOException(java.io.IOException) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) Cursor(org.zalando.nakadi.view.Cursor) Timeline(org.zalando.nakadi.domain.Timeline) Storage(org.zalando.nakadi.domain.Storage) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) TypeReference(com.fasterxml.jackson.core.type.TypeReference) TopicRepository(org.zalando.nakadi.repository.TopicRepository) Map(java.util.Map) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 14 with InvalidCursorException

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

the class PartitionsController method getPartition.

@RequestMapping(value = "/event-types/{name}/partitions/{partition}", method = RequestMethod.GET)
public ResponseEntity<?> getPartition(@PathVariable("name") final String eventTypeName, @PathVariable("partition") final String partition, @Nullable @RequestParam(value = "consumed_offset", required = false) final String consumedOffset, final NativeWebRequest request) {
    LOG.trace("Get partition endpoint for event-type '{}', partition '{}' is called", eventTypeName, partition);
    try {
        final EventType eventType = eventTypeRepository.findByName(eventTypeName);
        authorizationValidator.authorizeStreamRead(eventType);
        if (consumedOffset != null) {
            final CursorLag cursorLag = getCursorLag(eventTypeName, partition, consumedOffset);
            return ok().body(cursorLag);
        } else {
            final EventTypePartitionView result = getTopicPartition(eventTypeName, partition);
            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 get partition. Respond with SERVICE_UNAVAILABLE.", e);
        return create(e.asProblem(), request);
    } catch (final InvalidCursorException e) {
        return create(Problem.valueOf(MoreStatus.UNPROCESSABLE_ENTITY, INVALID_CURSOR_MESSAGE), request);
    }
}
Also used : EventType(org.zalando.nakadi.domain.EventType) EventTypePartitionView(org.zalando.nakadi.view.EventTypePartitionView) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) NakadiCursorLag(org.zalando.nakadi.domain.NakadiCursorLag) CursorLag(org.zalando.nakadi.view.CursorLag) 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 15 with InvalidCursorException

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

the class MultiTimelineEventConsumer method electTopicRepositories.

private void electTopicRepositories() throws NakadiException, InvalidCursorException {
    final Map<TopicRepository, List<NakadiCursor>> newAssignment = new HashMap<>();
    borderOffsets.clear();
    // Purpose of this collection is to hold tr that definitely changed their positions and should be recreated.
    final Set<TopicPartition> actualReadPositionChanged = new HashSet<>();
    // load new topic repositories and possibly replace cursors to newer timelines.
    for (final NakadiCursor cursor : latestOffsets.values()) {
        final AtomicReference<NakadiCursor> cursorReplacement = new AtomicReference<>();
        final TopicRepository topicRepository = selectCorrectTopicRepo(cursor, cursorReplacement::set, nc -> Optional.ofNullable(nc).ifPresent(itm -> borderOffsets.put(itm.getEventTypePartition(), itm.getOffset())));
        if (!newAssignment.containsKey(topicRepository)) {
            newAssignment.put(topicRepository, new ArrayList<>());
        }
        if (cursorReplacement.get() != null) {
            actualReadPositionChanged.add(cursor.getTopicPartition());
            newAssignment.get(topicRepository).add(cursorReplacement.get());
        } else {
            newAssignment.get(topicRepository).add(cursor);
        }
    }
    final Set<TopicRepository> removedTopicRepositories = eventConsumers.keySet().stream().filter(tr -> !newAssignment.containsKey(tr)).collect(Collectors.toSet());
    // Stop and remove event consumers that are not needed anymore
    for (final TopicRepository toRemove : removedTopicRepositories) {
        stopAndRemoveConsumer(toRemove);
    }
    // Stop and remove event consumers with changed configuration
    for (final Map.Entry<TopicRepository, List<NakadiCursor>> entry : newAssignment.entrySet()) {
        final EventConsumer.LowLevelConsumer existingEventConsumer = eventConsumers.get(entry.getKey());
        if (null != existingEventConsumer) {
            final Set<TopicPartition> newTopicPartitions = entry.getValue().stream().map(NakadiCursor::getTopicPartition).collect(Collectors.toSet());
            final Set<TopicPartition> oldAssignment = existingEventConsumer.getAssignment();
            if (!oldAssignment.equals(newTopicPartitions) || oldAssignment.stream().anyMatch(actualReadPositionChanged::contains)) {
                stopAndRemoveConsumer(entry.getKey());
            }
        }
    }
    // Start new consumers with changed configuration.
    for (final Map.Entry<TopicRepository, List<NakadiCursor>> entry : newAssignment.entrySet()) {
        if (!eventConsumers.containsKey(entry.getKey())) {
            final TopicRepository repo = entry.getKey();
            LOG.info("Creating underlying consumer for client id {} and cursors {}", clientId, Arrays.deepToString(entry.getValue().toArray()));
            final EventConsumer.LowLevelConsumer consumer = repo.createEventConsumer(clientId, entry.getValue());
            eventConsumers.put(repo, consumer);
        }
    }
}
Also used : ConsumedEvent(org.zalando.nakadi.domain.ConsumedEvent) Arrays(java.util.Arrays) EventTypePartition(org.zalando.nakadi.domain.EventTypePartition) ListIterator(java.util.ListIterator) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) NakadiCollectionUtils(org.zalando.nakadi.util.NakadiCollectionUtils) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) NakadiException(org.zalando.nakadi.exceptions.NakadiException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) TopicPartition(org.zalando.nakadi.domain.TopicPartition) ServiceUnavailableException(org.zalando.nakadi.exceptions.ServiceUnavailableException) Map(java.util.Map) TimelineService(org.zalando.nakadi.service.timeline.TimelineService) Logger(org.slf4j.Logger) TimelineSync(org.zalando.nakadi.service.timeline.TimelineSync) Collection(java.util.Collection) PartitionStatistics(org.zalando.nakadi.domain.PartitionStatistics) Set(java.util.Set) IOException(java.io.IOException) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) NakadiRuntimeException(org.zalando.nakadi.exceptions.NakadiRuntimeException) List(java.util.List) Timeline(org.zalando.nakadi.domain.Timeline) Optional(java.util.Optional) Comparator(java.util.Comparator) Collections(java.util.Collections) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) TopicPartition(org.zalando.nakadi.domain.TopicPartition) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

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