final String directory = injector.getInstance(Key.get(String.class, Names.named("eventhub.directory")));
final ShardedEventIndex shardedEventIndex = injector.getInstance(ShardedEventIndex.class);
final DatedEventIndex datedEventIndex = injector.getInstance(DatedEventIndex.class);
final PropertiesIndex propertiesIndex = injector.getInstance(PropertiesIndex.class);
final UserEventIndex userEventIndex = injector.getInstance(UserEventIndex.class);
final EventStorage eventStorage = injector.getInstance(JournalEventStorage.class);
final UserStorage userStorage = injector.getInstance(JournalUserStorage.class);
final EventHub eventHub = new EventHub(directory, shardedEventIndex, datedEventIndex,
propertiesIndex, userEventIndex, eventStorage, userStorage);
final int NUM_EVENTS = 2000;
final int NUM_THREADS = 20; // NUM_EVENTS needs to be muliple of NUM_THREADS
final String[] EVENT_TYPES = { "eventType1", "eventType2", "eventType3", "eventType4" };
final String[] EXTERNAL_USER_IDS = { "10", "11", "12", "13", "14", "15", "16", "17", "18" };
final String[] DATES = { "20130101", "20130102", "20130103", "20130104", "20130105" };
final AtomicInteger counter = new AtomicInteger(0);
final Random random = new Random();
final CountDownLatch latch = new CountDownLatch(NUM_THREADS);
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
latch.countDown();
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for (int j = 0; j < NUM_EVENTS / NUM_THREADS; j++) {
int eventTypeIndex = random.nextInt(EVENT_TYPES.length);
int userIdIndex = random.nextInt(EXTERNAL_USER_IDS.length);
int dateIndex = counter.getAndIncrement() * DATES.length / NUM_EVENTS;
addEvent(eventHub, EVENT_TYPES[eventTypeIndex], EXTERNAL_USER_IDS[userIdIndex], DATES[dateIndex],
Maps.<String, String>newHashMap());
}
}
});
threads[i] = thread;
thread.start();
}
for (int i = 0; i < NUM_THREADS; i++) {
threads[i].join();
}
for (int eventId = 0; eventId < NUM_EVENTS; eventId++) {
Event event = eventStorage.getEvent(eventId);
Assert.assertEquals(shardedEventIndex.getEventTypeId(event.getEventType()), eventStorage.getEventTypeId(eventId));
Assert.assertEquals(userStorage.getId(event.getExternalUserId()), eventStorage.getUserId(eventId));
}
Set<String> externalUserIds = Sets.newHashSet();
for (int i = 0; i < EXTERNAL_USER_IDS.length; i++) {
externalUserIds.add(userStorage.getUser(i).getExternalId());
}
Assert.assertEquals(Sets.newHashSet(EXTERNAL_USER_IDS), externalUserIds);
try {
userStorage.getUser(EXTERNAL_USER_IDS.length);
Assert.fail("Should fail when fetching an user with inexistent id.");
} catch (RuntimeException e) {}
for (int eventTypeId = 0; eventTypeId < EVENT_TYPES.length; eventTypeId++) {
final int EVENT_TYPE_ID = eventTypeId;
// didn't bother check the callback is actually called
shardedEventIndex.enumerateEventIds(EVENT_TYPES[eventTypeId], DATES[0], "21991231",
new EventIndex.Callback() {
@Override
public void onEventId(long eventId) {
Assert.assertEquals(EVENT_TYPES[EVENT_TYPE_ID],
eventStorage.getEvent(eventId).getEventType());
}
});
}
for (int userId = 0; userId < EXTERNAL_USER_IDS.length; userId++) {
final int USER_ID = userId;
userEventIndex.enumerateEventIds(userId, 0, NUM_EVENTS, new UserEventIndex.Callback() {
@Override
public boolean shouldContinueOnEventId(long eventId) {
Assert.assertEquals(USER_ID, userStorage.getId(
eventStorage.getEvent(eventId).getExternalUserId()));
return true;