use of org.zalando.nakadi.exceptions.NakadiException 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);
}
}
use of org.zalando.nakadi.exceptions.NakadiException 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);
}
}
}
use of org.zalando.nakadi.exceptions.NakadiException in project nakadi by zalando.
the class EventTypeService method deleteEventType.
private Multimap<TopicRepository, String> deleteEventType(final String eventTypeName) throws EventTypeUnavailableException, EventTypeDeletionException {
try {
final Multimap<TopicRepository, String> topicsToDelete = timelineService.deleteAllTimelinesForEventType(eventTypeName);
eventTypeRepository.removeEventType(eventTypeName);
return topicsToDelete;
} catch (TimelineException | NotFoundException e) {
LOG.error("Problem deleting timeline for event type " + eventTypeName, e);
throw new EventTypeDeletionException("Failed to delete timelines for event type " + eventTypeName);
} catch (NakadiException e) {
LOG.error("Error deleting event type " + eventTypeName, e);
throw new EventTypeDeletionException("Failed to delete event type " + eventTypeName);
}
}
use of org.zalando.nakadi.exceptions.NakadiException in project nakadi by zalando.
the class EventTypeService method update.
public void update(final String eventTypeName, final EventTypeBase eventTypeBase) throws TopicConfigException, InconsistentStateException, NakadiRuntimeException, ServiceTemporarilyUnavailableException, UnableProcessException, DbWriteOperationsBlockedException {
if (featureToggleService.isFeatureEnabled(FeatureToggleService.Feature.DISABLE_DB_WRITE_OPERATIONS)) {
throw new DbWriteOperationsBlockedException("Cannot update event type: write operations on DB " + "are blocked by feature flag.");
}
Closeable updatingCloser = null;
try {
updatingCloser = timelineSync.workWithEventType(eventTypeName, nakadiSettings.getTimelineWaitTimeoutMs());
final EventType original = eventTypeRepository.findByName(eventTypeName);
authorizationValidator.authorizeEventTypeAdmin(original);
authorizationValidator.validateAuthorization(original, eventTypeBase);
validateName(eventTypeName, eventTypeBase);
validateSchema(eventTypeBase);
partitionResolver.validate(eventTypeBase);
final EventType eventType = schemaEvolutionService.evolve(original, eventTypeBase);
eventType.setDefaultStatistic(validateStatisticsUpdate(original.getDefaultStatistic(), eventType.getDefaultStatistic()));
updateRetentionTime(original, eventType);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw new ServiceTemporarilyUnavailableException("Event type is currently in maintenance, please repeat request", e);
} catch (final TimeoutException e) {
LOG.error("Failed to wait for timeline switch", e);
throw new ServiceTemporarilyUnavailableException("Event type is currently in maintenance, please repeat request", e);
} catch (final NakadiException e) {
LOG.error("Unable to update event type", e);
throw new NakadiRuntimeException(e);
} finally {
try {
if (updatingCloser != null) {
updatingCloser.close();
}
} catch (final IOException e) {
LOG.error("Exception occurred when releasing usage of event-type", e);
}
}
nakadiKpiPublisher.publish(etLogEventType, () -> new JSONObject().put("event_type", eventTypeName).put("status", "updated").put("category", eventTypeBase.getCategory()).put("authz", identifyAuthzState(eventTypeBase)).put("compatibility_mode", eventTypeBase.getCompatibilityMode()));
}
use of org.zalando.nakadi.exceptions.NakadiException in project nakadi by zalando.
the class EventTypeService method updateEventTypeInDB.
private void updateEventTypeInDB(final EventType eventType, final Long newRetentionTime, final Long oldRetentionTime) throws NakadiException {
final NakadiException exception = transactionTemplate.execute(action -> {
try {
updateTimelinesCleanup(eventType.getName(), newRetentionTime, oldRetentionTime);
eventTypeRepository.update(eventType);
return null;
} catch (final NakadiException e) {
return e;
}
});
if (exception != null) {
throw exception;
}
}
Aggregations