use of org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException in project nakadi by zalando.
the class AbstractZkSubscriptionClient method loadDataAsync.
protected <K, V> Map<K, V> loadDataAsync(final Collection<K> keys, final Function<K, String> keyConverter, final BiFunction<K, byte[], V> valueConverter) throws ServiceTemporarilyUnavailableException, NakadiRuntimeException {
final Map<K, V> result = new HashMap<>();
final CountDownLatch latch = new CountDownLatch(keys.size());
try {
for (final K key : keys) {
final String zkKey = keyConverter.apply(key);
getCurator().getData().inBackground((client, event) -> {
try {
if (event.getResultCode() == KeeperException.Code.OK.intValue()) {
final V value = valueConverter.apply(key, event.getData());
synchronized (result) {
result.put(key, value);
}
} else {
getLog().error("Failed to get {} data from zk. status code: {}", zkKey, event.getResultCode());
}
} catch (RuntimeException ex) {
getLog().error("Failed to memorize {} key value", key, ex);
} finally {
latch.countDown();
}
}).forPath(zkKey);
}
} catch (Exception ex) {
throw new NakadiRuntimeException(ex);
}
try {
if (!latch.await(MAX_ZK_RESPONSE_SECONDS, TimeUnit.SECONDS)) {
throw new ServiceTemporarilyUnavailableException("Failed to wait for zk response", null);
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new ServiceTemporarilyUnavailableException("Failed to wait for zk response", ex);
}
if (result.size() != keys.size()) {
throw new ServiceTemporarilyUnavailableException("Failed to wait for keys " + keys.stream().filter(v -> !result.containsKey(v)).map(String::valueOf).collect(Collectors.joining(", ")) + " to be in response", null);
}
return result;
}
use of org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException in project nakadi by zalando.
the class AbstractZkSubscriptionClient method listSessions.
@Override
public final Collection<Session> listSessions() throws SubscriptionNotInitializedException, NakadiRuntimeException, ServiceTemporarilyUnavailableException {
getLog().info("fetching sessions information");
final List<String> zkSessions;
try {
zkSessions = getCurator().getChildren().forPath(getSubscriptionPath("/sessions"));
} catch (final KeeperException.NoNodeException e) {
throw new SubscriptionNotInitializedException(getSubscriptionId());
} catch (Exception ex) {
throw new NakadiRuntimeException(ex);
}
return loadDataAsync(zkSessions, key -> getSubscriptionPath("/sessions/" + key), this::deserializeSession).values();
}
use of org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException 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.ServiceTemporarilyUnavailableException 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()));
}
use of org.zalando.nakadi.exceptions.runtime.ServiceTemporarilyUnavailableException in project nakadi by zalando.
the class SubscriptionService method createSubscriptionStat.
private List<SubscriptionEventTypeStats> createSubscriptionStat(final Subscription subscription) throws InconsistentStateException, ServiceTemporarilyUnavailableException {
final List<EventType> eventTypes = subscription.getEventTypes().stream().map(Try.wrap(eventTypeRepository::findByName)).map(Try::getOrThrow).sorted(Comparator.comparing(EventType::getName)).collect(Collectors.toList());
final List<PartitionEndStatistics> topicPartitions;
try {
topicPartitions = loadPartitionEndStatistics(eventTypes);
} catch (final ServiceUnavailableException ex) {
throw new ServiceTemporarilyUnavailableException(ex);
}
final ZkSubscriptionClient subscriptionClient;
try {
subscriptionClient = subscriptionClientFactory.createClient(subscription, "subscription." + subscription.getId() + ".stats");
} catch (final InternalNakadiException | NoSuchEventTypeException e) {
throw new ServiceTemporarilyUnavailableException(e);
}
final Optional<ZkSubscriptionNode> zkSubscriptionNode = subscriptionClient.getZkSubscriptionNodeLocked();
return loadStats(eventTypes, zkSubscriptionNode, subscriptionClient, topicPartitions);
}
Aggregations