Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -rae02cc75ca6d4d08c0e45aa9f36b33d646c893b1 -r3b35f079ed7194371481503fe4f0a0462f2cbe63 Binary files differ Index: lams_central/src/java/org/lamsfoundation/lams/web/RuntimeStatsServlet.java =================================================================== diff -u -rae02cc75ca6d4d08c0e45aa9f36b33d646c893b1 -r3b35f079ed7194371481503fe4f0a0462f2cbe63 --- lams_central/src/java/org/lamsfoundation/lams/web/RuntimeStatsServlet.java (.../RuntimeStatsServlet.java) (revision ae02cc75ca6d4d08c0e45aa9f36b33d646c893b1) +++ lams_central/src/java/org/lamsfoundation/lams/web/RuntimeStatsServlet.java (.../RuntimeStatsServlet.java) (revision 3b35f079ed7194371481503fe4f0a0462f2cbe63) @@ -29,21 +29,15 @@ import java.lang.management.MemoryUsage; import java.lang.management.ThreadMXBean; import java.util.Date; -import java.util.Set; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanOperationInfo; import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; -import org.lamsfoundation.lams.util.HttpUrlConnectionUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; @@ -102,10 +96,7 @@ System.out.println(" " + attr.getName() + "\n"); } } - - ObjectName engineName = new ObjectName("jboss.web:type=Engine"); - String jvmRoute = (String) server.getAttribute(engineName, "jvmRoute"); - */ + */ ObjectName dataSourceName = new ObjectName( "jboss.as.expr:subsystem=datasources,data-source=lams-ds,statistics=pool"); @@ -115,8 +106,8 @@ if (activeCount > 0) { resp.append(" - DB connection established"); } - // resp.append("\nServer : ").append(jvmRoute).append("\n"); - resp.append("\nCurrent Sessions : ").append(SessionManager.getSessionCount()).append("\n"); + resp.append("\nServer : ").append(SessionManager.getJvmRoute()).append("\n"); + resp.append("Current Sessions : ").append(SessionManager.getSessionCount()).append("\n"); resp.append("Time of Request : ").append(date); } catch (Exception e) { RuntimeStatsServlet.log.error("Error while getting short runtime stats", e); @@ -130,9 +121,7 @@ MBeanServer server = ManagementFactory.getPlatformMBeanServer(); try { - //ObjectName engineName = new ObjectName("jboss.web:type=Engine"); - //String jvmRoute = (String) server.getAttribute(engineName, "jvmRoute"); - //resp.append("jvmRoute: ").append(jvmRoute).append("\n"); + resp.append("jvmRoute: ").append(SessionManager.getJvmRoute()).append("\n"); MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean(); MemoryUsage memoryUsage = memoryBean.getHeapMemoryUsage(); @@ -154,13 +143,14 @@ .append(threadBean.getThreadCount()).append("/").append(threadBean.getPeakThreadCount()) .append("\n"); - /* + /* Connector statistics do not seem to be present for WF 8. + * They should be available in WF 9+ (WFLY-4420). ObjectName connectorName = new ObjectName("jboss.as.expr:subsystem=io,worker=default"); Integer busyThreads = (Integer) server.getAttribute(connectorName, "ioThreads"); Integer maxThreads = (Integer) server.getAttribute(connectorName, "taskMaxThreads"); resp.append("IO threads [io/task max]: ").append(busyThreads).append("/").append(maxThreads).append("\n"); */ - + resp.append("Active sessions : ").append(SessionManager.getSessionCount()).append("\n"); ObjectName dataSourceName = new ObjectName( Index: lams_common/src/java/org/lamsfoundation/lams/integration/security/SsoHandler.java =================================================================== diff -u -r57fd95981e299065f2c8c90629420058ea0d88e9 -r3b35f079ed7194371481503fe4f0a0462f2cbe63 --- lams_common/src/java/org/lamsfoundation/lams/integration/security/SsoHandler.java (.../SsoHandler.java) (revision 57fd95981e299065f2c8c90629420058ea0d88e9) +++ lams_common/src/java/org/lamsfoundation/lams/integration/security/SsoHandler.java (.../SsoHandler.java) (revision 3b35f079ed7194371481503fe4f0a0462f2cbe63) @@ -20,19 +20,10 @@ */ package org.lamsfoundation.lams.integration.security; -import io.undertow.Handlers; -import io.undertow.server.HandlerWrapper; -import io.undertow.server.HttpHandler; -import io.undertow.server.HttpServerExchange; -import io.undertow.server.session.Session; -import io.undertow.servlet.ServletExtension; -import io.undertow.servlet.api.DeploymentInfo; -import io.undertow.servlet.handlers.ServletRequestContext; -import io.undertow.servlet.spec.HttpSessionImpl; - import java.security.AccessController; import javax.servlet.ServletContext; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -46,9 +37,15 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import io.undertow.Handlers; +import io.undertow.server.session.Session; +import io.undertow.servlet.ServletExtension; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.handlers.ServletRequestContext; +import io.undertow.servlet.spec.HttpSessionImpl; + /** - * Allows access to LAMS WARs if an user logged in. It puts user Account into shared session so SsoConsumer in other - * WARs can use it. + * Allows access to LAMS WARs when an user logs in. * * @author Marcin Cieslak * @@ -64,51 +61,50 @@ SessionManager.setServletContext(servletContext); // run when request and response were already parsed, but before security handlers - deploymentInfo.addOuterHandlerChainWrapper(new HandlerWrapper() { - @Override - public HttpHandler wrap(final HttpHandler handler) { - // just forward all requests except one for logging in - return Handlers.path().addPrefixPath("/", handler).addExactPath("/j_security_check", new HttpHandler() { - @Override - public void handleRequest(HttpServerExchange exchange) throws Exception { - ServletRequestContext context = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY); - HttpServletRequest request = (HttpServletRequest) context.getServletRequest(); + deploymentInfo.addOuterHandlerChainWrapper(handler -> { + // just forward all requests except one for logging in + return Handlers.path().addPrefixPath("/", handler).addExactPath("/j_security_check", exchange -> { + ServletRequestContext context = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY); + HttpServletRequest request = (HttpServletRequest) context.getServletRequest(); - // recreate session here in case it was invalidated in login.jsp by sysadmin's LoginAs - HttpSession session = request.getSession(); + // initialise jvmRoute for runtime statistics servlet + if (SessionManager.getJvmRoute() == null) { + SsoHandler.setJvmRoute(request); + } - // LoginRequestServlet (integrations) and LoginAsAction (sysadmin) set this parameter - String redirectURL = request.getParameter("redirectURL"); - if (!StringUtils.isBlank(redirectURL)) { - SsoHandler.handleRedirectBack(context, redirectURL); - } - - /* Fetch UserDTO before completing request so putting it later in session is done ASAP - * Response is sent in another thread and if UserDTO is not present in session when browser completes redirect, - * it results in error. Winning this race is the easiest option. - */ - UserDTO userDTO = null; - String login = request.getParameter("j_username"); - if (!StringUtils.isBlank(login)) { - User user = getUserManagementService(session.getServletContext()).getUserByLogin(login); - if (user != null) { - userDTO = user.getUserDTO(); - } - } + // recreate session here in case it was invalidated in login.jsp by sysadmin's LoginAs + HttpSession session = request.getSession(); - // store session so UniversalLoginModule can access it - SessionManager.startSession(request); - // do the logging in UniversalLoginModule or cache - handler.handleRequest(exchange); + // LoginRequestServlet (integrations) and LoginAsAction (sysadmin) set this parameter + String redirectURL = request.getParameter("redirectURL"); + if (!StringUtils.isBlank(redirectURL)) { + SsoHandler.handleRedirectBack(context, redirectURL); + } - if (!StringUtils.isBlank(login) && login.equals(request.getRemoteUser())) { - session.setAttribute(AttributeNames.USER, userDTO); - } - - SessionManager.endSession(); + /* Fetch UserDTO before completing request so putting it later in session is done ASAP + * Response is sent in another thread and if UserDTO is not present in session when browser completes redirect, + * it results in error. Winning this race is the easiest option. + */ + UserDTO userDTO = null; + String login = request.getParameter("j_username"); + if (!StringUtils.isBlank(login)) { + User user = getUserManagementService(session.getServletContext()).getUserByLogin(login); + if (user != null) { + userDTO = user.getUserDTO(); } - }); - } + } + + // store session so UniversalLoginModule can access it + SessionManager.startSession(request); + // do the logging in UniversalLoginModule or cache + handler.handleRequest(exchange); + + if (!StringUtils.isBlank(login) && login.equals(request.getRemoteUser())) { + session.setAttribute(AttributeNames.USER, userDTO); + } + + SessionManager.endSession(); + }); }); } @@ -130,6 +126,28 @@ } } + /** + * Memorises jvmRoute if it is already set. + */ + protected static void setJvmRoute(HttpServletRequest request) { + // if previous requests has not created a session, cookies will be null + Cookie[] cookies = request.getCookies(); + if (cookies == null) { + return; + } + + for (Cookie cookie : cookies) { + if (cookie.getName().equals("JSESSIONID")) { + // look for jvmRoute + int index = cookie.getValue().indexOf('.'); + if (index > 0) { + SessionManager.setJvmRoute(cookie.getValue().substring(index + 1)); + return; + } + } + } + } + protected IUserManagementService getUserManagementService(ServletContext context) { if (SsoHandler.userManagementService == null) { WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); Index: lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java =================================================================== diff -u -rae02cc75ca6d4d08c0e45aa9f36b33d646c893b1 -r3b35f079ed7194371481503fe4f0a0462f2cbe63 --- lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java (.../SessionManager.java) (revision ae02cc75ca6d4d08c0e45aa9f36b33d646c893b1) +++ lams_common/src/java/org/lamsfoundation/lams/web/session/SessionManager.java (.../SessionManager.java) (revision 3b35f079ed7194371481503fe4f0a0462f2cbe63) @@ -38,8 +38,9 @@ private static final Map sessionContainer = new ConcurrentHashMap(); private ThreadLocal currentSessionIdContainer = new ThreadLocal(); - // various classes need to have to access to it + // various classes need to have to access these private static ServletContext servletContext; + private static String jvmRoute; /** * This class initialize method called by Spring framework. @@ -105,4 +106,12 @@ public static ServletContext getServletContext() { return SessionManager.servletContext; } + + public static String getJvmRoute() { + return jvmRoute; + } + + public static void setJvmRoute(String jvmRoute) { + SessionManager.jvmRoute = jvmRoute; + } } \ No newline at end of file