You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2014/09/13 01:47:49 UTC
git commit: AMBARI-7221 - Ambari Server REST API Memory Leak
(jonathanhurley)
Repository: ambari
Updated Branches:
refs/heads/trunk 4209a4929 -> 33557337b
AMBARI-7221 - Ambari Server REST API Memory Leak (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/33557337
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/33557337
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/33557337
Branch: refs/heads/trunk
Commit: 33557337bb7bc917fa08509587031e077652803d
Parents: 4209a49
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 9 21:30:46 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Sep 12 19:47:24 2014 -0400
----------------------------------------------------------------------
ambari-server/conf/unix/ambari.properties | 3 ++
.../server/configuration/Configuration.java | 44 ++++++++++++++------
.../ambari/server/controller/AmbariServer.java | 22 +++++++---
3 files changed, 52 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/33557337/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index 41cada7..f1bb88c 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -53,3 +53,6 @@ agent.threadpool.size.max=25
# linux open-file limit
ulimit.open.files=10000
+
+# Server HTTP settings
+server.http.session.inactive_timeout=1800
http://git-wip-us.apache.org/repos/asf/ambari/blob/33557337/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 78fd7b6..9bdbc31 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -261,12 +261,11 @@ public class Configuration {
private static final String RESOURCES_DIR_DEFAULT =
"/var/lib/ambari-server/resources/";
private static final String ANONYMOUS_AUDIT_NAME_KEY = "anonymous.audit.name";
- private static final String CLIENT_SECURITY_DEFAULT = "local";
+
private static final int CLIENT_API_PORT_DEFAULT = 8080;
private static final int CLIENT_API_SSL_PORT_DEFAULT = 8443;
- private static final String USER_ROLE_NAME_DEFAULT = "user";
- private static final String ADMIN_ROLE_NAME_DEFAULT = "admin";
private static final String LDAP_BIND_ANONYMOUSLY_DEFAULT = "true";
+
//TODO For embedded server only - should be removed later
private static final String LDAP_PRIMARY_URL_DEFAULT = "localhost:33389";
private static final String LDAP_BASE_DN_DEFAULT = "dc=ambari,dc=apache,dc=org";
@@ -310,6 +309,8 @@ public class Configuration {
private static final String VIEW_EXTRACTION_THREADPOOL_TIMEOUT_KEY = "view.extraction.threadpool.timeout";
private static final long VIEW_EXTRACTION_THREADPOOL_TIMEOUT_DEFAULT = 100000L;
+ private static final String SERVER_HTTP_SESSION_INACTIVE_TIMEOUT = "server.http.session.inactive_timeout";
+
private static final Logger LOG = LoggerFactory.getLogger(
Configuration.class);
private Properties properties;
@@ -404,7 +405,7 @@ public class Configuration {
}
configsMap.put(SRVR_CRT_PASS_KEY, password);
- if (this.getApiSSLAuthentication()) {
+ if (getApiSSLAuthentication()) {
LOG.info("API SSL Authentication is turned on.");
File httpsPassFile = new File(configsMap.get(CLIENT_API_SSL_KSTR_DIR_NAME_KEY)
+ File.separator + configsMap.get(CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY));
@@ -467,14 +468,14 @@ public class Configuration {
private synchronized void loadCredentialProvider() {
if (!credentialProviderInitialized) {
try {
- this.credentialProvider = new CredentialProvider(null,
+ credentialProvider = new CredentialProvider(null,
getMasterKeyLocation(), isMasterKeyPersisted());
} catch (Exception e) {
LOG.info("Credential provider creation failed. Reason: " + e.getMessage());
if (LOG.isDebugEnabled()) {
e.printStackTrace();
}
- this.credentialProvider = null;
+ credentialProvider = null;
}
credentialProviderInitialized = true;
}
@@ -490,8 +491,9 @@ public class Configuration {
//Get property file stream from classpath
InputStream inputStream = Configuration.class.getClassLoader().getResourceAsStream(CONFIG_FILE);
- if (inputStream == null)
+ if (inputStream == null) {
throw new RuntimeException(CONFIG_FILE + " not found in classpath");
+ }
// load the properties
try {
@@ -534,8 +536,9 @@ public class Configuration {
public String getBootSetupAgentPassword() {
String pass = configsMap.get(PASSPHRASE_KEY);
- if (null != pass)
+ if (null != pass) {
return pass;
+ }
// fallback
return properties.getProperty(BOOTSTRAP_SETUP_AGENT_PASSWORD, "password");
@@ -688,8 +691,9 @@ public class Configuration {
public String getLocalDatabaseUrl() {
String dbName = properties.getProperty(SERVER_DB_NAME_KEY);
- if(dbName == null || dbName.isEmpty())
+ if(dbName == null || dbName.isEmpty()) {
throw new RuntimeException("Server DB Name is not configured!");
+ }
return JDBC_LOCAL_URL + dbName;
}
@@ -705,10 +709,11 @@ public class Configuration {
dbpasswd = readPasswordFromStore(passwdProp);
}
- if (dbpasswd != null)
+ if (dbpasswd != null) {
return dbpasswd;
- else
+ } else {
return readPasswordFromFile(passwdProp, SERVER_JDBC_USER_PASSWD_DEFAULT);
+ }
}
public String getRcaDatabaseDriver() {
@@ -727,8 +732,9 @@ public class Configuration {
String passwdProp = properties.getProperty(SERVER_JDBC_RCA_USER_PASSWD_KEY);
if (passwdProp != null) {
String dbpasswd = readPasswordFromStore(passwdProp);
- if (dbpasswd != null)
+ if (dbpasswd != null) {
return dbpasswd;
+ }
}
return readPasswordFromFile(passwdProp, SERVER_JDBC_RCA_USER_PASSWD_DEFAULT);
}
@@ -1084,4 +1090,18 @@ public class Configuration {
return Long.parseLong(properties.getProperty(
VIEW_EXTRACTION_THREADPOOL_TIMEOUT_KEY, String.valueOf(VIEW_EXTRACTION_THREADPOOL_TIMEOUT_DEFAULT)));
}
+
+ /**
+ * Gets the inactivity timeout value, in seconds, for sessions created in
+ * Jetty by Spring Security. Without this timeout value, each request to the
+ * REST APIs will create new sessions that are never reaped since their
+ * default time is -1.
+ *
+ * @return the time value or {@code 1800} seconds for default.
+ */
+ public int getHttpSessionInactiveTimeout() {
+ return Integer.parseInt(properties.getProperty(
+ SERVER_HTTP_SESSION_INACTIVE_TIMEOUT,
+ "1800"));
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/33557337/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index fc74e00..e109f7e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -230,8 +230,18 @@ public class AmbariServer {
root.setErrorHandler(injector.getInstance(AmbariErrorHandler.class));
root.getSessionHandler().setSessionManager(sessionManager);
- //Changing session cookie name to avoid conflicts
- root.getSessionHandler().getSessionManager().setSessionCookie("AMBARISESSIONID");
+ SessionManager jettySessionManager = root.getSessionHandler().getSessionManager();
+
+ // use AMBARISESSIONID instead of JSESSIONID to avoid conflicts with
+ // other services (like HDFS) that run on the same context but a different
+ // port
+ jettySessionManager.setSessionCookie("AMBARISESSIONID");
+
+ // each request that does not use AMBARISESSIONID will create a new
+ // HashedSession in Jetty; these MUST be reaped after inactivity in order
+ // to prevent a memory leak
+ int sessionInactivityTimeout = configs.getHttpSessionInactiveTimeout();
+ jettySessionManager.setMaxInactiveInterval(sessionInactivityTimeout);
GenericWebApplicationContext springWebAppContext = new GenericWebApplicationContext();
springWebAppContext.setServletContext(root.getServletContext());
@@ -246,8 +256,10 @@ public class AmbariServer {
certMan.initRootCert();
- ServletContextHandler agentroot = new ServletContextHandler(serverForAgent,
- "/", ServletContextHandler.SESSIONS );
+ // the agent communication (heartbeats, registration, etc) is stateless
+ // and does not use sessions.
+ ServletContextHandler agentroot = new ServletContextHandler(
+ serverForAgent, "/", ServletContextHandler.NO_SESSIONS);
ServletHolder rootServlet = root.addServlet(DefaultServlet.class, "/");
rootServlet.setInitParameter("dirAllowed", "false");
@@ -262,8 +274,8 @@ public class AmbariServer {
root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/proxy/*", 1);
root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/api/*", 1);
root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/proxy/*", 1);
- agentroot.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/agent/*", 1);
+ agentroot.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/agent/*", 1);
agentroot.addFilter(SecurityFilter.class, "/*", 1);
if (configs.getApiAuthentication()) {