This is an automated email from the ASF dual-hosted git repository. juhan pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract-cn-async.git
commit 2e4f5c3939720b530b9517e08ff9d4de4a24ad66 Author: mgeiss <[email protected]> AuthorDate: Wed Apr 19 09:53:50 2017 +0200 created DelegatingTenantContextExecutor to assure tenant inheritance for pooled threads --- build.gradle | 4 +- .../config/AsyncProcessingJavaConfiguration.java | 4 +- .../core/DelegatingTenantContextCallable.java | 28 ++++++++++++ .../core/DelegatingTenantContextExecutor.java | 50 ++++++++++++++++++++++ .../core/DelegatingTenantContextRunnable.java | 26 +++++++++++ 5 files changed, 110 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 59040c4..9fb26c5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { repositories { - jcenter(); + jcenter() } dependencies { classpath 'io.spring.gradle:dependency-management-plugin:0.6.0.RELEASE' @@ -15,6 +15,7 @@ group 'io.mifos.core' version '0.1.0-BUILD-SNAPSHOT' ext.versions = [ + frameworklang : '0.1.0-BUILD-SNAPSHOT', springcontext : '4.3.3.RELEASE', springsecurity : '4.2.2.RELEASE', springboot : '1.4.1.RELEASE', @@ -40,6 +41,7 @@ repositories { dependencies { compile( + [group: 'io.mifos.core', name: 'lang', version: versions.frameworklang], [group: 'org.springframework', name: 'spring-context', version: versions.springcontext], [group: 'org.springframework.security', name: 'spring-security-web', version: versions.springsecurity], [group: 'com.google.code.findbugs', name: 'jsr305', version: versions.findbugs] diff --git a/src/main/java/io/mifos/core/async/config/AsyncProcessingJavaConfiguration.java b/src/main/java/io/mifos/core/async/config/AsyncProcessingJavaConfiguration.java index 1b966c0..272f37f 100644 --- a/src/main/java/io/mifos/core/async/config/AsyncProcessingJavaConfiguration.java +++ b/src/main/java/io/mifos/core/async/config/AsyncProcessingJavaConfiguration.java @@ -15,6 +15,7 @@ */ package io.mifos.core.async.config; +import io.mifos.core.async.core.DelegatingTenantContextExecutor; import io.mifos.core.async.util.AsyncConstants; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; @@ -53,7 +54,8 @@ public class AsyncProcessingJavaConfiguration executor.setThreadNamePrefix( this.env.getProperty(AsyncConstants.THREAD_NAME_PROP, AsyncConstants.THREAD_NAME_DEFAULT)); executor.initialize(); - return new DelegatingSecurityContextAsyncTaskExecutor(executor); + + return new DelegatingTenantContextExecutor(new DelegatingSecurityContextAsyncTaskExecutor(executor)); } @Override diff --git a/src/main/java/io/mifos/core/async/core/DelegatingTenantContextCallable.java b/src/main/java/io/mifos/core/async/core/DelegatingTenantContextCallable.java new file mode 100644 index 0000000..d473b24 --- /dev/null +++ b/src/main/java/io/mifos/core/async/core/DelegatingTenantContextCallable.java @@ -0,0 +1,28 @@ +package io.mifos.core.async.core; + +import io.mifos.core.lang.TenantContextHolder; + +import java.util.concurrent.Callable; + +public class DelegatingTenantContextCallable<V> implements Callable<V> { + + private final Callable<V> delegate; + private final String tenantIdentifier; + + DelegatingTenantContextCallable(final Callable<V> delegate, final String tenantIdentifier) { + super(); + this.delegate = delegate; + this.tenantIdentifier = tenantIdentifier; + } + + @Override + public V call() throws Exception { + try { + TenantContextHolder.clear(); + TenantContextHolder.setIdentifier(this.tenantIdentifier); + return this.delegate.call(); + } finally { + TenantContextHolder.clear(); + } + } +} diff --git a/src/main/java/io/mifos/core/async/core/DelegatingTenantContextExecutor.java b/src/main/java/io/mifos/core/async/core/DelegatingTenantContextExecutor.java new file mode 100644 index 0000000..67e6322 --- /dev/null +++ b/src/main/java/io/mifos/core/async/core/DelegatingTenantContextExecutor.java @@ -0,0 +1,50 @@ +package io.mifos.core.async.core; + +import io.mifos.core.lang.TenantContextHolder; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.security.task.DelegatingSecurityContextAsyncTaskExecutor; + +import java.util.concurrent.Callable; +import java.util.concurrent.Future; + +public class DelegatingTenantContextExecutor implements AsyncTaskExecutor { + + private final DelegatingSecurityContextAsyncTaskExecutor delegate; + + public DelegatingTenantContextExecutor(final DelegatingSecurityContextAsyncTaskExecutor delegate) { + super(); + this.delegate = delegate; + } + + @Override + public void execute(final Runnable task, final long startTimeout) { + final Runnable taskWrapper = this.wrap(task); + this.delegate.execute(taskWrapper, startTimeout); + } + + @Override + public Future<?> submit(final Runnable task) { + final Runnable taskWrapper = this.wrap(task); + return this.delegate.submit(taskWrapper); + } + + @Override + public <T> Future<T> submit(final Callable<T> task) { + final Callable<T> taskWrapper = this.wrap(task); + return this.delegate.submit(taskWrapper); + } + + @Override + public void execute(final Runnable task) { + final Runnable taskWrapper = this.wrap(task); + this.delegate.execute(taskWrapper); + } + + private Runnable wrap(final Runnable task) { + return new DelegatingTenantContextRunnable(task, TenantContextHolder.checkedGetIdentifier()); + } + + private <T> Callable<T> wrap(final Callable<T> task) { + return new DelegatingTenantContextCallable<>(task, TenantContextHolder.checkedGetIdentifier()); + } +} diff --git a/src/main/java/io/mifos/core/async/core/DelegatingTenantContextRunnable.java b/src/main/java/io/mifos/core/async/core/DelegatingTenantContextRunnable.java new file mode 100644 index 0000000..e0471d1 --- /dev/null +++ b/src/main/java/io/mifos/core/async/core/DelegatingTenantContextRunnable.java @@ -0,0 +1,26 @@ +package io.mifos.core.async.core; + +import io.mifos.core.lang.TenantContextHolder; + +public class DelegatingTenantContextRunnable implements Runnable { + + private final Runnable delegate; + private final String tenantIdentifier; + + DelegatingTenantContextRunnable(final Runnable delegate, final String tenantIdentifier) { + super(); + this.delegate = delegate; + this.tenantIdentifier = tenantIdentifier; + } + + @Override + public void run() { + try { + TenantContextHolder.clear(); + TenantContextHolder.setIdentifier(this.tenantIdentifier); + this.delegate.run(); + } finally { + TenantContextHolder.clear(); + } + } +}
