@Override public void afterPropertiesSet() { config = configurer.buildConfiguration(); }
/** * Configures an Aggregate using default settings. This means the aggregate is expected to be Event Sourced if an * Event Store present in the configuration. Otherwise, an explicit repository must be configured and the * {@link #configureAggregate(AggregateConfiguration)} must be used to register the aggregate. * * @param aggregate The aggregate type to register with the Configuration * @param <A> The type of aggregate * @return the current instance of the Configurer, for chaining purposes */ default <A> Configurer configureAggregate(Class<A> aggregate) { return configureAggregate(AggregateConfigurer.defaultConfiguration(aggregate)); }
@Override public void configureModule(Configurer configurer) { configurer.registerComponent(AxonServerConfiguration.class, c -> new AxonServerConfiguration()); configurer.registerComponent(AxonServerConnectionManager.class, c -> buildAxonServerConnectionManager(c)); configurer.configureEventStore(this::buildEventStore); configurer.configureCommandBus(this::buildCommandBus); configurer.configureQueryBus(this::buildQueryBus); configurer.registerModule(new EventProcessorInfoConfiguration()); configurer.registerComponent(TokenStore.class, c -> { logger.warn("BEWARE! Falling back to an in-memory token store. It is highly recommended to configure a " + "persistent implementation, based on the activity of the handler."); return new InMemoryTokenStore(); }); }
@Test public void testDispatchCommand() { Configuration c = DefaultConfigurer.defaultConfiguration() .configureAggregate(TestAggregate.class) .registerCommandHandler(x -> new Handler()) .configureEmbeddedEventStore(x -> new InMemoryEventStorageEngine()) .buildConfiguration(); c.start(); CommandGateway gw = c.commandGateway(); gw.sendAndWait(new TestCommand()); }
configurer.registerComponent(ParameterResolverFactory.class, c -> beanFactory .getBean(parameterResolver.getBeanName(), ParameterResolverFactory.class)); configurer.registerHandlerDefinition((c, clazz) -> beanFactory .getBean(handlerDefinition.getBeanName(), HandlerDefinition.class)); .ifPresent(commandBus -> configurer.configureCommandBus(c -> getBean(commandBus, c))); findComponent(QueryBus.class) .ifPresent(queryBus -> configurer.configureQueryBus(c -> getBean(queryBus, c))); findComponent(QueryUpdateEmitter.class) .ifPresent(queryUpdateEmitter -> configurer.configureQueryUpdateEmitter(c -> getBean(queryUpdateEmitter, c))); findComponent(EventStorageEngine.class) .ifPresent(ese -> configurer.configureEmbeddedEventStore(c -> getBean(ese, c))); findComponent(EventBus.class).ifPresent(eventBus -> configurer.configureEventBus(c -> getBean(eventBus, c))); findComponent(Serializer.class) .ifPresent(serializer -> configurer.configureSerializer(c -> getBean(serializer, c))); findComponent(Serializer.class, "eventSerializer") .ifPresent(eventSerializer -> configurer.configureEventSerializer(c -> getBean(eventSerializer, c))); findComponent(Serializer.class, "messageSerializer").ifPresent( messageSerializer -> configurer.configureMessageSerializer(c -> getBean(messageSerializer, c))); findComponent(TokenStore.class) .ifPresent(tokenStore -> configurer.registerComponent(TokenStore.class, c -> getBean(tokenStore, c))); try { findComponent(PlatformTransactionManager.class).ifPresent( ptm -> configurer.configureTransactionManager(c -> new SpringTransactionManager(getBean(ptm, c)))); } catch (NoClassDefFoundError error) { .ifPresent(tm -> configurer.configureTransactionManager(c -> getBean(tm, c))); findComponent(SagaStore.class)
@Test public void testQueryHandlerAndEventHandlerCleanlyShutdown() { UserSummaryProjection userSummaryProjection = new UserSummaryProjection(); Configurer configurer = DefaultConfigurer.defaultConfiguration(); configurer.configureCommandBus(c -> SimpleCommandBus.builder().build()) .configureQueryBus(c -> SimpleQueryBus.builder().build()) .configureEmbeddedEventStore(c -> new InMemoryEventStorageEngine()) .registerQueryHandler(c -> userSummaryProjection); configurer.eventProcessing() .registerEventHandler(c -> userSummaryProjection); Configuration configuration = configurer.buildConfiguration(); configuration.start(); configuration.shutdown(); }
@Before public void setUp() { Configuration configuration = DefaultConfigurer.defaultConfiguration() .configureEmbeddedEventStore(c -> new InMemoryEventStorageEngine()) .configureAggregate(StubAggregate.class) .buildConfiguration(); configuration.start(); commandGateway = configuration.commandGateway(); }
@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()))); }
.configureCommandBus(conf -> commandBus) .configureEventStore(conf -> eventStore) .configureAggregate(User.class) .configureAggregate(Company.class) .configureAggregate(Portfolio.class) .configureAggregate(Transaction.class) .configureAggregate(OrderBook.class) .registerModule(queryModelConfiguration) .registerModule(commandPublisherConfiguration) .registerModule(SagaConfiguration.subscribingSagaManager(SellTradeManagerSaga.class)) .registerModule(SagaConfiguration.subscribingSagaManager(BuyTradeManagerSaga.class)) .buildConfiguration(); configuration.start(); return configuration;
@SneakyThrows public static void disabledMain(String[] args) { final Configuration configuration = DefaultConfigurer.defaultConfiguration() .configureAggregate(Entrance.class) .configureAggregate(Guest.class) .configureEmbeddedEventStore(c -> new InMemoryEventStorageEngine()) .configureCommandBus(c -> new AsynchronousCommandBus()) .buildConfiguration(); configuration.start(); final CommandBus commandBus = configuration.commandBus(); commandBus.dispatch(asCommandMessage(new RegisterEntranceCommand("main"))); commandBus.dispatch(asCommandMessage(new UnlockEntranceCommand("main"))); commandBus.dispatch(asCommandMessage(new UnregisterEntranceCommand("main")) ); TimeUnit.SECONDS.sleep(1L); } }
/** * Configures the given Transaction Manager to use in this configuration. The builder receives the Configuration as * input and is expected to return a fully initialized {@link TransactionManager} * instance. * * @param transactionManagerBuilder The builder function for the {@link TransactionManager} * @return the current instance of the Configurer, for chaining purposes */ default Configurer configureTransactionManager(Function<Configuration, TransactionManager> transactionManagerBuilder) { return registerComponent(TransactionManager.class, transactionManagerBuilder); }
return new DefaultConfigurer() .registerComponent(EntityManagerProvider.class, c -> entityManagerProvider) .registerComponent(TransactionManager.class, c -> transactionManager) .configureEmbeddedEventStore( c -> JpaEventStorageEngine.builder() .snapshotSerializer(c.serializer()) .build() .registerComponent(TokenStore.class, c -> JpaTokenStore.builder() .entityManagerProvider(c.getComponent(EntityManagerProvider.class)) .serializer(c.serializer()) .build()) .registerComponent(SagaStore.class, c -> JpaSagaStore.builder() .entityManagerProvider(c.getComponent(EntityManagerProvider.class))
/** * Configures the builder function to create the Message Monitor for the Message processing components in this * configuration that match the given componentType, unless more specific configuration based on both type and name * is available. * <p> * <p>A component matches componentType if componentType is assignable from the component's class. If a component * matches multiple types, and the types derive from each other, the configuration from the most derived type is * used. If the matching types do not derive from each other, the result is unspecified.</p> * <p> * <p>For example: in case a monitor is configured for {@link CommandBus} and another monitor is configured for * {@link org.axonframework.commandhandling.SimpleCommandBus SimpleCommandBus}), components of type * {@link org.axonframework.commandhandling.AsynchronousCommandBus AsynchronousCommandBus} will use the monitor * configured for the SimpleCommandBus.</p> * <p> * <p>A component's name matches componentName if they are identical; i.e. they are compared case sensitively.</p> * * @param componentType The declared type of the component * @param messageMonitorBuilder The builder function to use * @return the current instance of the Configurer, for chaining purposes */ default Configurer configureMessageMonitor(Class<?> componentType, Function<Configuration, MessageMonitor<Message<?>>> messageMonitorBuilder) { return configureMessageMonitor(componentType, (configuration, type, name) -> messageMonitorBuilder.apply(configuration)); }
/** * Registers a command handler bean with this configuration. The bean may be of any type. The actual command handler * methods will be detected based on the annotations present on the bean's methods. * <p> * The builder function receives the Configuration as input, and is expected to return a fully initialized instance * of the command handler bean. * * @param annotatedCommandHandlerBuilder The builder function of the Command Handler bean * @return the current instance of the Configurer, for chaining purposes */ default Configurer registerCommandHandler(Function<Configuration, Object> annotatedCommandHandlerBuilder) { return registerCommandHandler(0, annotatedCommandHandlerBuilder); }
/** * Locates the {@link EventProcessingConfigurer} registered as a module with this Configurer and provides it to the * given consumer for configuration. If there aren't any pre-registered instances of * {@link EventProcessingConfigurer}, it will create an {@link EventProcessingModule} and register it as a module. * If there are multiple, an {@link AxonConfigurationException} is thrown. * * This method is identical to using {@link #eventProcessing()}, except that this variant allows for easier fluent * interfacing. * * @param eventProcessingConfigurer a consumer to configure the * @return an instance of Event Processing Configurer * * @throws AxonConfigurationException thrown if there are multiple {@link EventProcessingConfigurer}s */ default Configurer eventProcessing(Consumer<EventProcessingConfigurer> eventProcessingConfigurer) throws AxonConfigurationException { eventProcessingConfigurer.accept(eventProcessing()); return this; }
@Test public void testStagedEventsLoadInCorrectOrder() { Configuration config = DefaultConfigurer.defaultConfiguration() .configureAggregate(TestAggregate.class) .registerCommandHandler(x -> new Handler()) .configureEmbeddedEventStore(x -> new InMemoryEventStorageEngine()) .registerComponent(List.class, c -> new CopyOnWriteArrayList()) .buildConfiguration(); config.start(); CommandGateway gw = config.commandGateway(); gw.sendAndWait(new Create("1")); gw.sendAndWait(new Test1()); gw.sendAndWait(new ShowItems("1", "from-eventstore")); config.shutdown(); assertEquals(asList("pre-rollback-first","pre-rollback-second", "post-rollback-first","post-rollback-second", "from-eventstore-first", "from-eventstore-second"), config.getComponent(List.class)); }
public static void main(String args[]){ Configuration config = DefaultConfigurer.defaultConfiguration() .configureAggregate(BankAccount.class) .configureEmbeddedEventStore(c -> new InMemoryEventStorageEngine()) .buildConfiguration(); config.start(); AccountId id = new AccountId(); config.commandGateway().send(new CreateAccountCommand(id, "MyAccount",1000)); config.commandGateway().send(new WithdrawMoneyCommand(id, 500)); config.commandGateway().send(new WithdrawMoneyCommand(id, 500)); /*config.commandBus().dispatch(asCommandMessage(new CreateAccountCommand(id, "MyAccount", 1000))); config.commandBus().dispatch(asCommandMessage(new WithdrawMoneyCommand(id, 500)));*/ }
/** * Configures the given Resource Injector to use for Sagas in this configuration. The builder receives the * Configuration as input and is expected to return a fully initialized {@link ResourceInjector} instance. * * @param resourceInjectorBuilder The builder function for the {@link ResourceInjector} * @return the current instance of the Configurer, for chaining purposes */ default Configurer configureResourceInjector(Function<Configuration, ResourceInjector> resourceInjectorBuilder) { return registerComponent(ResourceInjector.class, resourceInjectorBuilder); }
return new DefaultConfigurer() .registerComponent(EntityManagerProvider.class, c -> entityManagerProvider) .registerComponent(TransactionManager.class, c -> transactionManager) .configureEmbeddedEventStore(c -> new JpaEventStorageEngine( c.serializer(), c.upcasterChain(), null, null, true )) .registerComponent(TokenStore.class, c -> new JpaTokenStore(c.getComponent(EntityManagerProvider.class), c.serializer())) .registerComponent(SagaStore.class, c -> new JpaSagaStore(c.serializer(), c.getComponent(EntityManagerProvider.class)));
/** * Configures the builder function to create the Message Monitor for the Message processing components in this * configuration that match the given class and name. * <p> * <p>A component matches componentType if componentType is assignable from the component's class. If a component * matches multiple types, and the types derive from each other, the configuration from the most derived type is * used. If the matching types do not derive from each other, the result is unspecified.</p> * <p> * <p>For example: in case a monitor is configured for {@link CommandBus} and another monitor is configured for * {@link org.axonframework.commandhandling.SimpleCommandBus SimpleCommandBus}), components of type * {@link org.axonframework.commandhandling.AsynchronousCommandBus AsynchronousCommandBus} will use the monitor * configured for the SimpleCommandBus.</p> * <p> * <p>A component's name matches componentName if they are identical; i.e. they are compared case sensitively.</p> * * @param componentType The declared type of the component * @param componentName The name of the component * @param messageMonitorBuilder The builder function to use * @return the current instance of the Configurer, for chaining purposes */ default Configurer configureMessageMonitor(Class<?> componentType, String componentName, Function<Configuration, MessageMonitor<Message<?>>> messageMonitorBuilder) { return configureMessageMonitor(componentType, componentName, (configuration, type, name) -> messageMonitorBuilder.apply(configuration)); }