EventRouting extends MessageRouting<EventMessage, EventContext, Set<I>> implements EventRoute<I, EventMessage> { @CanIgnoreReturnValue public <E extends EventMessage> EventRouting<I> route(Class<E> eventType, EventRoute<I, ? super E> via) throws IllegalStateException { @SuppressWarnings("unchecked") Route<EventMessage, EventContext, Set<I>> casted = (Route<EventMessage, EventContext, Set<I>>) via; addRoute(eventType, casted); return this; } private  EventRouting(EventRoute<I, EventMessage> defaultRoute); @CanIgnoreReturnValue static EventRouting<I> withDefault(EventRoute<I, EventMessage> defaultRoute); static EventRouting<I> withDefaultByProducerId(); @Override final EventRoute<I, EventMessage> defaultRoute(); @CanIgnoreReturnValue EventRouting<I> replaceDefault(EventRoute<I, EventMessage> newDefault); @CanIgnoreReturnValue EventRouting<I> route(Class<E> eventType, EventRoute<I, ? super E> via); @CanIgnoreReturnValue EventRouting<I> routeStateUpdates(StateUpdateRouting<I> routing); Optional<EventRoute<I, M>> get(Class<M> eventClass);  }
@Test @DisplayName("not allow overwriting set route") void notOverwriteSetRoute() { eventRouting.route(UserRegistered.class, customRoute); assertThrows(IllegalStateException.class, () -> eventRouting.route(UserRegistered.class, customRoute)); }
@Test @DisplayName("remove previously set route") void removePreviouslySetRoute() { eventRouting.route(UserRegistered.class, customRoute); eventRouting.remove(UserRegistered.class); assertThat(eventRouting.routeFor(UserLoggedIn.class) .found()) .isFalse(); }
@Test @DisplayName("apply default route") void applyDefaultRoute() { eventRouting.route(UserRegistered.class, customRoute); Event event = GivenEvent.arbitrary(); Set<Long> ids = eventRouting.apply(event.enclosedMessage(), event.context()); assertThat(ids) .isEqualTo(DEFAULT_ROUTE); }
@Test @DisplayName("apply custom route") void applyCustomRoute() { eventRouting.route(UserRegistered.class, customRoute); UserRegistered eventMessage = UserRegistered .newBuilder() .setId(random(1, 100)) .build(); EventEnvelope event = EventEnvelope.of(GivenEvent.withMessage(eventMessage)); Set<Long> ids = eventRouting.apply(event.message(), event.context()); assertThat(ids) .isEqualTo(CUSTOM_ROUTE); }
@Test @DisplayName("allow routing via interface") void routesViaInterface() { eventRouting.route(UserLoggedOut.class, alternativeRoute) .route(LoginEvent.class, customRoute); EventContext ctx = EventContext.getDefaultInstance(); assertThat(eventRouting.apply(UserLoggedIn.getDefaultInstance(), ctx)) .isEqualTo(CUSTOM_ROUTE); assertThat(eventRouting.apply(UserLoggedOut.getDefaultInstance(), ctx)) .isEqualTo(ALT_ROUTE); }
@Test @DisplayName("prohibit adding specific type after interface routing") void overridingInterfaceRouting() { assertThrows(IllegalStateException.class, () -> eventRouting.route(UserAccountEvent.class, alternativeRoute) .route(AccountSuspended.class, customRoute) ); }
@Test @DisplayName("cache routing defined via interface") void cacheInterfaceRouting() { eventRouting.route(LoginEvent.class, customRoute); Match firstMatch = eventRouting.routeFor(UserLoggedIn.class); assertThat(firstMatch.found()) .isTrue(); assertThat(firstMatch.entryClass()) .isEqualTo(LoginEvent.class); Match secondMatch = eventRouting.routeFor(UserLoggedIn.class); assertThat(secondMatch.found()) .isTrue(); assertThat(secondMatch.entryClass()) .isEqualTo(UserLoggedIn.class); }
@Test @DisplayName("use default route when neither direct nor interface routing is defined") void useDefaultRoute() { eventRouting.route(UserAccountEvent.class, alternativeRoute); Match match = eventRouting.routeFor(UserLoggedIn.class); assertThat(match.found()) .isFalse(); Set<Long> route = eventRouting.apply(UserLoggedIn.getDefaultInstance(), EventContext.getDefaultInstance()); assertThat(route) .isEqualTo(DEFAULT_ROUTE); }