use of org.zalando.nakadi.domain.Subscription in project nakadi by zalando.
the class CursorsService method resetCursors.
public void resetCursors(final String subscriptionId, final List<NakadiCursor> cursors) throws ServiceUnavailableException, NoSuchSubscriptionException, UnableProcessException, OperationTimeoutException, ZookeeperException, InternalNakadiException, NoSuchEventTypeException, InvalidCursorException {
final Subscription subscription = subscriptionRepository.getSubscription(subscriptionId);
validateCursorsBelongToSubscription(subscription, cursors);
for (final NakadiCursor cursor : cursors) {
cursor.checkStorageAvailability();
}
final Map<TopicRepository, List<NakadiCursor>> topicRepositories = cursors.stream().collect(Collectors.groupingBy(c -> timelineService.getTopicRepository(c.getTimeline())));
for (final Map.Entry<TopicRepository, List<NakadiCursor>> entry : topicRepositories.entrySet()) {
entry.getKey().validateReadCursors(entry.getValue());
}
final ZkSubscriptionClient zkClient = zkSubscriptionFactory.createClient(subscription, "subscription." + subscriptionId + ".reset_cursors");
// In case if subscription was never initialized - initialize it
zkClient.runLocked(() -> StartingState.initializeSubscriptionLocked(zkClient, subscription, timelineService, cursorConverter));
// add 1 second to commit timeout in order to give time to finish reset if there is uncommitted events
if (!cursors.isEmpty()) {
final long timeout = TimeUnit.SECONDS.toMillis(nakadiSettings.getDefaultCommitTimeoutSeconds()) + TimeUnit.SECONDS.toMillis(1);
zkClient.resetCursors(cursors.stream().map(cursorConverter::convertToNoToken).collect(Collectors.toList()), timeout);
}
}
use of org.zalando.nakadi.domain.Subscription in project nakadi by zalando.
the class SubscriptionService method listSubscriptions.
public Result listSubscriptions(@Nullable final String owningApplication, @Nullable final Set<String> eventTypes, final int limit, final int offset) {
if (limit < 1 || limit > 1000) {
final Problem problem = Problem.valueOf(Response.Status.BAD_REQUEST, "'limit' parameter should have value from 1 to 1000");
return Result.problem(problem);
}
if (offset < 0) {
final Problem problem = Problem.valueOf(Response.Status.BAD_REQUEST, "'offset' parameter can't be lower than 0");
return Result.problem(problem);
}
try {
final Set<String> eventTypesFilter = eventTypes == null ? ImmutableSet.of() : eventTypes;
final Optional<String> owningAppOption = Optional.ofNullable(owningApplication);
final List<Subscription> subscriptions = subscriptionRepository.listSubscriptions(eventTypesFilter, owningAppOption, offset, limit);
final PaginationLinks paginationLinks = SubscriptionsUriHelper.createSubscriptionPaginationLinks(owningAppOption, eventTypesFilter, offset, limit, subscriptions.size());
return Result.ok(new PaginationWrapper<>(subscriptions, paginationLinks));
} catch (final ServiceUnavailableException e) {
LOG.error("Error occurred during listing of subscriptions", e);
return Result.problem(e.asProblem());
}
}
use of org.zalando.nakadi.domain.Subscription in project nakadi by zalando.
the class SubscriptionService method getSubscriptionStat.
public ItemsWrapper<SubscriptionEventTypeStats> getSubscriptionStat(final String subscriptionId) throws InconsistentStateException, NoSuchSubscriptionException, ServiceTemporarilyUnavailableException {
final Subscription subscription;
try {
subscription = subscriptionRepository.getSubscription(subscriptionId);
} catch (final ServiceUnavailableException ex) {
throw new InconsistentStateException(ex.getMessage());
}
final List<SubscriptionEventTypeStats> subscriptionStat = createSubscriptionStat(subscription);
return new ItemsWrapper<>(subscriptionStat);
}
use of org.zalando.nakadi.domain.Subscription in project nakadi by zalando.
the class CursorsServiceAT method before.
@Before
public void before() throws Exception {
sid = randomUUID();
streamId = randomUUID();
etName = randomValidEventTypeName();
topic = randomUUID();
cursorConverter = mock(CursorConverter.class);
testCursors = ImmutableList.of(NakadiCursor.of(buildTimeline(etName, topic, CREATED_AT), P1, NEW_OFFSET));
final EventType eventType = mock(EventType.class);
when(eventType.getName()).thenReturn(etName);
final ZooKeeperHolder zkHolder = mock(ZooKeeperHolder.class);
when(zkHolder.get()).thenReturn(CURATOR);
final TopicRepository topicRepository = mock(TopicRepository.class);
final TimelineService timelineService = mock(TimelineService.class);
when(timelineService.getTopicRepository((Timeline) any())).thenReturn(topicRepository);
timeline = buildTimeline(etName, topic, CREATED_AT);
when(timelineService.getActiveTimeline(any(EventType.class))).thenReturn(timeline);
final Subscription subscription = mock(Subscription.class);
when(subscription.getId()).thenReturn(sid);
when(subscription.getEventTypes()).thenReturn(ImmutableSet.of(etName));
final SubscriptionDbRepository subscriptionRepo = mock(SubscriptionDbRepository.class);
when(subscriptionRepo.getSubscription(sid)).thenReturn(subscription);
final SubscriptionClientFactory zkSubscriptionFactory = new SubscriptionClientFactory(zkHolder, MAPPER);
uuidGenerator = mock(UUIDGenerator.class);
when(uuidGenerator.isUUID(any())).thenReturn(true);
cursorsService = new CursorsService(subscriptionRepo, null, mock(NakadiSettings.class), zkSubscriptionFactory, cursorConverter, uuidGenerator, null);
// Register cursors in converter
registerNakadiCursor(NakadiCursor.of(buildTimeline(etName, topic, CREATED_AT), P1, NEW_OFFSET));
registerNakadiCursor(NakadiCursor.of(buildTimeline(etName, topic, CREATED_AT), P1, OLD_OFFSET));
registerNakadiCursor(NakadiCursor.of(buildTimeline(etName, topic, CREATED_AT), P2, NEW_OFFSET));
registerNakadiCursor(NakadiCursor.of(buildTimeline(etName, topic, CREATED_AT), P2, OLD_OFFSET));
// bootstrap data in ZK
CURATOR.create().creatingParentsIfNeeded().forPath(offsetPath(P1), OLD_OFFSET.getBytes(UTF_8));
CURATOR.create().creatingParentsIfNeeded().forPath(offsetPath(P2), OLD_OFFSET.getBytes(UTF_8));
CURATOR.create().creatingParentsIfNeeded().forPath(sessionPath(streamId));
}
use of org.zalando.nakadi.domain.Subscription in project nakadi by zalando.
the class UserJourneyAT method userJourneyHila.
@Test(timeout = 15000)
public void userJourneyHila() throws InterruptedException, IOException {
postEvents(rangeClosed(0, 3).mapToObj(x -> "{\"foo\":\"bar" + x + "\"}").collect(Collectors.toList()).toArray(new String[4]));
// create subscription
final SubscriptionBase subscriptionToCreate = RandomSubscriptionBuilder.builder().withOwningApplication("stups_aruha-test-end2end-nakadi").withEventType(eventTypeName).withStartFrom(BEGIN).buildSubscriptionBase();
final Subscription subscription = createSubscription(jsonRequestSpec(), subscriptionToCreate);
// list subscriptions
jsonRequestSpec().param("event_type", eventTypeName).get("/subscriptions").then().statusCode(OK.value()).body("items.size()", equalTo(1)).body("items[0].id", equalTo(subscription.getId()));
// create client and wait till we receive all events
final TestStreamingClient client = new TestStreamingClient(RestAssured.baseURI + ":" + RestAssured.port, subscription.getId(), "", oauthToken).start();
waitFor(() -> assertThat(client.getBatches(), hasSize(4)));
final List<StreamBatch> batches = client.getBatches();
// validate the content of events
for (int i = 0; i < batches.size(); i++) {
final SubscriptionCursor cursor = new SubscriptionCursor("0", TestUtils.toTimelineOffset(i), eventTypeName, "");
final StreamBatch expectedBatch = new StreamBatch(cursor, ImmutableList.of(ImmutableMap.of("foo", "bar" + i)), i == 0 ? new StreamMetadata("Stream started") : null);
final StreamBatch batch = batches.get(i);
assertThat(batch, equalToBatchIgnoringToken(expectedBatch));
}
// as we didn't commit, there should be still 4 unconsumed events
jsonRequestSpec().get("/subscriptions/{sid}/stats", subscription.getId()).then().statusCode(OK.value()).body("items[0].partitions[0].unconsumed_events", equalTo(4));
// commit cursor of latest event
final StreamBatch lastBatch = batches.get(batches.size() - 1);
final int commitCode = commitCursors(jsonRequestSpec(), subscription.getId(), ImmutableList.of(lastBatch.getCursor()), client.getSessionId());
assertThat(commitCode, equalTo(NO_CONTENT.value()));
// now there should be 0 unconsumed events
jsonRequestSpec().get("/subscriptions/{sid}/stats", subscription.getId()).then().statusCode(OK.value()).body("items[0].partitions[0].unconsumed_events", equalTo(0));
// get cursors
jsonRequestSpec().get("/subscriptions/{sid}/cursors", subscription.getId()).then().statusCode(OK.value()).body("items[0].partition", equalTo("0")).body("items[0].offset", equalTo("001-0001-000000000000000003"));
// delete subscription
jsonRequestSpec().delete("/subscriptions/{sid}", subscription.getId()).then().statusCode(NO_CONTENT.value());
}
Aggregations