You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/12/04 22:21:26 UTC
[isis] branch master updated: ISIS-2464: SudoService overhaul
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 5b7ba8b ISIS-2464: SudoService overhaul
5b7ba8b is described below
commit 5b7ba8b34b71faa91522ee31ce047a2cbcff0922
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Dec 4 23:21:08 2020 +0100
ISIS-2464: SudoService overhaul
allows full control of the ExecutionContext to use for sudo, based on
the current ExecutionContext that sits on top of the current thread's
stack; we use the wither idiom here to create copies of
ExecutionContexts
---
.../isis/applib/services/sudo/SudoService.java | 16 ++++++-----
.../command/CommandExecutorServiceDefault.java | 4 +--
.../runtimeservices/sudo/SudoServiceDefault.java | 31 +++++++++++++---------
3 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java b/api/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java
index 72518eb..edff67b 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/sudo/SudoService.java
@@ -19,9 +19,10 @@
package org.apache.isis.applib.services.sudo;
import java.util.concurrent.Callable;
+import java.util.function.UnaryOperator;
+import org.apache.isis.applib.services.iactn.ExecutionContext;
import org.apache.isis.applib.services.user.RoleMemento;
-import org.apache.isis.applib.services.user.UserMemento;
import org.apache.isis.applib.services.user.UserService;
import lombok.NonNull;
@@ -48,23 +49,25 @@ public interface SudoService {
// end::refguide[]
/**
* Executes the supplied block, with the {@link UserService} returning the specified user.
+ * @param sudoMapper - maps the current {@link ExecutionContext} to the sudo one
* @since 2.0
*/
// tag::refguide[]
<T> T call( // <.>
- @NonNull UserMemento user,
+ @NonNull UnaryOperator<ExecutionContext> sudoMapper,
@NonNull Callable<T> supplier);
// end::refguide[]
/**
* Executes the supplied block, with the {@link UserService} returning the specified user.
+ * @param sudoMapper - maps the current {@link ExecutionContext} to the sudo one
* @since 2.0
*/
// tag::refguide[]
default void run( // <.>
- final @NonNull UserMemento user,
+ final @NonNull UnaryOperator<ExecutionContext> sudoMapper,
final @NonNull Runnable runnable) {
- call(user, ()->{runnable.run(); return null;});
+ call(sudoMapper, ()->{runnable.run(); return null;});
}
// end::refguide[]
@@ -73,14 +76,13 @@ public interface SudoService {
/**
* Allows the {@link SudoService} to notify other services/components that the effective user has been changed.
* @since 2.0
- * @deprecated its better to subscribe to interaction life-cycle events on the event bus
*/
// tag::refguide-1[]
interface Listener {
- void beforeCall(@NonNull UserMemento user); // <.>
+ void beforeCall(@NonNull ExecutionContext before, @NonNull ExecutionContext after); // <.>
- void afterCall(); // <.>
+ void afterCall(@NonNull ExecutionContext before, @NonNull ExecutionContext after); // <.>
}
// end::refguide-1[]
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
index 25598e2..2f441af 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -151,8 +151,8 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
val result = transactionService.executeWithinTransaction(
() -> sudoPolicy == SudoPolicy.SWITCH
? sudoService.call(
- UserMemento.ofName(dto.getUser()),
- () -> doExecuteCommand(dto))
+ context->context.withUser(UserMemento.ofName(dto.getUser())),
+ () -> doExecuteCommand(dto))
: doExecuteCommand(dto));
return handleOutcomeAndSetCompletedAt(commandUpdater, result, null);
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/sudo/SudoServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/sudo/SudoServiceDefault.java
index 759e986..fe41e68 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/sudo/SudoServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/sudo/SudoServiceDefault.java
@@ -20,6 +20,7 @@
package org.apache.isis.core.runtimeservices.sudo;
import java.util.concurrent.Callable;
+import java.util.function.UnaryOperator;
import javax.inject.Inject;
import javax.inject.Named;
@@ -30,9 +31,9 @@ import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.services.iactn.ExecutionContext;
import org.apache.isis.applib.services.registry.ServiceRegistry;
import org.apache.isis.applib.services.sudo.SudoService;
-import org.apache.isis.applib.services.user.UserMemento;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.core.runtime.iactn.InteractionFactory;
import org.apache.isis.core.runtime.iactn.InteractionTracker;
@@ -66,36 +67,42 @@ public class SudoServiceDefault implements SudoService {
// -- IMPLEMENTATION
@Override
- public <T> T call(final @NonNull UserMemento sudoUser, final @NonNull Callable<T> callable) {
+ public <T> T call(
+ final @NonNull UnaryOperator<ExecutionContext> sudoMapper,
+ final @NonNull Callable<T> callable) {
- val currentinteractionLayer = interactionTracker.currentInteractionLayerElseFail();
- val currentExecutionContext = currentinteractionLayer.getExecutionContext();
- val sudoExecutionContext = currentExecutionContext.withUser(sudoUser);
+ val currentInteractionLayer = interactionTracker.currentInteractionLayerElseFail();
+ val currentExecutionContext = currentInteractionLayer.getExecutionContext();
+ val sudoExecutionContext = sudoMapper.apply(currentExecutionContext);
- val sodoSession = currentinteractionLayer
+ val sodoSession = currentInteractionLayer
.getAuthenticationSession()
.withExecutionContext(sudoExecutionContext);
try {
- beforeCall(sudoUser);
+ beforeCall(currentExecutionContext, sudoExecutionContext);
return interactionFactory.callAuthenticated(sodoSession, callable);
} finally {
- afterCall();
+ afterCall(sudoExecutionContext, currentExecutionContext);
}
}
// -- HELPER
- private void beforeCall(final @NonNull UserMemento sudoUser) {
+ private void beforeCall(
+ final @NonNull ExecutionContext before,
+ final @NonNull ExecutionContext after) {
for (val sudoListener : sudoListeners) {
- sudoListener.beforeCall(sudoUser);
+ sudoListener.beforeCall(before, after);
}
}
- private void afterCall() {
+ private void afterCall(
+ final @NonNull ExecutionContext before,
+ final @NonNull ExecutionContext after) {
for (val sudoListener : sudoListeners) {
- sudoListener.afterCall();
+ sudoListener.afterCall(before, after);
}
}