Search in sources :

Example 6 with NakadiException

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

the class EventPublishingController method postEventInternal.

private ResponseEntity postEventInternal(final String eventTypeName, final String eventsAsString, final NativeWebRequest nativeWebRequest, final EventTypeMetrics eventTypeMetrics, final Client client) throws AccessDeniedException, ServiceTemporarilyUnavailableException {
    final long startingNanos = System.nanoTime();
    try {
        final EventPublishResult result = publisher.publish(eventsAsString, eventTypeName);
        final int eventCount = result.getResponses().size();
        final int totalSizeBytes = eventsAsString.getBytes(Charsets.UTF_8).length;
        reportMetrics(eventTypeMetrics, result, totalSizeBytes, eventCount);
        reportSLOs(startingNanos, totalSizeBytes, eventCount, result, eventTypeName, client);
        return response(result);
    } catch (final JSONException e) {
        LOG.debug("Problem parsing event", e);
        return processJSONException(e, nativeWebRequest);
    } catch (final NoSuchEventTypeException e) {
        LOG.debug("Event type not found.", e);
        return create(e.asProblem(), nativeWebRequest);
    } catch (final NakadiException e) {
        LOG.debug("Failed to publish batch", e);
        return create(e.asProblem(), nativeWebRequest);
    } finally {
        eventTypeMetrics.updateTiming(startingNanos, System.nanoTime());
    }
}
Also used : EventPublishResult(org.zalando.nakadi.domain.EventPublishResult) JSONException(org.json.JSONException) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) NakadiException(org.zalando.nakadi.exceptions.NakadiException)

Example 7 with NakadiException

use of org.zalando.nakadi.exceptions.NakadiException 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 8 with NakadiException

use of org.zalando.nakadi.exceptions.NakadiException 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 9 with NakadiException

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

the class EventTypeDbRepositoryTest method whenListExistingEventTypesAreListed.

@Test
public void whenListExistingEventTypesAreListed() throws NakadiException {
    final EventType eventType1 = buildDefaultEventType();
    final EventType eventType2 = buildDefaultEventType();
    repository.saveEventType(eventType1);
    repository.saveEventType(eventType2);
    final List<EventType> eventTypes = repository.list().stream().filter(et -> et.getName() != null).filter(et -> et.getName().equals(eventType1.getName()) || et.getName().equals(eventType2.getName())).collect(Collectors.toList());
    assertThat(eventTypes, hasSize(2));
}
Also used : EventCategory(org.zalando.nakadi.domain.EventCategory) EventType(org.zalando.nakadi.domain.EventType) TestUtils.buildDefaultEventType(org.zalando.nakadi.utils.TestUtils.buildDefaultEventType) IsEqual.equalTo(org.hamcrest.core.IsEqual.equalTo) DuplicatedEventTypeNameException(org.zalando.nakadi.exceptions.DuplicatedEventTypeNameException) Test(org.junit.Test) IOException(java.io.IOException) NakadiException(org.zalando.nakadi.exceptions.NakadiException) TestUtils(org.zalando.nakadi.utils.TestUtils) NoSuchEventTypeException(org.zalando.nakadi.exceptions.NoSuchEventTypeException) Collectors(java.util.stream.Collectors) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) TextNode(com.fasterxml.jackson.databind.node.TextNode) Version(org.zalando.nakadi.domain.Version) EventTypeSchema(org.zalando.nakadi.domain.EventTypeSchema) List(java.util.List) EventTypeRepository(org.zalando.nakadi.repository.EventTypeRepository) IsNull.notNullValue(org.hamcrest.core.IsNull.notNullValue) Matchers.hasSize(org.hamcrest.Matchers.hasSize) SqlRowSet(org.springframework.jdbc.support.rowset.SqlRowSet) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Before(org.junit.Before) EventType(org.zalando.nakadi.domain.EventType) TestUtils.buildDefaultEventType(org.zalando.nakadi.utils.TestUtils.buildDefaultEventType) Test(org.junit.Test)

Example 10 with NakadiException

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

the class ExceptionHandling method handleTimelineException.

@ExceptionHandler(TimelineException.class)
public ResponseEntity<Problem> handleTimelineException(final TimelineException exception, final NativeWebRequest request) {
    LOG.error(exception.getMessage(), exception);
    final Throwable cause = exception.getCause();
    if (cause instanceof NakadiException) {
        final NakadiException ne = (NakadiException) cause;
        return Responses.create(ne.asProblem(), request);
    }
    return Responses.create(Response.Status.SERVICE_UNAVAILABLE, exception.getMessage(), request);
}
Also used : NakadiException(org.zalando.nakadi.exceptions.NakadiException) ExceptionHandler(org.springframework.web.bind.annotation.ExceptionHandler)

Aggregations

NakadiException (org.zalando.nakadi.exceptions.NakadiException)17 InternalNakadiException (org.zalando.nakadi.exceptions.InternalNakadiException)9 List (java.util.List)7 Collectors (java.util.stream.Collectors)7 Timeline (org.zalando.nakadi.domain.Timeline)7 InvalidCursorException (org.zalando.nakadi.exceptions.InvalidCursorException)7 IOException (java.io.IOException)6 LoggerFactory (org.slf4j.LoggerFactory)6 EventType (org.zalando.nakadi.domain.EventType)6 NakadiCursor (org.zalando.nakadi.domain.NakadiCursor)6 NoSuchEventTypeException (org.zalando.nakadi.exceptions.NoSuchEventTypeException)6 Collections (java.util.Collections)5 Optional (java.util.Optional)5 Logger (org.slf4j.Logger)5 NakadiRuntimeException (org.zalando.nakadi.exceptions.NakadiRuntimeException)5 TimelineService (org.zalando.nakadi.service.timeline.TimelineService)5 Closeable (java.io.Closeable)4 Map (java.util.Map)4 EventTypePartition (org.zalando.nakadi.domain.EventTypePartition)4 PartitionStatistics (org.zalando.nakadi.domain.PartitionStatistics)4