/** * Registers the given {@code beans} as event handlers with the Event Handler Configuration. The beans are sorted * (see {@link AnnotationAwareOrderComparator}) before registering them to the configuration. * * @param beans the beans to register */ public void setEventHandlers(List<Object> beans) { AnnotationAwareOrderComparator.sort(beans); beans.forEach(b -> eventProcessingConfigurer.registerEventHandler(c -> b)); }
/** * Registers a Saga with default configuration within this Configurer. * * @param sagaType the type of Saga * @param <T> the type of Saga * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default <T> EventProcessingConfigurer registerSaga(Class<T> sagaType) { return registerSaga(sagaType, c -> {}); }
/** * Configures a rule to assign Event Handler beans that match the given {@code criteria} to the Processing Group * with given {@code name}, with neutral priority (value 0). * <p> * Note that, when beans match multiple criteria for different Processing Groups with equal priority, the outcome is * undefined. * * @param processingGroup a {@link String} specifying the name of a processing group to assign matching Event * Handlers or Sagas to * @param criteria a {@link Predicate} defining the criteria for an Event Handler or Saga to match * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer assignHandlerTypesMatching(String processingGroup, Predicate<Class<?>> criteria) { return assignHandlerTypesMatching(processingGroup, 0, criteria); }
/** * Registers the {@code processingGroup} name to assign Event Handler and Saga beans to when no other, more * explicit, rule matches and no {@link ProcessingGroup} annotation is found. * * @param processingGroup a {@link String} specifying the name of a processing group * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer byDefaultAssignTo(String processingGroup) { byDefaultAssignHandlerTypesTo(c -> processingGroup); return byDefaultAssignHandlerInstancesTo(o -> processingGroup); }
@SuppressWarnings("unchecked") @Autowired public void configureEventHandling(EventProcessingConfigurer eventProcessingConfigurer, ApplicationContext applicationContext) { eventProcessorProperties.getProcessors().forEach((k, v) -> { Function<Configuration, SequencingPolicy<? super EventMessage<?>>> sequencingPolicy = resolveSequencingPolicy(applicationContext, v); eventProcessingConfigurer.registerSequencingPolicy(k, sequencingPolicy); if (v.getMode() == EventProcessorProperties.Mode.TRACKING) { TrackingEventProcessorConfiguration config = TrackingEventProcessorConfiguration .forParallelProcessing(v.getThreadCount()) .andBatchSize(v.getBatchSize()) .andInitialSegmentsCount(v.getInitialSegmentCount()); Function<Configuration, StreamableMessageSource<TrackedEventMessage<?>>> messageSource = resolveMessageSource(applicationContext, v); eventProcessingConfigurer.registerTrackingEventProcessor(k, messageSource, c -> config); } else { if (v.getSource() == null) { eventProcessingConfigurer.registerSubscribingEventProcessor(k); } else { eventProcessingConfigurer.registerSubscribingEventProcessor(k, c -> applicationContext .getBean(v.getSource(), SubscribableMessageSource.class)); } } }); }
@SuppressWarnings("unchecked") private void registerSagaBeanDefinitions(EventProcessingConfigurer configurer) { String[] sagas = beanFactory.getBeanNamesForAnnotation(Saga.class); for (String saga : sagas) { Saga sagaAnnotation = beanFactory.findAnnotationOnBean(saga, Saga.class); Class sagaType = beanFactory.getType(saga); ProcessingGroup processingGroupAnnotation = beanFactory.findAnnotationOnBean(saga, ProcessingGroup.class); if (processingGroupAnnotation != null && !"".equals(processingGroupAnnotation.value())) { configurer.assignHandlerTypesMatching(processingGroupAnnotation.value(), sagaType::equals); } configurer.registerSaga(sagaType, sagaConfigurer -> { if (sagaAnnotation != null && !"".equals(sagaAnnotation.sagaStore())) { sagaConfigurer.configureSagaStore(c -> beanFactory.getBean(sagaAnnotation.sagaStore(), SagaStore.class)); } }); } }
@Before public void setUp() { EventStore eventStore = spy(EmbeddedEventStore.builder() .storageEngine(new InMemoryEventStorageEngine()) .build()); Configurer configurer = DefaultConfigurer.defaultConfiguration(); configurer.eventProcessing() .usingSubscribingEventProcessors() .registerSaga(MySaga.class); configuration = configurer.configureEventStore(c -> eventStore) .configureAggregate(MyAggregate.class) .registerComponent(DeadlineManager.class, this::buildDeadlineManager) .start(); published = new CopyOnWriteArrayList<>(); configuration.eventBus().subscribe(msgs -> msgs.forEach(msg -> published.add(msg.getPayload()))); }
/** * Registers a {@link org.axonframework.eventhandling.TrackingEventProcessor} with given {@code name} and {@code * source} within this Configurer. * * @param name a {@link String} specifying the name of the {@link org.axonframework.eventhandling.TrackingEventProcessor} * being registered * @param source a {@link Function} that builds a {@link StreamableMessageSource} * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer registerTrackingEventProcessor(String name, Function<Configuration, StreamableMessageSource<TrackedEventMessage<?>>> source) { return registerTrackingEventProcessor(name, source, c -> c.getComponent(TrackingEventProcessorConfiguration.class, TrackingEventProcessorConfiguration::forSingleThreadedProcessing)); }
/** * Registers a {@link org.axonframework.eventhandling.SubscribingEventProcessor} with given {@code name} within this * Configurer. * * @param name a {@link String} specyfing the name of the {@link org.axonframework.eventhandling.SubscribingEventProcessor} * being registered * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer registerSubscribingEventProcessor(String name) { return registerSubscribingEventProcessor(name, Configuration::eventBus); }
/** * Registers a builder {@link Function} to create the {@link MessageMonitor} for a {@link EventProcessor} of the * given {@code name}. * * @param eventProcessorName a {@link String} specifying the name of an {@link EventProcessor} * @param messageMonitorBuilder a builder {@link Function} to create a {@link MessageMonitor} * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer registerMessageMonitor(String eventProcessorName, Function<Configuration, MessageMonitor<Message<?>>> messageMonitorBuilder) { return registerMessageMonitorFactory( eventProcessorName, (configuration, componentType, componentName) -> messageMonitorBuilder.apply(configuration) ); }
/** * Configures a rule to assign Event Handler beans that match the given {@code criteria} to the Processing Group * with given {@code name}, with neutral priority (value 0). * <p> * Note that, when beans match multiple criteria for different Processing Groups with equal priority, the outcome is * undefined. * * @param processingGroup a {@link String} specifying the name of a processing group to assign matching Event * Handlers to * @param criteria a {@link Predicate} defining the criteria for an Event Handler to match * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer assignHandlerInstancesMatching(String processingGroup, Predicate<Object> criteria) { return assignHandlerInstancesMatching(processingGroup, 0, criteria); }
@SuppressWarnings("unchecked") @Autowired public void configureEventHandling(EventProcessingConfigurer eventProcessingConfigurer, ApplicationContext applicationContext) { eventProcessorProperties.getProcessors().forEach((k, v) -> { Function<Configuration, SequencingPolicy<? super EventMessage<?>>> sequencingPolicy = resolveSequencingPolicy(applicationContext, v); eventProcessingConfigurer.registerSequencingPolicy(k, sequencingPolicy); if (v.getMode() == EventProcessorProperties.Mode.TRACKING) { TrackingEventProcessorConfiguration config = TrackingEventProcessorConfiguration .forParallelProcessing(v.getThreadCount()) .andBatchSize(v.getBatchSize()) .andInitialSegmentsCount(v.getInitialSegmentCount()); Function<Configuration, StreamableMessageSource<TrackedEventMessage<?>>> messageSource = resolveMessageSource(applicationContext, v); eventProcessingConfigurer.registerTrackingEventProcessor(k, messageSource, c -> config); } else { if (v.getSource() == null) { eventProcessingConfigurer.registerSubscribingEventProcessor(k); } else { eventProcessingConfigurer.registerSubscribingEventProcessor(k, c -> applicationContext .getBean(v.getSource(), SubscribableMessageSource.class)); } } }); }
/** * Registers a {@link org.axonframework.eventhandling.TrackingEventProcessor} with given {@code name} within this * Configurer. * * @param name a {@link String} specifying the name of the {@link org.axonframework.eventhandling.TrackingEventProcessor} * being registered * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer registerTrackingEventProcessor(String name) { return registerTrackingEventProcessor(name, c -> { EventBus eventBus = c.eventBus(); if (!(eventBus instanceof StreamableMessageSource)) { throw new AxonConfigurationException("Cannot create Tracking Event Processor with name '" + name + "'. " + "The available EventBus does not support tracking processors."); } //noinspection unchecked return (StreamableMessageSource) eventBus; }); }
/** * Registers the {@code processingGroup} name to assign Event Handler and Saga beans to when no other, more * explicit, rule matches and no {@link ProcessingGroup} annotation is found. * * @param processingGroup a {@link String} specifying the name of a processing group * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer byDefaultAssignTo(String processingGroup) { byDefaultAssignHandlerTypesTo(c -> processingGroup); return byDefaultAssignHandlerInstancesTo(o -> processingGroup); }
/** * Registers a {@link org.axonframework.eventhandling.SubscribingEventProcessor} with given {@code name} within this * Configurer. * * @param name a {@link String} specyfing the name of the {@link org.axonframework.eventhandling.SubscribingEventProcessor} * being registered * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer registerSubscribingEventProcessor(String name) { return registerSubscribingEventProcessor(name, Configuration::eventBus); }
/** * Registers a builder {@link Function} to create the {@link MessageMonitor} for a {@link EventProcessor} of the * given {@code name}. * * @param eventProcessorName a {@link String} specifying the name of an {@link EventProcessor} * @param messageMonitorBuilder a builder {@link Function} to create a {@link MessageMonitor} * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer registerMessageMonitor(String eventProcessorName, Function<Configuration, MessageMonitor<Message<?>>> messageMonitorBuilder) { return registerMessageMonitorFactory( eventProcessorName, (configuration, componentType, componentName) -> messageMonitorBuilder.apply(configuration) ); }
/** * Configures a rule to assign Event Handler beans that match the given {@code criteria} to the Processing Group * with given {@code name}, with neutral priority (value 0). * <p> * Note that, when beans match multiple criteria for different Processing Groups with equal priority, the outcome is * undefined. * * @param processingGroup a {@link String} specifying the name of a processing group to assign matching Event * Handlers to * @param criteria a {@link Predicate} defining the criteria for an Event Handler to match * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer assignHandlerInstancesMatching(String processingGroup, Predicate<Object> criteria) { return assignHandlerInstancesMatching(processingGroup, 0, criteria); }
/** * Registers a {@link Function} that builds an Event Handler instance. * * @param eventHandlerBuilder a {@link Function} that builds an Event Handler instance. * @return the current instance of the Configurer, for chaining purposes. */ default Configurer registerEventHandler(Function<Configuration, Object> eventHandlerBuilder) { eventProcessing().registerEventHandler(eventHandlerBuilder); return this; }
/** * Registers a Saga with default configuration within this Configurer. * * @param sagaType the type of Saga * @param <T> the type of Saga * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default <T> EventProcessingConfigurer registerSaga(Class<T> sagaType) { return registerSaga(sagaType, c -> {}); }
/** * Registers a {@link org.axonframework.eventhandling.TrackingEventProcessor} with given {@code name} and {@code * source} within this Configurer. * * @param name a {@link String} specifying the name of the {@link org.axonframework.eventhandling.TrackingEventProcessor} * being registered * @param source a {@link Function} that builds a {@link StreamableMessageSource} * @return the current {@link EventProcessingConfigurer} instance, for fluent interfacing */ default EventProcessingConfigurer registerTrackingEventProcessor(String name, Function<Configuration, StreamableMessageSource<TrackedEventMessage<?>>> source) { return registerTrackingEventProcessor(name, source, c -> c.getComponent(TrackingEventProcessorConfiguration.class, TrackingEventProcessorConfiguration::forSingleThreadedProcessing)); }