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:01:20 UTC

[isis] branch master updated: ISIS-2464: store AuthSessions with each nested layer

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 c53db1a  ISIS-2464: store AuthSessions with each nested layer
c53db1a is described below

commit c53db1a077487c7dc608eebdafa95632f9775653
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Dec 4 23:00:10 2020 +0100

    ISIS-2464: store AuthSessions with each nested layer
---
 .../isis/applib/services/iactn/ExecutionContext.java |  9 +++++----
 .../services/wrapper/control/AsyncControl.java       |  2 +-
 .../isis/core/runtime/iactn/InteractionFactory.java  | 13 ++++++++++++-
 .../isis/core/runtime/iactn/InteractionLayer.java    | 15 ++++++++++-----
 .../isis/core/runtime/iactn/InteractionSession.java  |  6 +-----
 .../isis/core/runtime/iactn/InteractionTracker.java  |  7 ++++++-
 .../session/InteractionFactoryDefault.java           |  9 ++++-----
 .../runtimeservices/sudo/SudoServiceDefault.java     | 20 ++++----------------
 .../wrapper/WrapperFactoryDefault.java               | 15 +++++++--------
 9 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java
index 48cb813..2265b69 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactn/ExecutionContext.java
@@ -30,6 +30,7 @@ import lombok.Getter;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.Value;
+import lombok.With;
 
 /**
  * Provides the user and scenario specific environment for an {@link Interaction.Execution}
@@ -50,7 +51,7 @@ public final class ExecutionContext implements Serializable {
      * @apiNote immutable, allows an {@link Interaction} to (logically) run with its 
      * own simulated (or actual) user 
      */
-    @Getter @Builder.Default
+    @With @Getter @Builder.Default 
     private final @NonNull UserMemento user = UserMemento.system();
     
     /**
@@ -59,13 +60,13 @@ public final class ExecutionContext implements Serializable {
      * @apiNote immutable, allows an {@link Interaction} to (logically) run with its 
      * own simulated (or actual) clock 
      */
-    @Getter @Builder.Default 
+    @With @Getter @Builder.Default 
     private final @NonNull VirtualClock clock = VirtualClock.system();
     
-    @Getter @Builder.Default 
+    @With @Getter @Builder.Default 
     private final @NonNull Locale locale = Locale.getDefault();
     
