diff --git a/README.md b/README.md index 3ec5b65..4a9d234 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,37 @@ public void retryDLQ(@RequestParam String tenant, @RequestParam String processin Only JPA Dead letter queue and In-Memory queues are supported. +#### Deadline manager + +As of now, there is no plan to support deadline manager out of the box. +None of deadline manager implementation support multi-tenancy. +See Event scheduler section as alternative. + +#### Event scheduler + +You can use event scheduler to schedule events for specific tenant. +To do so, you need to inject `EventScheduler` and use it to schedule events. + + @Autowired + private EventScheduler eventScheduler; + + @EventHandler + public void eventHandler(Event event) { + ScheduledToken token = eventScheduler.schedule(Instant.now().plusDays(10), event); + //example of cancelation + eventScheduler.cancelSchedule(token); + } + +If you use scheduler from any message handler, it will automatically pick up tenant from message metadata, you dont need to specify it. +If you wish to use scheduler outside of message handlers, you need to wrap execution into tenant transaction where you specify tenant. + + new TenantWrappedTransactionManager( + TenantDescriptor.tenantWithId(tenantName)) + .executeInTransaction(() -> + eventScheduler.cancelSchedule(token) + ); + + ### Supported multi-tenant components Currently, supported multi-tenants components are as follows: diff --git a/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/AxonServerTenantProvider.java b/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/AxonServerTenantProvider.java index 76bfd36..ccce48a 100644 --- a/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/AxonServerTenantProvider.java +++ b/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/AxonServerTenantProvider.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -215,5 +215,12 @@ public Registration subscribe(MultiTenantAwareComponent bus) { @Override public void registerLifecycleHandlers(@Nonnull LifecycleRegistry lifecycle) { lifecycle.onStart(Phase.INSTRUCTION_COMPONENTS + 10, this::start); + lifecycle.onShutdown(Phase.INSTRUCTION_COMPONENTS + 10, this::shutdown); + } + + private void shutdown() { + registrationMap.forEach((tenant, registrationList) -> { + registrationList.forEach(Registration::cancel); + }); } } diff --git a/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/MultiTenancyAxonServerAutoConfiguration.java b/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/MultiTenancyAxonServerAutoConfiguration.java index 69fd9e9..0de496f 100644 --- a/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/MultiTenancyAxonServerAutoConfiguration.java +++ b/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/MultiTenancyAxonServerAutoConfiguration.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -108,17 +108,21 @@ public TenantCommandSegmentFactory tenantAxonServerCommandSegmentFactory( AxonServerConfiguration axonServerConfig, AxonServerConnectionManager connectionManager ) { - return tenantDescriptor -> AxonServerCommandBus.builder() - .localSegment(localSegment) - .serializer(messageSerializer) - .routingStrategy(routingStrategy) - .priorityCalculator(priorityCalculator) - .loadFactorProvider(loadFactorProvider) - .targetContextResolver(targetContextResolver) - .axonServerConnectionManager(connectionManager) - .configuration(axonServerConfig) - .defaultContext(tenantDescriptor.tenantId()) - .build(); + return tenantDescriptor -> { + AxonServerCommandBus commandBus = AxonServerCommandBus.builder() + .localSegment(localSegment) + .serializer(messageSerializer) + .routingStrategy(routingStrategy) + .priorityCalculator(priorityCalculator) + .loadFactorProvider(loadFactorProvider) + .targetContextResolver(targetContextResolver) + .axonServerConnectionManager(connectionManager) + .configuration(axonServerConfig) + .defaultContext(tenantDescriptor.tenantId()) + .build(); + commandBus.start(); + return commandBus; + }; } @@ -152,20 +156,23 @@ public TenantQuerySegmentFactory tenantAxonServerQuerySegmentFactory( new CorrelationDataInterceptor<>(config.correlationDataProviders()) ); - return AxonServerQueryBus.builder() - .axonServerConnectionManager(axonServerConnectionManager) - .configuration(axonServerConfig) - .localSegment(simpleQueryBus) - .updateEmitter( - ((MultiTenantQueryUpdateEmitter) multiTenantQueryUpdateEmitter) - .getTenant(tenantDescriptor) - ) - .messageSerializer(messageSerializer) - .genericSerializer(genericSerializer) - .priorityCalculator(priorityCalculator) - .targetContextResolver(targetContextResolver) - .defaultContext(tenantDescriptor.tenantId()) - .build(); + AxonServerQueryBus queryBus = AxonServerQueryBus.builder() + .axonServerConnectionManager(axonServerConnectionManager) + .configuration(axonServerConfig) + .localSegment(simpleQueryBus) + .updateEmitter( + ((MultiTenantQueryUpdateEmitter) multiTenantQueryUpdateEmitter) + .getTenant(tenantDescriptor) + ) + .messageSerializer(messageSerializer) + .genericSerializer(genericSerializer) + .priorityCalculator(priorityCalculator) + .targetContextResolver(targetContextResolver) + .defaultContext(tenantDescriptor.tenantId()) + .build(); + + queryBus.start(); + return queryBus; }; } @@ -214,11 +221,15 @@ public TenantEventSchedulerSegmentFactory tenantEventSchedulerSegmentFactory( AxonServerConnectionManager axonServerConnectionManager, Serializer serializer ) { - return tenant -> AxonServerEventScheduler.builder() - .connectionManager(axonServerConnectionManager) - .eventSerializer(serializer) - .defaultContext(tenant.tenantId()) - .build(); + return tenant -> { + AxonServerEventScheduler eventScheduler = AxonServerEventScheduler.builder() + .connectionManager(axonServerConnectionManager) + .eventSerializer(serializer) + .defaultContext(tenant.tenantId()) + .build(); + eventScheduler.start(); + return eventScheduler; + }; } @Bean diff --git a/multitenancy-spring-boot-starter/pom.xml b/multitenancy-spring-boot-starter/pom.xml index 8b8ebc9..51d1188 100644 --- a/multitenancy-spring-boot-starter/pom.xml +++ b/multitenancy-spring-boot-starter/pom.xml @@ -52,7 +52,7 @@ 3.1.1 3.1.0 3.1.1 - 3.6.0 + 3.6.2 3.3.1 diff --git a/multitenancy/src/main/java/org/axonframework/extensions/multitenancy/components/scheduling/TenantEventSchedulerSegmentFactory.java b/multitenancy/src/main/java/org/axonframework/extensions/multitenancy/components/scheduling/TenantEventSchedulerSegmentFactory.java index e7f856a..25042b0 100644 --- a/multitenancy/src/main/java/org/axonframework/extensions/multitenancy/components/scheduling/TenantEventSchedulerSegmentFactory.java +++ b/multitenancy/src/main/java/org/axonframework/extensions/multitenancy/components/scheduling/TenantEventSchedulerSegmentFactory.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,6 +22,7 @@ /** * Factory for creating {@link EventScheduler} segments for a given {@link TenantDescriptor}. + * After a segment is created, it may be started automatically by the factory. * * @author Stefan Dragisic * @since 4.9.0 diff --git a/pom.xml b/pom.xml index 13fcc3f..bd8b1ea 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 3.1.0 3.1.1 3.3.0 - 3.6.0 + 3.6.2 3.0.1 3.3.0 3.1.2