Skip to content

Commit

Permalink
improve session logging (#712)
Browse files Browse the repository at this point in the history
  • Loading branch information
KochTobi authored Jul 16, 2024
1 parent 37860d4 commit 8efea9d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.page.Page.ExtendedClientDetailsReceiver;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.server.ServiceDestroyEvent;
import com.vaadin.flow.server.ServiceInitEvent;
import com.vaadin.flow.server.SessionDestroyEvent;
import com.vaadin.flow.server.SessionDestroyListener;
import com.vaadin.flow.server.VaadinService;
import com.vaadin.flow.server.SessionInitEvent;
import com.vaadin.flow.server.UIInitEvent;
import com.vaadin.flow.server.VaadinServiceInitListener;
import com.vaadin.flow.server.WrappedSession;
import com.vaadin.flow.spring.annotation.SpringComponent;
import life.qbic.datamanager.exceptionhandling.UiExceptionHandler;
import life.qbic.datamanager.security.LogoutService;
Expand All @@ -28,8 +30,7 @@
* Adds listeners to vaadin sessions and ui initialization.
*/
@SpringComponent
public class MyVaadinSessionInitListener implements VaadinServiceInitListener,
SessionDestroyListener {
public class MyVaadinSessionInitListener implements VaadinServiceInitListener {

private static final Logger log = logger(MyVaadinSessionInitListener.class);
private final ExtendedClientDetailsReceiver clientDetailsReceiver;
Expand All @@ -40,36 +41,50 @@ public class MyVaadinSessionInitListener implements VaadinServiceInitListener,
public MyVaadinSessionInitListener(
@Autowired ExtendedClientDetailsReceiver clientDetailsProvider,
@Autowired UiExceptionHandler uiExceptionHandler,
LogoutService logoutService) {
@Autowired LogoutService logoutService) {
this.clientDetailsReceiver = clientDetailsProvider;
this.uiExceptionHandler = uiExceptionHandler;
this.logoutService = logoutService;
}

@Override
public void serviceInit(ServiceInitEvent event) {
event.getSource().addSessionInitListener(
initEvent -> log.debug("A new Session has been initialized! Session " + initEvent.getSession().getSession().getId()));

event.getSource().addSessionDestroyListener(this);
event.getSource().addSessionInitListener(MyVaadinSessionInitListener::onSessionInit);
event.getSource().addServiceDestroyListener(MyVaadinSessionInitListener::onServiceDestroyed);
event.getSource().addSessionDestroyListener(MyVaadinSessionInitListener::onSessionDestroy);
event.getSource().addUIInitListener(this::onUiInit);
}

event.getSource().addUIInitListener(
initEvent -> {
log.debug("A new UI has been initialized! Session is " + initEvent.getUI().getSession().getSession().getId());
UI ui = initEvent.getUI();
ui.getPage().retrieveExtendedClientDetails(clientDetailsReceiver);
ui.getSession().setErrorHandler(errorEvent -> uiExceptionHandler.error(errorEvent, ui));
ui.addBeforeEnterListener(this::ensureCompleteOidcRegistration);
});
private void onUiInit(UIInitEvent initEvent) {
log.debug("A new UI has been initialized! ui[%s] vaadin[%s] http[%s] ".formatted(
initEvent.getUI().getUIId(), initEvent.getUI().getSession().getPushId(),
initEvent.getUI().getSession().getSession().getId()));
UI ui = initEvent.getUI();
ui.getPage().retrieveExtendedClientDetails(clientDetailsReceiver);
ui.getSession().setErrorHandler(errorEvent -> uiExceptionHandler.error(errorEvent, ui));
ui.addBeforeEnterListener(this::ensureCompleteOidcRegistration);
}

private static void onSessionInit(SessionInitEvent initEvent) {
log.debug("A new Session has been initialized! vaadin[%s] http[%s] ".formatted(
initEvent.getSession().getPushId(), initEvent.getSession().getSession().getId()));
}

private static void onServiceDestroyed(ServiceDestroyEvent serviceDestroyEvent) {
log.debug("Destroying vaadin service [%s]".formatted(serviceDestroyEvent.getSource()));
}

@Override
public void sessionDestroy(SessionDestroyEvent event) {
log.debug("Session destroyed.");
event.getSession().getSession().invalidate();
log.debug("HTTP Session has been invalidated. Id is " + event.getSession().getSession().getId());
public static void onSessionDestroy(SessionDestroyEvent event) {
WrappedSession wrappedSession = event.getSession().getSession();
if (wrappedSession != null) {
wrappedSession.invalidate();
log.debug("Invalidated HTTP session " + wrappedSession.getId());
} else {
log.debug("Vaadin session [%s] does not wrap any HTTP session.".formatted(
event.getSession().getPushId()));
}
log.debug("Vaadin session destroyed [%s].".formatted(event.getSession().getPushId()));

}

private void ensureCompleteOidcRegistration(BeforeEnterEvent it) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,20 @@ public void error(ErrorEvent errorEvent, UI ui) {
}

private void displayUserFriendlyMessage(UI ui, ApplicationException exception) {
requireNonNull(ui);
requireNonNull(exception);

requireNonNull(ui, "ui must not be null");
requireNonNull(exception, "exception must not be null");
if (ui.isClosing()) {
log.error(
"tried to show message on closing UI ui[%s] vaadin[%s] http[%s]".formatted(ui.getUIId(),
ui.getSession().getPushId(), ui.getSession().getSession().getId()));
return;
}
if (!ui.isAttached()) {
log.error(
"tried to show message on detached UI ui[%s] vaadin[%s] http[%s]".formatted(ui.getUIId(),
ui.getSession().getPushId(), ui.getSession().getSession().getId()));
return;
}
UserFriendlyErrorMessage errorMessage = userMessageService.translate(exception, ui.getLocale());
ui.access(() -> showErrorDialog(errorMessage));
}
Expand Down
10 changes: 8 additions & 2 deletions user-interface/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,18 @@ qbic.broadcasting.identity.topic=User
spring.servlet.multipart.max-file-size=16777216
spring.servlet.multipart.fileSizeThreshold=16MB
spring.servlet.multipart.max-request-size=16MB
################# Session servlet handling ############################################
###############################################################################
################# Session servlet handling ####################################
#https://mvysny.github.io/vaadin-session-timeout/
# Close sessions after the servlet timeout except when there is activity.
# If there is activity and the session timeout is reached, the session is closed after three missed heartbeats.
# Keep in mind that it can take up to 1 minute after timeout to close the session.
# Session closes at server.servlet.session.timeout + 3*vaadin.heartbeatInterval + 0-1min
server.servlet.session.timeout=${SESSION_TIMEOUT:30m}
vaadin.closeIdleSessions=${SESSION_CLOSEIDLESESSIONS:true}
# Heartbeat value is specified as integer time in seconds
vaadin.heartbeatInterval=${SESSION_HEARTBEATINTERVAL:60}
################# Session cookie handling ############################################
################# Session cookie handling #####################################
server.servlet.session.cookie.max-age=${SESSION_COOKIE_MAX_AGE:30m}
server.servlet.session.cookie.secure=${SESSION_COOKIE_SECURE:true}
server.servlet.session.cookie.domain=${SESSION_COOKIE_DOMAIN:de.uni-tuebingen.qbic}
Expand Down

0 comments on commit 8efea9d

Please sign in to comment.