package org.peerbox.app; import javafx.application.Platform; import org.hive2hive.core.exceptions.NoPeerConnectionException; import org.hive2hive.core.exceptions.NoSessionException; import org.peerbox.app.manager.node.INodeManager; import org.peerbox.app.manager.user.IUserManager; import org.peerbox.events.MessageBus; import org.peerbox.server.IServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.inject.Inject; /** * The ExitHandler is responsible for shutting down the application in a controlled way. * All services should be stopped and the client should do a graceful leave (logout and * disconnect from the network). * * @author albrecht * */ public class ExitHandler implements IExitHandler { private static final Logger logger = LoggerFactory.getLogger(ExitHandler.class); private final AppContext appContext; @Inject public ExitHandler(AppContext appContext) { this.appContext = appContext; } @Override public void exit() { exit(0); } private void exit(int status) { try { if (appContext != null) { ClientContext clientContext = appContext.getCurrentClientContext(); if (clientContext != null) { shutdownClient(clientContext); } shutdownApp(appContext); } } catch (Throwable t) { logger.warn("Exception occurred during exit handler.", t); if (t instanceof Exception) { logger.warn("Exception: ", t); } } finally { shutdown(status); } } /** * Shutdown of application-wide services * * @param context of application */ private void shutdownApp(AppContext context) { stopMessageBus(context); stopServer(context); } /** * Shutdown of user-specific services * * @param context of client */ private void shutdownClient(ClientContext context) { logout(context); disconnect(context); } /** * Framework shutdown and final exit * * @param status exit code */ private void shutdown(int status) { logger.debug("Shutdown with status code = {}", status); // stop JavaFX application thread Platform.exit(); System.exit(status); } /** * Shutdown the message bus * * @param context of application */ private void stopMessageBus(AppContext context) { try { MessageBus messageBus = context.getMessageBus(); if (messageBus != null) { messageBus.shutdown(); } } catch (Exception e) { logger.warn("Could not shutdown message bus.", e); } } /** * Stop the HTTP server * * @param context of application */ private void stopServer(AppContext context) { try { IServer server = context.getServer(); if (server != null) { boolean success = server.stop(); if (!success) { logger.error("Could not stop API server properly."); } } } catch (Exception e) { logger.warn("Could not shutdown server.", e); } } /** * Logout H2H user profile * * @param context of client */ private void logout(ClientContext context) { try { IUserManager userManager = context.getUserManager(); if (userManager != null && userManager.isLoggedIn()) { userManager.logoutUser(); } } catch (NoPeerConnectionException npc) { logger.error("Cannot logout - no peer connection. ", npc); } catch (NoSessionException nse) { logger.error("Cannot logout - no session. ", nse); } catch (Exception e) { logger.warn("Could not logout.", e); } } /** * Disconnect from H2H network (graceful leave) * * @param context of client */ private void disconnect(ClientContext context) { try { INodeManager nodeManager = context.getNodeManager(); if (nodeManager != null && nodeManager.isConnected()) { boolean success = nodeManager.leaveNetwork(); if (!success) { logger.error("Could not disconnect from network properly."); } } } catch (Exception e) { logger.warn("Could not disconnect.", e); } } }