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/03/15 16:06:15 UTC
[isis] branch master updated: ISIS-2306: supposed fix to have
request scoped IsisSessions for Vaadin
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 d30b22e ISIS-2306: supposed fix to have request scoped IsisSessions for Vaadin
d30b22e is described below
commit d30b22e9ccf340983bf2cc52577504312c34491b
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Mar 15 17:06:01 2020 +0100
ISIS-2306: supposed fix to have request scoped IsisSessions for Vaadin
---
.../session/IsisSessionFactoryDefault.java | 6 ++
.../java/demoapp/vaadin/webapp/DemoAppVaadin.java | 2 +
.../vaadin/ui/auth/AuthSessionStoreUtil.java | 80 ++++++++++++++++
.../ui/auth/VaadinAuthenticationHandler.java | 35 +++----
.../vaadin/ui/components/collection/TableView.java | 102 ++++++++++++++++++++-
.../ui/components/object/ObjectFormView.java | 43 +--------
.../viewer/vaadin/ui/pages/main/MainView.java | 2 +-
.../viewer/IsisModuleIncViewerVaadinViewer.java | 5 +-
.../viewer/vaadin/viewer/IsisServletForVaadin.java | 84 +++++++++++++++++
9 files changed, 291 insertions(+), 68 deletions(-)
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/IsisSessionFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/IsisSessionFactoryDefault.java
index 730db5b..39803b1 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/IsisSessionFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/IsisSessionFactoryDefault.java
@@ -245,6 +245,12 @@ public class IsisSessionFactoryDefault implements IsisSessionFactory, IsisSessio
private void closeSessionStackDownToStackSize(int downToStackSize) {
+ log.debug("about to close IsisSession stack down to size {} (conversation-id={}, total-sessions-on-stack={}, {})",
+ downToStackSize,
+ conversationId.get(),
+ isisSessionStack.get().size(),
+ _Probe.currentThreadId());
+
val stack = isisSessionStack.get();
while(stack.size()>downToStackSize) {
if(stack.size()==1) {
diff --git a/examples/demo-vaadin/src/main/java/demoapp/vaadin/webapp/DemoAppVaadin.java b/examples/demo-vaadin/src/main/java/demoapp/vaadin/webapp/DemoAppVaadin.java
index c218b67..1e8f994 100644
--- a/examples/demo-vaadin/src/main/java/demoapp/vaadin/webapp/DemoAppVaadin.java
+++ b/examples/demo-vaadin/src/main/java/demoapp/vaadin/webapp/DemoAppVaadin.java
@@ -29,6 +29,7 @@ import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.core.runtimeservices.session.IsisSessionFactoryDefault;
import org.apache.isis.incubator.viewer.vaadin.ui.auth.VaadinAuthenticationHandler;
import org.apache.isis.incubator.viewer.vaadin.viewer.IsisModuleIncViewerVaadinViewer;
+import org.apache.isis.incubator.viewer.vaadin.viewer.IsisServletForVaadin;
import demoapp.webapp.DemoApp;
@@ -60,6 +61,7 @@ public class DemoAppVaadin extends SpringBootServletInitializer {
IsisPresets.logging(IsisSessionFactoryDefault.class, "debug");
IsisPresets.logging(VaadinAuthenticationHandler.class, "debug");
+ IsisPresets.logging(IsisServletForVaadin.class, "debug");
SpringApplication.run(new Class[] { DemoAppVaadin.class }, args);
}
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/auth/AuthSessionStoreUtil.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/auth/AuthSessionStoreUtil.java
new file mode 100644
index 0000000..ee09693
--- /dev/null
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/auth/AuthSessionStoreUtil.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); 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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.incubator.viewer.vaadin.ui.auth;
+
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+import javax.servlet.http.HttpSession;
+
+import com.vaadin.flow.server.VaadinSession;
+
+import org.apache.isis.core.commons.internal.collections._Lists;
+import org.apache.isis.core.security.authentication.AuthenticationSession;
+import org.apache.isis.core.security.authentication.standard.SimpleSession;
+
+import lombok.NonNull;
+import lombok.experimental.UtilityClass;
+
+/**
+ *
+ * @since Mar 15, 2020
+ *
+ */
+@UtilityClass
+public class AuthSessionStoreUtil {
+
+ public static void put(
+ @NonNull final HttpSession httpSession,
+ @Nullable final AuthenticationSession authSession) {
+ httpSession.setAttribute(AuthenticationSession.class.getName(), authSession);
+ }
+
+ public static Optional<AuthenticationSession> get(
+ @NonNull final HttpSession httpSession) {
+ return Optional.ofNullable(
+ (AuthenticationSession)httpSession
+ .getAttribute(AuthenticationSession.class.getName()));
+ }
+
+ /** when within a VaadinSession */
+ public static void put(
+ @Nullable final AuthenticationSession authSession) {
+ VaadinSession.getCurrent().getSession()
+ .setAttribute(AuthenticationSession.class.getName(), authSession);
+ }
+
+ /** when within a VaadinSession */
+ public static Optional<AuthenticationSession> get() {
+ return Optional.ofNullable(
+ (AuthenticationSession)VaadinSession.getCurrent().getSession()
+ .getAttribute(AuthenticationSession.class.getName()));
+ }
+
+ /** when within a VaadinSession */
+ public static void clear() {
+ put(null);
+ }
+
+ /** when within a VaadinSession */
+ public static void putSven() {
+ put(new SimpleSession("sven", _Lists.of("isis-module-security-admin")));
+ }
+
+}
\ No newline at end of file
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/auth/VaadinAuthenticationHandler.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/auth/VaadinAuthenticationHandler.java
index 48fc706..79c9207 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/auth/VaadinAuthenticationHandler.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/auth/VaadinAuthenticationHandler.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.incubator.viewer.vaadin.ui.auth;
-import java.util.Optional;
import java.util.concurrent.Callable;
import javax.inject.Inject;
@@ -31,11 +30,8 @@ import com.vaadin.flow.server.VaadinSession;
import org.springframework.stereotype.Component;
-import org.apache.isis.core.commons.internal.collections._Lists;
import org.apache.isis.core.runtime.session.IsisSessionFactory;
import org.apache.isis.core.runtime.session.IsisSessionFactory.ThrowingRunnable;
-import org.apache.isis.core.security.authentication.AuthenticationSession;
-import org.apache.isis.core.security.authentication.standard.SimpleSession;
import org.apache.isis.incubator.viewer.vaadin.ui.pages.login.VaadinLoginView;
import lombok.val;
@@ -57,7 +53,7 @@ public class VaadinAuthenticationHandler implements VaadinServiceInitListener {
@Override
public void serviceInit(ServiceInitEvent event) {
- log.info("service init event {}", event.getSource());
+ log.debug("service init event {}", event.getSource());
event.getSource().addUIInitListener(uiEvent -> {
uiEvent.getUI().addBeforeEnterListener(this::beforeEnter);
@@ -71,27 +67,23 @@ public class VaadinAuthenticationHandler implements VaadinServiceInitListener {
* @return whether login was successful
*/
public boolean loginToSession(String userName, String secret) {
- log.info("logging in {}", userName);
+ log.debug("logging in {}", userName);
+
// TODO yet does successfully login 'sven' regardless of arguments
- VaadinSession.getCurrent().setAttribute(
- AuthenticationSession.class,
- new SimpleSession("sven", _Lists.of("isis-module-security-admin")));
+ AuthSessionStoreUtil.putSven();
+
return true;
}
public void logoutFromSession() {
- currentAuthenticationSession()
+ AuthSessionStoreUtil.get()
.ifPresent(authSession->{
- log.info("logging out {}", authSession.getUserName());
- VaadinSession.getCurrent().setAttribute(AuthenticationSession.class, null);
+ log.debug("logging out {}", authSession.getUserName());
+ AuthSessionStoreUtil.clear();
});
VaadinSession.getCurrent().close();
+ isisSessionFactory.closeSessionStack();
}
-
- public static Optional<AuthenticationSession> currentAuthenticationSession() {
- return Optional.ofNullable(VaadinSession.getCurrent().getAttribute(
- AuthenticationSession.class));
- }
/**
* Executes a piece of code in a new (possibly nested) IsisSession, using the
@@ -102,7 +94,7 @@ public class VaadinAuthenticationHandler implements VaadinServiceInitListener {
*
*/
public <R> R callAuthenticated(Callable<R> callable) {
- return currentAuthenticationSession()
+ return AuthSessionStoreUtil.get()
.map(authSession->isisSessionFactory.callAuthenticated(authSession, callable))
.orElse(null); // TODO redirect to login
}
@@ -121,20 +113,21 @@ public class VaadinAuthenticationHandler implements VaadinServiceInitListener {
private void beforeEnter(BeforeEnterEvent event) {
val targetView = event.getNavigationTarget();
- log.info("Detected a routing event to {}", targetView);
+ log.debug("detected a routing event to {}", targetView);
- val authSession = currentAuthenticationSession().orElse(null);
+ val authSession = AuthSessionStoreUtil.get().orElse(null);
if(authSession!=null) {
isisSessionFactory.openSession(authSession);
return; // access granted
}
+ // otherwise redirect to login page
if(!VaadinLoginView.class.equals(targetView)) {
event.rerouteTo(VaadinLoginView.class);
}
}
private void beforeLeave(BeforeLeaveEvent event) {
- isisSessionFactory.closeSessionStack();
+ //isisSessionFactory.closeSessionStack();
}
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java
index 8f12661..38dde8e 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/collection/TableView.java
@@ -18,32 +18,126 @@
*/
package org.apache.isis.incubator.viewer.vaadin.ui.components.collection;
+import java.util.Collection;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
+
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import org.apache.isis.core.commons.internal.base._NullSafe;
import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.NonNull;
import lombok.val;
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TableView extends VerticalLayout {
private static final long serialVersionUID = 1L;
-
+
+ private static final String NULL_LITERAL = "<NULL>";
+
+ public static TableView empty() {
+ return new TableView();
+ }
+
/**
* Constructs a (page-able) {@link Grid} from given {@code collection}
- * @param collection of (wrapped) domain objects
+ * @param collection - of (wrapped) domain objects
*/
- public TableView(final ManagedObject collection) {
+ public static TableView fromCollection(final ManagedObject collection) {
val collectionFacet = collection.getSpecification()
.getFacet(CollectionFacet.class);
val objects = collectionFacet.stream(collection)
.collect(Collectors.toList());
+ if (_NullSafe.isEmpty(objects)) {
+ return empty();
+ }
+
+ val elementSpec = objects.iterator().next().getSpecification();
+ return new TableView(elementSpec, objects);
+ }
+
+ /**
+ * Constructs a (page-able) {@link Grid} from given {@code objectAssociation} and {@code assocObject}
+ * @param objectAssociation
+ * @param assocObject
+ */
+ public static TableView fromObjectAssociation(
+ @NonNull final ObjectAssociation objectAssociation,
+ @Nullable final ManagedObject assocObject) {
+
+ val assocObjectSpecification = assocObject.getSpecification();
+ val collectionFacet = assocObjectSpecification.getFacet(CollectionFacet.class);
+
+ val pojo = assocObject.getPojo();
+ if (pojo instanceof Collection) {
+ val objects = collectionFacet.stream(assocObject).collect(Collectors.toList());
+ return new TableView(objectAssociation.getOnType(), objects);
+ }
+
+ return empty();
+ }
+
+
+ /**
+ *
+ * @param elementSpec - as is common to all given {@code objects} aka elements
+ * @param objects - (wrapped) domain objects to be rendered by this table
+ */
+ private TableView(
+ @NonNull final ObjectSpecification elementSpec,
+ @Nullable final Collection<ManagedObject> objects) {
+ // final ComboBox<ManagedObject> listBox = new ComboBox<>();
+ // listBox.setLabel(label + " #" + objects.size());
+ // listBox.setItems(objects);
+ // if (!objects.isEmpty()) {
+ // listBox.setValue(objects.get(0));
+ // }
+ // listBox.setItemLabelGenerator(o -> o.titleString(null));
+
val objectGrid = new Grid<ManagedObject>();
- objectGrid.setItems(objects);
add(objectGrid);
+
+ if (_NullSafe.isEmpty(objects)) {
+ return;
+ }
+
+ objectGrid.setItems(objects);
+
+ elementSpec
+ .streamAssociations(Contributed.INCLUDED)
+ .filter(assoc -> assoc.getFeatureType().isProperty())
+ .forEach(property -> {
+
+ objectGrid.addColumn(targetObject -> {
+ // TODO call to property.get(...) requires an IsisSession,
+ // not sure if we want to spawn a new session for each such call.
+ // maybe we open an IsisSession earlier, to have this table/grid built
+ // within a single IsisSession
+
+ val propertyValue = property.get(targetObject);
+ return propertyValue == null
+ ? NULL_LITERAL
+ : propertyValue.titleString();
+
+// return "<" + property.getId() + ">";
+
+ })
+ .setHeader(property.getName());
+ });
+ objectGrid.setItems(objects);
+ objectGrid.recalculateColumnWidths();
+ objectGrid.setColumnReorderingAllowed(true);
+
}
}
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java
index 34bf31e..682cbef 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/object/ObjectFormView.java
@@ -20,12 +20,10 @@ package org.apache.isis.incubator.viewer.vaadin.ui.components.object;
import java.io.ByteArrayInputStream;
import java.util.Collection;
-import java.util.List;
import java.util.stream.Collectors;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.formlayout.FormLayout;
-import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Image;
@@ -35,11 +33,11 @@ import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.server.InputStreamFactory;
import com.vaadin.flow.server.StreamResource;
-import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.incubator.viewer.vaadin.ui.components.collection.TableView;
import lombok.val;
@@ -124,48 +122,11 @@ public class ObjectFormView extends VerticalLayout {
final ObjectAssociation objectAssociation,
final ManagedObject assocObject
) {
- val assocObjectSpecification = assocObject.getSpecification();
- val collectionFacet = assocObjectSpecification.getFacet(CollectionFacet.class);
val labelLiteral = "Collection: " + objectAssociation.getName();
val pojo = assocObject.getPojo();
if (pojo instanceof Collection) {
-
- final List<ManagedObject> objects = collectionFacet.stream(assocObject).collect(Collectors.toList());
-
- // final ComboBox<ManagedObject> listBox = new ComboBox<>();
- // listBox.setLabel(label + " #" + objects.size());
- // listBox.setItems(objects);
- // if (!objects.isEmpty()) {
- // listBox.setValue(objects.get(0));
- // }
- // listBox.setItemLabelGenerator(o -> o.titleString(null));
-
- val objectGrid = new Grid<ManagedObject>();
- if (objects.isEmpty()) {
- return objectGrid;
- }
- val firstObject = objects.get(0);
- firstObject.getSpecification()
- .streamAssociations(Contributed.INCLUDED)
- .filter(assoc -> assoc.getFeatureType().isProperty())
- .forEach(property -> {
- objectGrid.addColumn(targetObject -> {
- // TODO call to property.get(...) requires an IsisSession,
- // not sure if we want to spawn a new session for each such call.
- // maybe we open an IsisSession earlier, to have this table/grid built
- // within a single IsisSession
- val propertyValue = property.get(targetObject);
- return propertyValue == null
- ? NULL_LITERAL
- : propertyValue.titleString();
- })
- .setHeader(property.getName());
- });
- objectGrid.setItems(objects);
- objectGrid.recalculateColumnWidths();
- objectGrid.setColumnReorderingAllowed(true);
- return objectGrid;
+ return TableView.fromObjectAssociation(objectAssociation, assocObject);
}
if (pojo == null) {
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
index 5d172d5..7d0177b 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
@@ -193,7 +193,7 @@ public class MainView extends VerticalLayout {
);
if (result.getSpecification().isParentedOrFreeCollection()) {
- actionResult.add(new TableView(result));
+ actionResult.add(TableView.fromCollection(result));
} else {
actionResult.add(new ObjectFormView(result));
}
diff --git a/incubator/viewers/vaadin/viewer/src/main/java/org/apache/isis/incubator/viewer/vaadin/viewer/IsisModuleIncViewerVaadinViewer.java b/incubator/viewers/vaadin/viewer/src/main/java/org/apache/isis/incubator/viewer/vaadin/viewer/IsisModuleIncViewerVaadinViewer.java
index 8b28086..8890e85 100644
--- a/incubator/viewers/vaadin/viewer/src/main/java/org/apache/isis/incubator/viewer/vaadin/viewer/IsisModuleIncViewerVaadinViewer.java
+++ b/incubator/viewers/vaadin/viewer/src/main/java/org/apache/isis/incubator/viewer/vaadin/viewer/IsisModuleIncViewerVaadinViewer.java
@@ -41,6 +41,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+import org.apache.isis.core.runtime.session.IsisSessionFactory;
import org.apache.isis.incubator.viewer.vaadin.ui.IsisModuleIncViewerVaadinUi;
import lombok.val;
@@ -70,6 +71,7 @@ public class IsisModuleIncViewerVaadinViewer {
@Inject private WebApplicationContext context;
@Inject private VaadinConfigurationProperties configurationProperties;
+ @Inject private IsisSessionFactory isisSessionFactory;
/**
* Creates a {@link ServletContextInitializer} instance.
@@ -97,7 +99,8 @@ public class IsisModuleIncViewerVaadinViewer {
makeContextRelative(urlMapping.replace("*", "")));
}
val registration = new ServletRegistrationBean<SpringServlet>(
- new SpringServlet(context, isRootMapping), urlMapping);
+ new IsisServletForVaadin(isisSessionFactory, context, isRootMapping),
+ urlMapping);
registration.setInitParameters(initParameters);
registration.setAsyncSupported(configurationProperties.isAsyncSupported());
registration.setName(ClassUtils.getShortNameAsProperty(SpringServlet.class));
diff --git a/incubator/viewers/vaadin/viewer/src/main/java/org/apache/isis/incubator/viewer/vaadin/viewer/IsisServletForVaadin.java b/incubator/viewers/vaadin/viewer/src/main/java/org/apache/isis/incubator/viewer/vaadin/viewer/IsisServletForVaadin.java
new file mode 100644
index 0000000..d9cbf28
--- /dev/null
+++ b/incubator/viewers/vaadin/viewer/src/main/java/org/apache/isis/incubator/viewer/vaadin/viewer/IsisServletForVaadin.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); 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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.incubator.viewer.vaadin.viewer;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.vaadin.flow.spring.SpringServlet;
+
+import org.springframework.context.ApplicationContext;
+
+import org.apache.isis.core.runtime.session.IsisSession;
+import org.apache.isis.core.runtime.session.IsisSessionFactory;
+import org.apache.isis.incubator.viewer.vaadin.ui.auth.AuthSessionStoreUtil;
+
+import lombok.NonNull;
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+/**
+ * An extension of {@link SpringServlet} to support {@link IsisSession} life-cycle management.
+ * @since Mar 14, 2020
+ *
+ */
+@Log4j2
+public class IsisServletForVaadin
+extends SpringServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ private final IsisSessionFactory isisSessionFactory;
+
+ public IsisServletForVaadin(
+ @NonNull final IsisSessionFactory isisSessionFactory,
+ @NonNull final ApplicationContext context,
+ final boolean forwardingEnforced) {
+ super(context, forwardingEnforced);
+ this.isisSessionFactory = isisSessionFactory;
+ }
+
+
+ @Override
+ protected void service(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+
+ val authSession = AuthSessionStoreUtil.get(request.getSession(true))
+ .orElse(null);
+
+ log.debug("new request incoming (authentication={})", authSession);
+
+ if(authSession!=null) {
+ isisSessionFactory.runAuthenticated(authSession, ()->{
+ super.service(request, response);
+ });
+ } else {
+ // do not open an IsisSession, instead redirect to login page
+ // this should happen afterwards by means of the VaadinAuthenticationHandler
+
+ super.service(request, response);
+ }
+ }
+
+
+
+}