From a3789ba1be46cea8ccaf9a5927302d2f29414d2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:37:47 +0000 Subject: [PATCH 1/4] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.0 to 3.6.2 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.0 to 3.6.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.0...maven-javadoc-plugin-3.6.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> --- multitenancy-spring-boot-starter/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/multitenancy-spring-boot-starter/pom.xml b/multitenancy-spring-boot-starter/pom.xml index 06e4246..79671ec 100644 --- a/multitenancy-spring-boot-starter/pom.xml +++ b/multitenancy-spring-boot-starter/pom.xml @@ -52,7 +52,7 @@ <maven-deploy.version>3.1.1</maven-deploy.version> <maven-gpg.version>3.1.0</maven-gpg.version> <maven-install.version>3.1.1</maven-install.version> - <maven-javadoc.version>3.6.0</maven-javadoc.version> + <maven-javadoc.version>3.6.2</maven-javadoc.version> <maven-resources.version>3.3.1</maven-resources.version> </properties> diff --git a/pom.xml b/pom.xml index 4dc3ec8..5cecd01 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ <maven-gpg.version>3.1.0</maven-gpg.version> <maven-install.version>3.1.1</maven-install.version> <maven-jar.version>3.3.0</maven-jar.version> - <maven-javadoc.version>3.6.0</maven-javadoc.version> + <maven-javadoc.version>3.6.2</maven-javadoc.version> <maven-release.version>3.0.1</maven-release.version> <maven-source.version>3.3.0</maven-source.version> <maven-surefire.version>3.1.2</maven-surefire.version> From 764142932c8e1eb90fa3a0fb011dc879b289288a Mon Sep 17 00:00:00 2001 From: Stefan <91stefan@gmail.com> Date: Wed, 15 Nov 2023 13:43:35 +0100 Subject: [PATCH 2/4] Start Axon Server Tenant components before using them --- README.md | 31 ++++++++ ...ltiTenancyAxonServerAutoConfiguration.java | 74 +++++++++++-------- 2 files changed, 74 insertions(+), 31 deletions(-) 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/MultiTenancyAxonServerAutoConfiguration.java b/multitenancy-spring-boot-autoconfigure/src/main/java/org/axonframework/extensions/multitenancy/autoconfig/MultiTenancyAxonServerAutoConfiguration.java index 69fd9e9..6bbfa20 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 @@ -233,6 +244,7 @@ public EventProcessorInfoConfiguration processorInfoConfiguration( c.getComponent(AxonServerConfiguration.class) ); tenantProvider.subscribe(controlService); + controlService.start(); return controlService; }); } From f9a55b68b9f3922d16edf5c61fc0e20cb13bafde Mon Sep 17 00:00:00 2001 From: Stefan <91stefan@gmail.com> Date: Wed, 22 Nov 2023 09:57:28 +0100 Subject: [PATCH 3/4] add a comment about tenant segment creation, and a shutdown hook in tenant provided --- .../autoconfig/AxonServerTenantProvider.java | 9 ++++++++- .../scheduling/TenantEventSchedulerSegmentFactory.java | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) 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/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 From 7e6dd156a8a4e8c95eadd56a6dc6e14cba6dc50a Mon Sep 17 00:00:00 2001 From: Stefan <91stefan@gmail.com> Date: Wed, 22 Nov 2023 10:26:29 +0100 Subject: [PATCH 4/4] The get invocation of the eventProcessorControlService variable is retrieving the MultiTenantEventProcessorControlService from a Component. Due to this, its lifecycle methods should be invoked. --- .../autoconfig/MultiTenancyAxonServerAutoConfiguration.java | 1 - 1 file changed, 1 deletion(-) 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 6bbfa20..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 @@ -244,7 +244,6 @@ public EventProcessorInfoConfiguration processorInfoConfiguration( c.getComponent(AxonServerConfiguration.class) ); tenantProvider.subscribe(controlService); - controlService.start(); return controlService; }); }