Author: marrs
Date: Fri Apr 11 18:33:58 2014
New Revision: 1586741
URL: http://svn.apache.org/r1586741
Log:
ACE-442 Added sessions that time out and clean up workspaces.
Modified:
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/Activator.java
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/RESTClientServlet.java
ace/trunk/org.apache.ace.client.workspace/src/org/apache/ace/client/workspace/impl/Activator.java
ace/trunk/run-client/conf/org.apache.ace.client.rest.cfg
ace/trunk/run-server-allinone/conf/org.apache.ace.client.rest.cfg
Modified:
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/Activator.java
URL:
http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/Activator.java?rev=1586741&r1=1586740&r2=1586741&view=diff
==============================================================================
---
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/Activator.java
(original)
+++
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/Activator.java
Fri Apr 11 18:33:58 2014
@@ -21,6 +21,7 @@ package org.apache.ace.client.rest;
import java.util.Properties;
import javax.servlet.Servlet;
+import javax.servlet.http.HttpSessionListener;
import org.apache.ace.client.workspace.WorkspaceManager;
import org.apache.felix.dm.DependencyActivatorBase;
@@ -35,7 +36,7 @@ public class Activator extends Dependenc
@Override
public void init(BundleContext context, DependencyManager manager) throws
Exception {
manager.add(createComponent()
- .setInterface(Servlet.class.getName(), null)
+ .setInterface(new String[] { Servlet.class.getName(),
HttpSessionListener.class.getName() }, null)
.setImplementation(RESTClientServlet.class)
.add(createServiceDependency()
.setService(WorkspaceManager.class)
Modified:
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/RESTClientServlet.java
URL:
http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/RESTClientServlet.java?rev=1586741&r1=1586740&r2=1586741&view=diff
==============================================================================
---
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/RESTClientServlet.java
(original)
+++
ace/trunk/org.apache.ace.client.rest/src/org/apache/ace/client/rest/RESTClientServlet.java
Fri Apr 11 18:33:58 2014
@@ -22,13 +22,19 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
+import java.util.ArrayList;
import java.util.Dictionary;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
import org.apache.ace.client.repository.RepositoryObject;
import org.apache.ace.client.repository.stateful.StatefulTargetObject;
@@ -48,7 +54,11 @@ import com.google.gson.JsonPrimitive;
/**
* Servlet that offers a REST client API.
*/
-public class RESTClientServlet extends HttpServlet implements ManagedService {
+public class RESTClientServlet extends HttpServlet implements ManagedService,
HttpSessionListener {
+ private static final String SESSION_KEY_WORKSPACES = "workspaces";
+ /** Timeout in seconds for REST sessions. */
+ private static final String KEY_SESSION_TIMEOUT = "session.timeout";
+ private static final int DEFAULT_SESSION_TIMEOUT = 300; // in seconds.
/** Alias that redirects to the latest version automatically. */
private static final String LATEST_FOLDER = "latest";
@@ -65,6 +75,8 @@ public class RESTClientServlet extends H
private volatile LogService m_logger;
private volatile WorkspaceManager m_workspaceManager;
+
+ private volatile int m_sessionTimeout = DEFAULT_SESSION_TIMEOUT;
private final Gson m_gson;
@@ -126,6 +138,7 @@ public class RESTClientServlet extends H
*/
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ HttpSession session = getSession(req);
String[] pathElements = getPathElements(req);
if (pathElements == null || pathElements.length < 1 ||
!WORK_FOLDER.equals(pathElements[0])) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
@@ -142,6 +155,11 @@ public class RESTClientServlet extends H
if (pathElements.length == 2) {
try {
+ Set<String> workspaces = (Set<String>)
session.getAttribute(SESSION_KEY_WORKSPACES);
+ if (workspaces != null) {
+ workspaces.remove(workspace.getSessionID());
+ session.setAttribute(SESSION_KEY_WORKSPACES,
workspaces);
+ }
m_workspaceManager.removeWorkspace(id);
}
catch (IOException ioe) {
@@ -157,11 +175,21 @@ public class RESTClientServlet extends H
}
}
+ private HttpSession getSession(HttpServletRequest req) {
+ HttpSession session = req.getSession(false);
+ if (session == null) {
+ session = req.getSession(true);
+ session.setMaxInactiveInterval(m_sessionTimeout); //
seconds
+ }
+ return session;
+ }
+
/**
* @see
javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ HttpSession session = getSession(req);
String[] pathElements = getPathElements(req);
if (pathElements == null || pathElements.length == 0) {
// TODO return a list of versions
@@ -225,6 +253,7 @@ public class RESTClientServlet extends H
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ HttpSession session = getSession(req);
String[] pathElements = getPathElements(req);
if (pathElements == null || pathElements.length < 1 ||
!WORK_FOLDER.equals(pathElements[0])) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
@@ -233,10 +262,16 @@ public class RESTClientServlet extends H
if (pathElements.length == 1) {
Workspace workspace =
m_workspaceManager.createWorkspace(req.getParameterMap(), req);
- if(workspace == null) {
+ if (workspace == null) {
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
else {
+ Set<String> workspaces = (Set<String>)
session.getAttribute(SESSION_KEY_WORKSPACES);
+ if (workspaces == null) {
+ workspaces = new HashSet<>();
+ }
+ workspaces.add(workspace.getSessionID());
+ session.setAttribute(SESSION_KEY_WORKSPACES, workspaces);
resp.sendRedirect(req.getServletPath() + "/" +
buildPathFromElements(WORK_FOLDER, workspace.getSessionID()));
}
}
@@ -270,6 +305,7 @@ public class RESTClientServlet extends H
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ HttpSession session = getSession(req);
String[] pathElements = getPathElements(req);
if (pathElements == null || pathElements.length != 4 ||
!WORK_FOLDER.equals(pathElements[0])) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
@@ -549,7 +585,49 @@ public class RESTClientServlet extends H
@Override
public void updated(Dictionary properties) throws ConfigurationException {
- // TODO Does anything need to happen here when the service endpoint is
updated?
- }
-
- }
+ if (properties == null) {
+ // defaults
+ m_sessionTimeout = DEFAULT_SESSION_TIMEOUT;
+ }
+ else {
+ try {
+ Object timeoutObject =
properties.get(KEY_SESSION_TIMEOUT);
+ if (timeoutObject instanceof Integer) {
+ m_sessionTimeout = (Integer) timeoutObject;
+ }
+ else {
+ m_sessionTimeout =
Integer.parseInt(timeoutObject.toString());
+ }
+ if (m_sessionTimeout < 1) {
+ m_sessionTimeout = DEFAULT_SESSION_TIMEOUT;
+ throw new
ConfigurationException(KEY_SESSION_TIMEOUT, "Session timeout should be at least
1 second");
+ }
+ }
+ catch (Exception e) {
+ throw new ConfigurationException(KEY_SESSION_TIMEOUT,
"Could not parse timeout, it should either be a string or integer");
+ }
+ }
+ }
+
+ @Override
+ public void sessionCreated(HttpSessionEvent e) {
+ }
+
+ @Override
+ public void sessionDestroyed(HttpSessionEvent e) {
+ HttpSession session = e.getSession();
+ if (session != null) {
+ Set<String> workspaces = (Set<String>)
session.getAttribute(SESSION_KEY_WORKSPACES);
+ if (workspaces != null) {
+ for (String id : workspaces) {
+ try {
+
m_workspaceManager.removeWorkspace(id);
+ }
+ catch (IOException ioe) {
+
m_logger.log(LogService.LOG_WARNING, "Error while removing workspace after
session timeout", ioe);
+ }
+ }
+ }
+ }
+ }
+}
Modified:
ace/trunk/org.apache.ace.client.workspace/src/org/apache/ace/client/workspace/impl/Activator.java
URL:
http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.workspace/src/org/apache/ace/client/workspace/impl/Activator.java?rev=1586741&r1=1586740&r2=1586741&view=diff
==============================================================================
---
ace/trunk/org.apache.ace.client.workspace/src/org/apache/ace/client/workspace/impl/Activator.java
(original)
+++
ace/trunk/org.apache.ace.client.workspace/src/org/apache/ace/client/workspace/impl/Activator.java
Fri Apr 11 18:33:58 2014
@@ -29,7 +29,6 @@ import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
public class Activator extends DependencyActivatorBase {
-
/**
* Identifier for configuration settings.
*/
@@ -41,10 +40,10 @@ public class Activator extends Dependenc
props.put(CommandProcessor.COMMAND_SCOPE, "ace");
props.put(CommandProcessor.COMMAND_FUNCTION, new String[] { "cw",
"gw", "rw" });
manager.add(createComponent().setInterface(WorkspaceManager.class.getName(),
props)
- .setImplementation(WorkspaceManagerImpl.class)
-
.add(createServiceDependency().setService(SessionFactory.class).setRequired(true))
-
.add(createConfigurationDependency().setPropagate(true).setPid(WORKSPACE_PID))
-
.add(createServiceDependency().setService(LogService.class).setRequired(false)));
+ .setImplementation(WorkspaceManagerImpl.class)
+
.add(createServiceDependency().setService(SessionFactory.class).setRequired(true))
+
.add(createConfigurationDependency().setPropagate(true).setPid(WORKSPACE_PID))
+
.add(createServiceDependency().setService(LogService.class).setRequired(false)));
}
@Override
Modified: ace/trunk/run-client/conf/org.apache.ace.client.rest.cfg
URL:
http://svn.apache.org/viewvc/ace/trunk/run-client/conf/org.apache.ace.client.rest.cfg?rev=1586741&r1=1586740&r2=1586741&view=diff
==============================================================================
--- ace/trunk/run-client/conf/org.apache.ace.client.rest.cfg (original)
+++ ace/trunk/run-client/conf/org.apache.ace.client.rest.cfg Fri Apr 11
18:33:58 2014
@@ -1,3 +1,2 @@
org.apache.ace.server.servlet.endpoint=/client
-
-
+session.timeout=300
Modified: ace/trunk/run-server-allinone/conf/org.apache.ace.client.rest.cfg
URL:
http://svn.apache.org/viewvc/ace/trunk/run-server-allinone/conf/org.apache.ace.client.rest.cfg?rev=1586741&r1=1586740&r2=1586741&view=diff
==============================================================================
--- ace/trunk/run-server-allinone/conf/org.apache.ace.client.rest.cfg (original)
+++ ace/trunk/run-server-allinone/conf/org.apache.ace.client.rest.cfg Fri Apr
11 18:33:58 2014
@@ -0,0 +1,2 @@
+org.apache.ace.server.servlet.endpoint=/client
+session.timeout=300