-    @Getter @Builder.Default 
+    @With @Getter @Builder.Default 
     private final @NonNull TimeZone timeZone = TimeZone.getDefault();
     
     // -- FACTORIES
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/control/AsyncControl.java b/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/control/AsyncControl.java
index 16cc37f..c95027e 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/control/AsyncControl.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/wrapper/control/AsyncControl.java
@@ -86,7 +86,7 @@ public class AsyncControl<R> extends ControlAbstract<AsyncControl<R>> {
 
     // end::refguide[]
     /**
-     * Defaults to the system clock, if not overridden
+     * Defaults to the system locale, if not overridden
      */
     // tag::refguide[]
     @Getter
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java
index 6817eb1..570ffe8 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionFactory.java
@@ -43,6 +43,18 @@ public interface InteractionFactory {
         void run() throws Exception;
     }
 
+    /**
+     * Creates a new {@link InteractionSession}, which represents a user's span of
+     * activities interacting with the application.
+     *
+     * <p>
+     *     If there is already an {@link InteractionSession} available (as held
+     *     in a thread-local stack), then the interactions are stacked.
+     *     These are closed using {@link #closeSessionStack()}.
+     * </p>
+     *
+     * @param authenticationSession
+     */
     InteractionLayer openInteraction();
     
     /**
@@ -56,7 +68,6 @@ public interface InteractionFactory {
      * </p>
      *
      * @param authenticationSession
-     * @return
      */
     InteractionLayer openInteraction(AuthenticationSession authenticationSession);
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionLayer.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionLayer.java
index de00654..f79632b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionLayer.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionLayer.java
@@ -20,6 +20,7 @@ package org.apache.isis.core.runtime.iactn;
 
 import org.apache.isis.applib.services.iactn.ExecutionContext;
 import org.apache.isis.core.runtime.context.RuntimeContextBase;
+import org.apache.isis.core.security.authentication.AuthenticationSession;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -27,7 +28,7 @@ import lombok.NonNull;
 /**
  * Provides the environment for an (or parts of an) user interaction to be executed.
  * <p>
- * Can be nested by pushing onto the current Thread's ClosureStack.  
+ * Can be nested by pushing onto the current Thread's InteractionLayer Stack.  
  * 
  * @since 2.0
  *
@@ -35,11 +36,11 @@ import lombok.NonNull;
 public class InteractionLayer extends RuntimeContextBase {
 
 	@Getter private final InteractionSession interactionSession;
-	@Getter private final ExecutionContext executionContext;
+	@Getter private final AuthenticationSession authenticationSession;
 	
 	public InteractionLayer(
 			final @NonNull InteractionSession interactionSession,
-			final @NonNull ExecutionContext executionContext) {
+			final @NonNull AuthenticationSession authenticationSession) {
 
 		super(interactionSession.getMetaModelContext());
 		
@@ -47,8 +48,12 @@ public class InteractionLayer extends RuntimeContextBase {
 		// meaning the InteractionSession that holds the stack containing this layer 
 		this.interactionSession = interactionSession;
 		
-		// binds given executionContext to this layer 
-		this.executionContext = executionContext; 
+		// binds given authenticationSession to this layer 
+		this.authenticationSession = authenticationSession; 
+	}
+	
+	public ExecutionContext getExecutionContext() {
+	    return authenticationSession.getExecutionContext();
 	}
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionSession.java
index d6a9d27..7fe37f8 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionSession.java
@@ -32,7 +32,6 @@ import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.commons.ToString;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.runtime.context.RuntimeContextBase;
-import org.apache.isis.core.security.authentication.AuthenticationSession;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -55,7 +54,6 @@ import lombok.Setter;
  */
 public class InteractionSession extends RuntimeContextBase {
 
-    @Getter private final AuthenticationSession authenticationSession;
     @Getter private final long lifecycleStartedAtSystemNanos;
     
     /**
@@ -64,11 +62,9 @@ public class InteractionSession extends RuntimeContextBase {
     @Getter private final MessageBroker messageBroker = new MessageBroker();
 
     public InteractionSession(
-            @NonNull final MetaModelContext mmc,
-            @NonNull final AuthenticationSession authenticationSession) {
+            @NonNull final MetaModelContext mmc) {
 
         super(mmc);
-        this.authenticationSession = authenticationSession; // binds this session to given authenticationSession
         this.lifecycleStartedAtSystemNanos = System.nanoTime(); // used to measure time periods, so not using ClockService here
         this.interaction = new IsisInteraction(UUID.randomUUID());
     }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionTracker.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionTracker.java
index 528cffd..fd7763b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionTracker.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/iactn/InteractionTracker.java
@@ -41,6 +41,11 @@ extends InteractionContext, AuthenticationContext {
      * request- or test-scoped InteractionSession*/
     Optional<InteractionLayer> currentInteractionLayer();
     
+    default InteractionLayer currentInteractionLayerElseFail() {
+        return currentInteractionLayer()
+        .orElseThrow(()->_Exceptions.illegalState("No InteractionSession available on current thread"));
+    }
+    
     /** @return the current request- or test-scoped InteractionSession*/
     default Optional<InteractionSession> currentInteractionSession() {
     	return currentInteractionLayer().map(InteractionLayer::getInteractionSession);
@@ -66,7 +71,7 @@ extends InteractionContext, AuthenticationContext {
     
     @Override
     default Optional<AuthenticationSession> currentAuthenticationSession() {
-        return currentInteractionSession().map(InteractionSession::getAuthenticationSession);
+        return currentInteractionLayer().map(InteractionLayer::getAuthenticationSession);
     }
     
     // -- INTERACTION CONTEXT
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
index 6eca0a6..7afb853 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionFactoryDefault.java
@@ -154,8 +154,8 @@ implements InteractionFactory, InteractionTracker {
     @Override
     public InteractionLayer openInteraction(final @NonNull AuthenticationSession authSessionToUse) {
 
-        val interactionSession = getOrCreateInteractionSession(authSessionToUse);
-        val newInteractionClosure = new InteractionLayer(interactionSession, authSessionToUse.getExecutionContext());
+        val interactionSession = getOrCreateInteractionSession();
+        val newInteractionClosure = new InteractionLayer(interactionSession, authSessionToUse);
         
         interactionLayerStack.get().push(newInteractionClosure);
 
@@ -173,11 +173,10 @@ implements InteractionFactory, InteractionTracker {
         return newInteractionClosure;
     }
     
-    private InteractionSession getOrCreateInteractionSession(
-    		final @NonNull AuthenticationSession authSessionToUse) {
+    private InteractionSession getOrCreateInteractionSession() {
     	
     	return interactionLayerStack.get().isEmpty()
-    			? new InteractionSession(metaModelContext, authSessionToUse)
+    			? new InteractionSession(metaModelContext)
 				: interactionLayerStack.get().firstElement().getInteractionSession();
     }
 
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 1931f2f..759e986 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
@@ -30,12 +30,10 @@ 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.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.runtime.iactn.InteractionFactory;
 import org.apache.isis.core.runtime.iactn.InteractionTracker;
 
@@ -70,21 +68,11 @@ public class SudoServiceDefault implements SudoService {
     @Override
     public <T> T call(final @NonNull UserMemento sudoUser, final @NonNull Callable<T> callable) {
 
-        val interactionLayer = interactionTracker.currentInteractionLayer()
-                .orElseThrow(()->_Exceptions.illegalState(
-                        "will not execute sudo on top of non authenticated session, use WrapperFactory instead"));
+        val currentinteractionLayer = interactionTracker.currentInteractionLayerElseFail();
+        val currentExecutionContext = currentinteractionLayer.getExecutionContext();
+        val sudoExecutionContext = currentExecutionContext.withUser(sudoUser);
         
-        val executionContext = interactionLayer.getExecutionContext();
-        
-        val sudoExecutionContext = ExecutionContext.builder()
-        .clock(executionContext.getClock())
-        .locale(executionContext.getLocale())
-        .timeZone(executionContext.getTimeZone())
-        .user(sudoUser)
-        .build();
-        
-        val interactionSession = interactionLayer.getInteractionSession();
-        val sodoSession = interactionSession
+        val sodoSession = currentinteractionLayer
                 .getAuthenticationSession()
                 .withExecutionContext(sudoExecutionContext);
         
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index d59ebf3..c80447b 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -93,7 +93,7 @@ import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionMixedIn;
 import org.apache.isis.core.runtime.iactn.InteractionFactory;
-import org.apache.isis.core.runtime.iactn.InteractionSession;
+import org.apache.isis.core.runtime.iactn.InteractionLayer;
 import org.apache.isis.core.runtime.iactn.InteractionTracker;
 import org.apache.isis.core.runtimeservices.wrapper.dispatchers.InteractionEventDispatcher;
 import org.apache.isis.core.runtimeservices.wrapper.dispatchers.InteractionEventDispatcherTypeSafe;
@@ -124,7 +124,7 @@ import lombok.val;
 //@Log4j2
 public class WrapperFactoryDefault implements WrapperFactory {
     
-    @Inject InteractionTracker isisInteractionTracker;
+    @Inject InteractionTracker interactionTracker;
     @Inject FactoryService factoryService;
     @Inject MetaModelContext metaModelContext;
     @Inject SpecificationLoader specificationLoader;
@@ -326,8 +326,8 @@ public class WrapperFactoryDefault implements WrapperFactory {
             final Object[] args,
             final AsyncControl<R> asyncControl) {
 
-        val interactionSession = currentInteractionSession();
-        val asyncAuthSession = authSessionFrom(asyncControl, interactionSession.getAuthenticationSession());
+        val interactionLayer = currentInteractionLayer();
+        val asyncAuthSession = authSessionFrom(asyncControl, interactionLayer.getAuthenticationSession());
         val command = interactionContextProvider.get().getInteractionElseFail().getCommand();
         val commandUniqueId = command.getUniqueId();
 
@@ -545,13 +545,12 @@ public class WrapperFactoryDefault implements WrapperFactory {
         dispatchersByEventClass.put(type, dispatcher);
     }
 
-
-    private InteractionSession currentInteractionSession() {
-        return isisInteractionTracker.currentInteractionSession().orElseThrow(() -> new RuntimeException("No IsisInteraction is open"));
+    private InteractionLayer currentInteractionLayer() {
+        return interactionTracker.currentInteractionLayerElseFail();
     }
 
     private ObjectManager currentObjectManager() {
-        return currentInteractionSession().getObjectManager();
+        return metaModelContext.getObjectManager();
     }
 
     @RequiredArgsConstructor