use of org.zalando.nakadi.exceptions.runtime.DbWriteOperationsBlockedException in project nakadi by zalando.
the class TimelineService method createDefaultTimeline.
public Timeline createDefaultTimeline(final String eventTypeName, final int partitionsCount, final long retentionTime) throws TopicCreationException, InconsistentStateException, RepositoryProblemException, DuplicatedTimelineException, TimelineException, DbWriteOperationsBlockedException {
if (featureToggleService.isFeatureEnabled(FeatureToggleService.Feature.DISABLE_DB_WRITE_OPERATIONS)) {
throw new DbWriteOperationsBlockedException("Cannot create default timeline: write operations on DB " + "are blocked by feature flag.");
}
final TopicRepository repository = topicRepositoryHolder.getTopicRepository(defaultStorage.getStorage());
final String topic = repository.createTopic(partitionsCount, retentionTime);
try {
final Timeline timeline = Timeline.createTimeline(eventTypeName, 1, defaultStorage.getStorage(), topic, new Date());
timeline.setSwitchedAt(new Date());
timelineDbRepository.createTimeline(timeline);
eventTypeCache.updated(eventTypeName);
return timeline;
} catch (final InconsistentStateException | RepositoryProblemException | DuplicatedTimelineException e) {
rollbackTopic(repository, topic);
throw e;
} catch (final Exception e) {
rollbackTopic(repository, topic);
throw new TimelineException("Failed to update event type cache, while creating timeline", e);
}
}
use of org.zalando.nakadi.exceptions.runtime.DbWriteOperationsBlockedException in project nakadi by zalando.
the class StorageService method createStorage.
public Result<Void> createStorage(final JSONObject json) throws DbWriteOperationsBlockedException {
if (featureToggleService.isFeatureEnabled(FeatureToggleService.Feature.DISABLE_DB_WRITE_OPERATIONS)) {
throw new DbWriteOperationsBlockedException("Cannot create storage: write operations on DB " + "are blocked by feature flag.");
}
final String type;
final String id;
final JSONObject configuration;
try {
id = json.getString("id");
type = json.getString("storage_type");
switch(type) {
case "kafka":
configuration = json.getJSONObject("kafka_configuration");
break;
default:
return Result.problem(Problem.valueOf(UNPROCESSABLE_ENTITY, "Type '" + type + "' is not a valid storage type"));
}
} catch (JSONException e) {
return Result.problem(Problem.valueOf(UNPROCESSABLE_ENTITY, e.getMessage()));
}
final Storage storage = new Storage();
storage.setId(id);
storage.setType(Storage.Type.valueOf(type.toUpperCase()));
try {
storage.parseConfiguration(objectMapper, configuration.toString());
} catch (final IOException e) {
return Result.problem(Problem.valueOf(UNPROCESSABLE_ENTITY, e.getMessage()));
}
try {
storageDbRepository.createStorage(storage);
} catch (final RepositoryProblemException e) {
LOG.error("DB error occurred when creating storage", e);
return Result.problem(Problem.valueOf(INTERNAL_SERVER_ERROR, e.getMessage()));
} catch (final DuplicatedStorageException e) {
return Result.problem(Problem.valueOf(CONFLICT, e.getMessage()));
}
return Result.ok();
}
use of org.zalando.nakadi.exceptions.runtime.DbWriteOperationsBlockedException 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);
}
}
use of org.zalando.nakadi.exceptions.runtime.DbWriteOperationsBlockedException 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.runtime.DbWriteOperationsBlockedException in project nakadi by zalando.
the class EventTypeService method delete.
public void delete(final String eventTypeName) throws EventTypeDeletionException, AccessDeniedException, NoEventTypeException, ConflictException, ServiceTemporarilyUnavailableException, DbWriteOperationsBlockedException {
if (featureToggleService.isFeatureEnabled(FeatureToggleService.Feature.DISABLE_DB_WRITE_OPERATIONS)) {
throw new DbWriteOperationsBlockedException("Cannot delete event type: write operations on DB " + "are blocked by feature flag.");
}
Closeable deletionCloser = null;
final EventType eventType;
Multimap<TopicRepository, String> topicsToDelete = null;
try {
deletionCloser = timelineSync.workWithEventType(eventTypeName, nakadiSettings.getTimelineWaitTimeoutMs());
final Optional<EventType> eventTypeOpt = eventTypeRepository.findByNameO(eventTypeName);
if (!eventTypeOpt.isPresent()) {
throw new NoEventTypeException("EventType \"" + eventTypeName + "\" does not exist.");
}
eventType = eventTypeOpt.get();
authorizationValidator.authorizeEventTypeAdmin(eventType);
final List<Subscription> subscriptions = subscriptionRepository.listSubscriptions(ImmutableSet.of(eventTypeName), Optional.empty(), 0, 1);
if (!subscriptions.isEmpty()) {
throw new ConflictException("Can't remove event type " + eventTypeName + ", as it has subscriptions");
}
topicsToDelete = transactionTemplate.execute(action -> deleteEventType(eventTypeName));
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
LOG.error("Failed to wait for timeline switch", e);
throw new EventTypeUnavailableException("Event type " + eventTypeName + " is currently in maintenance, please repeat request");
} catch (final TimeoutException e) {
LOG.error("Failed to wait for timeline switch", e);
throw new EventTypeUnavailableException("Event type " + eventTypeName + " is currently in maintenance, please repeat request");
} catch (final NakadiException e) {
LOG.error("Error deleting event type " + eventTypeName, e);
throw new EventTypeDeletionException("Failed to delete event type " + eventTypeName);
} finally {
try {
if (deletionCloser != null) {
deletionCloser.close();
}
} catch (final IOException e) {
LOG.error("Exception occurred when releasing usage of event-type", e);
}
}
if (topicsToDelete != null) {
for (final TopicRepository topicRepository : topicsToDelete.keySet()) {
for (final String topic : topicsToDelete.get(topicRepository)) {
try {
topicRepository.deleteTopic(topic);
} catch (TopicDeletionException e) {
// If a timeline was marked as deleted, then the topic does not exist, and we should proceed.
LOG.info("Could not delete topic " + topic, e);
}
}
}
}
nakadiKpiPublisher.publish(etLogEventType, () -> new JSONObject().put("event_type", eventTypeName).put("status", "deleted").put("category", eventType.getCategory()).put("authz", identifyAuthzState(eventType)).put("compatibility_mode", eventType.getCompatibilityMode()));
}
Aggregations