modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
| 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
| 143 ++++++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/LocatableHStack.java
| 82 +++++
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
| 2
modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
| 45 +--
modules/enterprise/server/jar/pom.xml
| 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionLogManagerBean.java
| 16 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionManagerBean.java
| 16 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDampeningManagerBean.java
| 16 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
| 16 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/CachedConditionManagerBean.java
| 18 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/CloudManagerBean.java
| 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StatusManagerBean.java
| 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/CacheConsistencyManagerBean.java
| 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/ServerManagerBean.java
| 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
| 14
pom.xml
| 6
17 files changed, 363 insertions(+), 82 deletions(-)
New commits:
commit 1ab97b2da8e9fc950f18feaaa59f7d3c10020127
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Fri May 6 12:17:04 2011 -0400
on the 10 SLSB's containing one or methods that are invoked directly or indirectly
by an MDB or EJB timer, use the PoolClass annotation to tell the EJB container to use the
strict max pool, rather than the threadlocal pool, for those SLSB's; this avoids SLSB
instances from accumulating and eventually filling up the entire heap
(
https://bugzilla.redhat.com/show_bug.cgi?id=693232)
diff --git a/modules/enterprise/server/jar/pom.xml
b/modules/enterprise/server/jar/pom.xml
index 5b9ff73..c6ebed5 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -233,6 +233,15 @@
<scope>provided</scope> <!-- by JBossAS -->
</dependency>
+ <!-- includes the org.jboss.ejb3.StrictMaxPool class, which is needed by the
PoolClass annotation used on some
+ of our SLSB's -->
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>jboss-ejb3</artifactId>
+ <!-- NOTE: The version is defined in the root POM's dependencyManagement
section. -->
+ <scope>provided</scope> <!-- by JBossAS -->
+ </dependency>
+
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-j2ee</artifactId>
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionLogManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionLogManagerBean.java
index ba54373..0804736 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionLogManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionLogManagerBean.java
@@ -34,6 +34,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.exception.ConstraintViolationException;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionLog;
import org.rhq.core.domain.alert.AlertDampeningEvent;
@@ -44,8 +46,20 @@ import org.rhq.enterprise.server.RHQConstants;
/**
* @author Joseph Marques
*/
-
@Stateless
+// NOTE: The AlertConditionLogManagerBean, AlertConditionManagerBean,
AlertDampeningManagerBean,
+// AlertDefinitionManagerBean, and CachedConditionManagerBean SLSB's are all
invoked, either directly or
+// indirectly, by the AlertConditionConsumerBean MDB. Since MDB invocations are
always done in new threads, using
+// the default SLSB pool impl ({@link ThreadlocalPool}) would cause a new instance
of this SLSB to be created
+// every time it was invoked by AlertConditionConsumerBean. This would be bad
because an existing instance would
+// not be reused, but it is really bad because the instance would also never get
destroyed, causing heap space to
+// gradually leak until the Server eventually ran out of memory. Hence, we must use
a {@link StrictMaxPool}, which
+// will use a fixed pool of instances of this SLSB, instead of a ThreadlocalPool.
Because most of these SLSB's are
+// also invoked by other callers (i.e. Agents, GUI's, or CLI's) besides
AlertConditionConsumerBean, we set the max
+// pool size to 60, which is double the default value, to minimize the chances of
AlertConditionConsumerBean
+// invocations, which are the most critical, from having to block and potentially
getting backed up in the queue.
+// For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232 (ips,
05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class AlertConditionLogManagerBean implements AlertConditionLogManagerLocal {
private final Log log = LogFactory.getLog(AlertConditionLogManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionManagerBean.java
index 5bb5861..3d49479 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertConditionManagerBean.java
@@ -32,6 +32,8 @@ import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
import org.rhq.core.domain.alert.AlertDefinition;
@@ -48,8 +50,20 @@ import org.rhq.enterprise.server.authz.PermissionException;
/**
* @author Joseph Marques
*/
-
@Stateless
+// NOTE: The AlertConditionLogManagerBean, AlertConditionManagerBean,
AlertDampeningManagerBean,
+// AlertDefinitionManagerBean, and CachedConditionManagerBean SLSB's are all
invoked, either directly or
+// indirectly, by the AlertConditionConsumerBean MDB. Since MDB invocations are
always done in new threads, using
+// the default SLSB pool impl ({@link ThreadlocalPool}) would cause a new instance
of this SLSB to be created
+// every time it was invoked by AlertConditionConsumerBean. This would be bad
because an existing instance would
+// not be reused, but it is really bad because the instance would also never get
destroyed, causing heap space to
+// gradually leak until the Server eventually ran out of memory. Hence, we must use
a {@link StrictMaxPool}, which
+// will use a fixed pool of instances of this SLSB, instead of a ThreadlocalPool.
Because most of these SLSB's are
+// also invoked by other callers (i.e. Agents, GUI's, or CLI's) besides
AlertConditionConsumerBean, we set the max
+// pool size to 60, which is double the default value, to minimize the chances of
AlertConditionConsumerBean
+// invocations, which are the most critical, from having to block and potentially
getting backed up in the queue.
+// For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232 (ips,
05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class AlertConditionManagerBean implements AlertConditionManagerLocal {
private static final Log LOG = LogFactory.getLog(AlertConditionManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDampeningManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDampeningManagerBean.java
index 1645efc..5df78c5 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDampeningManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDampeningManagerBean.java
@@ -31,6 +31,8 @@ import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.alert.AlertDampening;
import org.rhq.core.domain.alert.AlertDampeningEvent;
import org.rhq.core.domain.alert.AlertDefinition;
@@ -40,8 +42,20 @@ import org.rhq.enterprise.server.RHQConstants;
/**
* @author Joseph Marques
*/
-
@Stateless
+// NOTE: The AlertConditionLogManagerBean, AlertConditionManagerBean,
AlertDampeningManagerBean,
+// AlertDefinitionManagerBean, and CachedConditionManagerBean SLSB's are all
invoked, either directly or
+// indirectly, by the AlertConditionConsumerBean MDB. Since MDB invocations are
always done in new threads, using
+// the default SLSB pool impl ({@link ThreadlocalPool}) would cause a new instance
of this SLSB to be created
+// every time it was invoked by AlertConditionConsumerBean. This would be bad
because an existing instance would
+// not be reused, but it is really bad because the instance would also never get
destroyed, causing heap space to
+// gradually leak until the Server eventually ran out of memory. Hence, we must use
a {@link StrictMaxPool}, which
+// will use a fixed pool of instances of this SLSB, instead of a ThreadlocalPool.
Because most of these SLSB's are
+// also invoked by other callers (i.e. Agents, GUI's, or CLI's) besides
AlertConditionConsumerBean, we set the max
+// pool size to 60, which is double the default value, to minimize the chances of
AlertConditionConsumerBean
+// invocations, which are the most critical, from having to block and potentially
getting backed up in the queue.
+// For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232 (ips,
05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class AlertDampeningManagerBean implements AlertDampeningManagerLocal {
private final Log log = LogFactory.getLog(AlertDampeningManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
index 1cd2a71..ba3b045 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java
@@ -34,6 +34,8 @@ import org.apache.commons.logging.LogFactory;
import org.jboss.annotation.IgnoreDependency;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
import org.rhq.core.domain.alert.AlertConditionLog;
@@ -66,8 +68,20 @@ import
org.rhq.enterprise.server.util.CriteriaQueryGenerator.AuthorizationTokenT
/**
* @author Joseph Marques
*/
-
@Stateless
+// NOTE: The AlertConditionLogManagerBean, AlertConditionManagerBean,
AlertDampeningManagerBean,
+// AlertDefinitionManagerBean, and CachedConditionManagerBean SLSB's are all
invoked, either directly or
+// indirectly, by the AlertConditionConsumerBean MDB. Since MDB invocations are
always done in new threads, using
+// the default SLSB pool impl ({@link ThreadlocalPool}) would cause a new instance
of this SLSB to be created
+// every time it was invoked by AlertConditionConsumerBean. This would be bad
because an existing instance would
+// not be reused, but it is really bad because the instance would also never get
destroyed, causing heap space to
+// gradually leak until the Server eventually ran out of memory. Hence, we must use
a {@link StrictMaxPool}, which
+// will use a fixed pool of instances of this SLSB, instead of a ThreadlocalPool.
Because most of these SLSB's are
+// also invoked by other callers (i.e. Agents, GUI's, or CLI's) besides
AlertConditionConsumerBean, we set the max
+// pool size to 60, which is double the default value, to minimize the chances of
AlertConditionConsumerBean
+// invocations, which are the most critical, from having to block and potentially
getting backed up in the queue.
+// For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232 (ips,
05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
AlertDefinitionManagerRemote {
private static final Log LOG = LogFactory.getLog(AlertDefinitionManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/CachedConditionManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/CachedConditionManagerBean.java
index 9f757e1..55aa2a4 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/CachedConditionManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/CachedConditionManagerBean.java
@@ -28,6 +28,8 @@ import javax.persistence.PersistenceContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.alert.AlertDampeningEvent;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.enterprise.server.RHQConstants;
@@ -36,12 +38,26 @@ import
org.rhq.enterprise.server.alert.engine.jms.model.ActiveAlertConditionMess
import org.rhq.enterprise.server.alert.engine.jms.model.InactiveAlertConditionMessage;
/**
- * see {@link
CachedConditionManagerLocal#processCachedConditionMessage(AbstractAlertConditionMessage,
AlertDefinition)}
+ * see {@link CachedConditionManagerLocal#processCachedConditionMessage(
+ * org.rhq.enterprise.server.alert.engine.jms.model.AbstractAlertConditionMessage,
Integer)}
* for more information.
*
* @author Joseph Marques
*/
@Stateless
+// NOTE: The AlertConditionLogManagerBean, AlertConditionManagerBean,
AlertDampeningManagerBean,
+// AlertDefinitionManagerBean, and CachedConditionManagerBean SLSB's are all
invoked, either directly or
+// indirectly, by the AlertConditionConsumerBean MDB. Since MDB invocations are
always done in new threads, using
+// the default SLSB pool impl ({@link ThreadlocalPool}) would cause a new instance
of this SLSB to be created
+// every time it was invoked by AlertConditionConsumerBean. This would be bad
because an existing instance would
+// not be reused, but it is really bad because the instance would also never get
destroyed, causing heap space to
+// gradually leak until the Server eventually ran out of memory. Hence, we must use
a {@link StrictMaxPool}, which
+// will use a fixed pool of instances of this SLSB, instead of a ThreadlocalPool.
Because most of these SLSB's are
+// also invoked by other callers (i.e. Agents, GUI's, or CLI's) besides
AlertConditionConsumerBean, we set the max
+// pool size to 60, which is double the default value, to minimize the chances of
AlertConditionConsumerBean
+// invocations, which are the most critical, from having to block and potentially
getting backed up in the queue.
+// For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232 (ips,
05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class CachedConditionManagerBean implements CachedConditionManagerLocal {
private final Log log = LogFactory.getLog(CachedConditionManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/CloudManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/CloudManagerBean.java
index 4b98c67..919149d 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/CloudManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/CloudManagerBean.java
@@ -32,6 +32,8 @@ import org.apache.commons.logging.LogFactory;
import org.jboss.annotation.IgnoreDependency;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.cloud.FailoverListDetails;
@@ -56,6 +58,18 @@ import org.rhq.enterprise.server.util.LookupUtil;
* @author Joseph Marques
*/
@Stateless
+// NOTE: The CacheConsistencyManagerBean, CloudManagerBean, ServerManagerBean,
StatusManagerBean, and SystemManagerBean
+// SLSB's are all invoked, either directly or indirectly, by EJB timers. Since
EJB timer invocations are always
+// done in new threads, using the default SLSB pool impl ({@link ThreadlocalPool})
would cause a new instance of
+// this SLSB to be created every time it was invoked by an EJB timer. This would be
bad because an existing
+// instance would not be reused, but it is really bad because the instance would
also never get destroyed, causing
+// heap space to gradually leak until the Server eventually ran out of memory.
Hence, we must use a
+// {@link StrictMaxPool}, which will use a fixed pool of instances of this SLSB,
instead of a ThreadlocalPool.
+// Because most of these SLSB's are also invoked by other callers (i.e. Agents,
GUI's, or CLI's) besides EJB
+// timers, we set the max pool size to 60, which is double the default value, to
minimize the chances of EJB
+// timer invocations, which are the most critical, from having to block and
potentially getting backed up in the
+// queue. For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232
(ips, 05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class CloudManagerBean implements CloudManagerLocal {
private final Log log = LogFactory.getLog(CloudManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StatusManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StatusManagerBean.java
index dfd1990..526f801 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StatusManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StatusManagerBean.java
@@ -33,6 +33,8 @@ import org.apache.commons.logging.LogFactory;
import org.jboss.annotation.IgnoreDependency;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.cloud.Server;
@@ -65,6 +67,18 @@ import org.rhq.enterprise.server.util.LookupUtil;
* require holding these locks as part of their processing.
*/
@Stateless
+// NOTE: The CacheConsistencyManagerBean, CloudManagerBean, ServerManagerBean,
StatusManagerBean, and SystemManagerBean
+// SLSB's are all invoked, either directly or indirectly, by EJB timers. Since
EJB timer invocations are always
+// done in new threads, using the default SLSB pool impl ({@link ThreadlocalPool})
would cause a new instance of
+// this SLSB to be created every time it was invoked by an EJB timer. This would be
bad because an existing
+// instance would not be reused, but it is really bad because the instance would
also never get destroyed, causing
+// heap space to gradually leak until the Server eventually ran out of memory.
Hence, we must use a
+// {@link StrictMaxPool}, which will use a fixed pool of instances of this SLSB,
instead of a ThreadlocalPool.
+// Because most of these SLSB's are also invoked by other callers (i.e. Agents,
GUI's, or CLI's) besides EJB
+// timers, we set the max pool size to 60, which is double the default value, to
minimize the chances of EJB
+// timer invocations, which are the most critical, from having to block and
potentially getting backed up in the
+// queue. For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232
(ips, 05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class StatusManagerBean implements StatusManagerLocal {
private final Log log = LogFactory.getLog(StatusManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/CacheConsistencyManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/CacheConsistencyManagerBean.java
index 2de7bad..6cbf361 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/CacheConsistencyManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/CacheConsistencyManagerBean.java
@@ -34,6 +34,8 @@ import javax.ejb.TransactionAttributeType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.enterprise.server.alert.engine.AlertConditionCacheManagerLocal;
/**
@@ -44,6 +46,18 @@ import
org.rhq.enterprise.server.alert.engine.AlertConditionCacheManagerLocal;
* @author Joseph Marques
*/
@Stateless
+// NOTE: The CacheConsistencyManagerBean, CloudManagerBean, ServerManagerBean,
StatusManagerBean, and SystemManagerBean
+// SLSB's are all invoked, either directly or indirectly, by EJB timers. Since
EJB timer invocations are always
+// done in new threads, using the default SLSB pool impl ({@link ThreadlocalPool})
would cause a new instance of
+// this SLSB to be created every time it was invoked by an EJB timer. This would be
bad because an existing
+// instance would not be reused, but it is really bad because the instance would
also never get destroyed, causing
+// heap space to gradually leak until the Server eventually ran out of memory.
Hence, we must use a
+// {@link StrictMaxPool}, which will use a fixed pool of instances of this SLSB,
instead of a ThreadlocalPool.
+// Because most of these SLSB's are also invoked by other callers (i.e. Agents,
GUI's, or CLI's) besides EJB
+// timers, we set the max pool size to 60, which is double the default value, to
minimize the chances of EJB
+// timer invocations, which are the most critical, from having to block and
potentially getting backed up in the
+// queue. For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232
(ips, 05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class CacheConsistencyManagerBean implements CacheConsistencyManagerLocal {
private final Log log = LogFactory.getLog(CacheConsistencyManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/ServerManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/ServerManagerBean.java
index be91c65..588d8e8 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/ServerManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/instance/ServerManagerBean.java
@@ -38,6 +38,8 @@ import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.annotation.ejb.PoolClass;
+import org.jboss.ejb3.StrictMaxPool;
import org.rhq.core.domain.cloud.PartitionEventType;
import org.rhq.core.domain.cloud.Server;
import org.rhq.core.domain.resource.Agent;
@@ -64,6 +66,18 @@ import
org.rhq.enterprise.server.core.comm.ServerCommunicationsServiceUtil;
* @author Joseph Marques
*/
@Stateless
+// NOTE: The CacheConsistencyManagerBean, CloudManagerBean, ServerManagerBean,
StatusManagerBean, and SystemManagerBean
+// SLSB's are all invoked, either directly or indirectly, by EJB timers. Since
EJB timer invocations are always
+// done in new threads, using the default SLSB pool impl ({@link ThreadlocalPool})
would cause a new instance of
+// this SLSB to be created every time it was invoked by an EJB timer. This would be
bad because an existing
+// instance would not be reused, but it is really bad because the instance would
also never get destroyed, causing
+// heap space to gradually leak until the Server eventually ran out of memory.
Hence, we must use a
+// {@link StrictMaxPool}, which will use a fixed pool of instances of this SLSB,
instead of a ThreadlocalPool.
+// Because most of these SLSB's are also invoked by other callers (i.e. Agents,
GUI's, or CLI's) besides EJB
+// timers, we set the max pool size to 60, which is double the default value, to
minimize the chances of EJB
+// timer invocations, which are the most critical, from having to block and
potentially getting backed up in the
+// queue. For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232
(ips, 05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class ServerManagerBean implements ServerManagerLocal {
private final Log log = LogFactory.getLog(ServerManagerBean.class);
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
index 19a454a..a03f525 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/system/SystemManagerBean.java
@@ -51,7 +51,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.annotation.IgnoreDependency;
+import org.jboss.annotation.ejb.PoolClass;
import org.jboss.deployment.MainDeployerMBean;
+import org.jboss.ejb3.StrictMaxPool;
import org.jboss.mx.util.MBeanServerLocator;
import org.rhq.core.db.DatabaseType;
@@ -74,6 +76,18 @@ import org.rhq.enterprise.server.util.LookupUtil;
import org.rhq.enterprise.server.util.SystemDatabaseInformation;
@Stateless
+// NOTE: The CacheConsistencyManagerBean, CloudManagerBean, ServerManagerBean,
StatusManagerBean, and SystemManagerBean
+// SLSB's are all invoked, either directly or indirectly, by EJB timers. Since
EJB timer invocations are always
+// done in new threads, using the default SLSB pool impl ({@link ThreadlocalPool})
would cause a new instance of
+// this SLSB to be created every time it was invoked by an EJB timer. This would be
bad because an existing
+// instance would not be reused, but it is really bad because the instance would
also never get destroyed, causing
+// heap space to gradually leak until the Server eventually ran out of memory.
Hence, we must use a
+// {@link StrictMaxPool}, which will use a fixed pool of instances of this SLSB,
instead of a ThreadlocalPool.
+// Because most of these SLSB's are also invoked by other callers (i.e. Agents,
GUI's, or CLI's) besides EJB
+// timers, we set the max pool size to 60, which is double the default value, to
minimize the chances of EJB
+// timer invocations, which are the most critical, from having to block and
potentially getting backed up in the
+// queue. For more details, see
https://bugzilla.redhat.com/show_bug.cgi?id=693232
(ips, 05/05/11).
+@PoolClass(value = StrictMaxPool.class, maxSize = 60)
public class SystemManagerBean implements SystemManagerLocal, SystemManagerRemote {
private final String SQL_VACUUM = "VACUUM ANALYZE {0}";
diff --git a/pom.xml b/pom.xml
index 3c49e2d..98a9c31 100644
--- a/pom.xml
+++ b/pom.xml
@@ -219,6 +219,12 @@
<dependency>
<groupId>jboss</groupId>
+ <artifactId>jboss-ejb3</artifactId>
+ <version>${jboss.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>jboss</groupId>
<artifactId>jboss-ejb3-client</artifactId>
<version>${jboss.version}</version>
</dependency>
commit b4c21e2fc5e99d8886fb4431713c4d548f95de50
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Fri May 6 11:52:18 2011 -0400
re-implement top menu bar using SmartGWT widgets, rather than raw HTML (part of fix
for
https://bugzilla.redhat.com/show_bug.cgi?id=697590)
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index 09ca49b..85f5e92 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -146,7 +146,7 @@ public class CoreGUI implements EntryPoint,
ValueChangeHandler<String>, Event.Na
UserSessionManager.login();
- // removing loading image, which can be seen if LoginView doesn't completely
cover it
+ // Remove loading image, which can be seen if LoginView doesn't completely
cover it.
Element loadingPanel = DOM.getElementById("Loading-Panel");
loadingPanel.removeFromParent();
}
@@ -163,8 +163,8 @@ public class CoreGUI implements EntryPoint,
ValueChangeHandler<String>, Event.Na
String url = element.getAttribute("href");
String viewPath = getViewPath(url);
if (viewPath != null) {
- GWT.log("Forcing CoreGUI.goToView(\"" +
viewPath + "\")...");
- CoreGUI.goToView(viewPath);
+ GWT.log("Forcing History.newItem(\"" +
viewPath + "\")...");
+ History.newItem(viewPath);
nativeEvent.preventDefault();
}
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
index 58fd490..557042f 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -21,14 +21,15 @@ package org.rhq.enterprise.gui.coregui.client.menu;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.ui.Hyperlink;
import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.Img;
+import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
@@ -40,13 +41,17 @@ import
org.rhq.enterprise.gui.coregui.client.dashboard.DashboardsView;
import org.rhq.enterprise.gui.coregui.client.help.HelpView;
import org.rhq.enterprise.gui.coregui.client.inventory.InventoryView;
import org.rhq.enterprise.gui.coregui.client.report.ReportTopView;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableHStack;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableLabel;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
+
+import java.util.HashMap;
+import java.util.Map;
/**
* @author Greg Hinkle
* @author Joseph Marques
+ * @author Ian Springer
*/
public class MenuBarView extends LocatableVLayout {
@@ -80,7 +85,7 @@ public class MenuBarView extends LocatableVLayout {
markForRedraw();
}
- // When redrawing, ensire the correct session infor is displayed
+ // When redrawing, ensure the correct session info is displayed
@Override
public void markForRedraw() {
String currentDisplayName = userLabel.getContents();
@@ -104,50 +109,7 @@ public class MenuBarView extends LocatableVLayout {
}
private Canvas getLinksSection() {
- final HTMLFlow linksPane = new HTMLFlow();
- linksPane.setContents(setupLinks());
-
- History.addValueChangeHandler(new ValueChangeHandler<String>() {
- public void onValueChange(ValueChangeEvent<String>
stringValueChangeEvent) {
- String first =
stringValueChangeEvent.getValue().split("/")[0];
-
- if ("Resource".equals(first)) {
- first = "Inventory";
- }
-
- currentlySelectedSection = first;
- linksPane.setContents(setupLinks());
- linksPane.markForRedraw();
- }
- });
- return linksPane;
- }
-
- private String setupLinks() {
- // TODO: Replace the below HTML with SmartGWT widgets.
- StringBuilder headerString = new StringBuilder(
- "<table style=\"height: 34px;\" cellpadding=\"0\"
cellspacing=\"0\"><tr>");
-
- headerString.append("<td style=\"width: 1px;\"><img
src=\"images/header/header_bg_line.png\"/></td>");
- for (ViewName sectionName : SECTIONS) {
-
- String styleClass = "TopSectionLink";
- if (sectionName.getName().equals(currentlySelectedSection)) {
- styleClass = "TopSectionLinkSelected";
- }
-
- // Set explicit identifiers because the generated scLocator is not getting
picked up by Selenium.
- headerString.append("<td style=\"vertical-align:middle\"
id=\"").append(sectionName).append("\" class=\"")
- .append(styleClass).append("\"
onclick=\"window.location.href='#").append(sectionName).append("'\"
>");
- headerString.append(sectionName.getTitle());
- headerString.append("</td>\n");
-
- headerString.append("<td style=\"width: 1px;\"><img
src=\"images/header/header_bg_line.png\"/></td>");
- }
-
- headerString.append("</tr></table>");
-
- return headerString.toString();
+ return new LinkBar();
}
private Canvas getActionsSection() {
@@ -158,13 +120,13 @@ public class MenuBarView extends LocatableVLayout {
userLabel = new LocatableLabel(this.extendLocatorId("User"),
UserSessionManager.getSessionSubject().getName());
userLabel.setAutoWidth();
- LocatableLabel lineLabel = new
LocatableLabel(this.extendLocatorId("Line"), " | ");
- lineLabel.setWidth("10px");
+ Label lineLabel = new Label(" | ");
+ lineLabel.setWidth("12px");
lineLabel.setAlign(Alignment.CENTER);
- Hyperlink logoutLink = SeleniumUtility.setHtmlId(new
Hyperlink(LOGOUT_VIEW_ID.getTitle(), LOGOUT_VIEW_ID
- .getName()), LOGOUT_VIEW_ID.getName());
- logoutLink.setWidth("50px");
+ String contents = "<a href='#" + LOGOUT_VIEW_ID.getName() +
"'>" + LOGOUT_VIEW_ID.getTitle() + "</a>";
+ LocatableLabel logoutLink = new
LocatableLabel(this.extendLocatorId("LogoutLink"), contents);
+ logoutLink.setAutoWidth();
layout.addMember(userLabel);
layout.addMember(lineLabel);
@@ -173,4 +135,77 @@ public class MenuBarView extends LocatableVLayout {
return layout;
}
+ class LinkBar extends LocatableHStack implements ValueChangeHandler<String> {
+ private final Map<String, VLayout> sectionNameToLinkVLayoutMap = new
HashMap<String, VLayout>();
+
+ LinkBar() {
+ super(MenuBarView.this.extendLocatorId("LinkBar"));
+
+ setWidth100();
+ setHeight100();
+
+ Img divider = new Img("header/header_bg_line.png");
+ divider.setWidth(1);
+ divider.setHeight100();
+ addMember(divider);
+
+ for (ViewName sectionName : SECTIONS) {
+ VLayout linkVLayout = new VLayout();
+ linkVLayout.setHeight100();
+ linkVLayout.setAlign(VerticalAlignment.CENTER);
+
+ String contents = "<a class='menuBar' href='#" +
sectionName.getName() + "'>" + sectionName.getTitle()
+ + "</a>";
+ LocatableLabel link = new
LocatableLabel(extendLocatorId(sectionName.getName()), contents);
+ link.setAutoHeight();
+ link.setAlign(Alignment.CENTER);
+ link.setStyleName("inheritColor");
+ linkVLayout.addMember(link);
+
+ this.sectionNameToLinkVLayoutMap.put(sectionName.getName(),
linkVLayout);
+ updateLinkStyle(sectionName.getName());
+ addMember(linkVLayout);
+
+ divider = new Img("header/header_bg_line.png");
+ divider.setWidth(1);
+ divider.setHeight100();
+ addMember(divider);
+ }
+
+ History.addValueChangeHandler(this);
+ }
+
+ @Override
+ public void onValueChange(ValueChangeEvent<String> stringValueChangeEvent)
{
+ String viewPath = stringValueChangeEvent.getValue();
+ String topViewId = viewPath.split("/")[0];
+ if ("Resource".equals(topViewId)) {
+ topViewId = InventoryView.VIEW_ID.getName();
+ }
+ currentlySelectedSection = topViewId;
+
+ for (String sectionName : this.sectionNameToLinkVLayoutMap.keySet()) {
+ updateLinkStyle(sectionName);
+ }
+ }
+
+ private void updateLinkStyle(String sectionName) {
+ String divStyleClass;
+ String styleClass;
+ if (sectionName.equals(currentlySelectedSection)) {
+ divStyleClass = "TopSectionLinkDivSelected";
+ styleClass = "TopSectionLinkSelected";
+ } else {
+ divStyleClass = "TopSectionLinkDiv";
+ styleClass = "TopSectionLink";
+ }
+ VLayout linkVLayout = this.sectionNameToLinkVLayoutMap.get(sectionName);
+ linkVLayout.setStyleName(divStyleClass);
+ linkVLayout.markForRedraw();
+ Canvas link = linkVLayout.getMember(0);
+ link.setStyleName(styleClass);
+ link.markForRedraw();
+ }
+ }
+
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/LocatableHStack.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/LocatableHStack.java
new file mode 100644
index 0000000..4ea7bb1
--- /dev/null
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/selenium/LocatableHStack.java
@@ -0,0 +1,82 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2011 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.util.selenium;
+
+import com.smartgwt.client.widgets.layout.HStack;
+
+/**
+ * Wrapper for a SmartGWT {@link HStack} that sets the ID for use with Selenium
scLocators.
+ *
+ * @author Ian Springer
+ */
+public class LocatableHStack extends HStack implements Locatable {
+
+ private String locatorId;
+
+ /**
+ * <pre>
+ * ID Format: "simpleClassname_locatorId"
+ * </pre>
+ * @param locatorId not null or empty.
+ */
+ public LocatableHStack(String locatorId) {
+ super();
+ init(locatorId);
+ }
+
+ /**
+ * <pre>
+ * ID Format: "simpleClassname_locatorId"
+ * </pre>
+ * @param locatorId not null or empty.
+ * @param membersMargin
+ */
+ public LocatableHStack(String locatorId, int membersMargin) {
+ super(membersMargin);
+ init(locatorId);
+ }
+
+ private void init(String locatorId) {
+ this.locatorId = locatorId;
+ SeleniumUtility.setID(this, locatorId);
+ }
+
+ public String getLocatorId() {
+ return locatorId;
+ }
+
+ public String extendLocatorId(String extension) {
+ return this.locatorId + "_" + extension;
+ }
+
+ public void destroyMembers() {
+ SeleniumUtility.destroyMembers(this);
+ }
+
+ @Override
+ public void destroy() {
+ destroyMembers();
+ super.destroy();
+ }
+
+}
diff --git
a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
index f63dbd9..c2ba874 100644
---
a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
+++
b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
@@ -10,7 +10,7 @@
<inherits name='com.smartgwt.SmartGwt' />
<inherits name="com.smartgwt.tools.SmartGwtTools"/>
- <inherits name='com.google.gwt.user.theme.standard.Standard'/>
+ <!--<inherits
name='com.google.gwt.user.theme.standard.Standard'/>-->
<!--
<inherits name="com.smartclient.theme.graphite.Graphite"/>
-->
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
index f6befb0..7c86907 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
+++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
@@ -1,13 +1,8 @@
-/*body {
- background-color: white;
- color: black;
- font-family: Arial, sans-serif;
- font-size: small;
- margin: 8px;
-}*/
+body {
+ color: #010101;
+}
body, p, td, th, option, input, textarea, select {
- color: #000000;
font-family: tahoma, verdana, sans-serif !important;
font-size: 11px !important;
}
@@ -30,6 +25,9 @@ hr {
a, a:link, a:visited, a:hover {
color: #4A5D75 !important;
font-weight: bold !important;
+}
+
+a, a:link, a:visited {
text-decoration: none !important;
}
@@ -37,6 +35,10 @@ a:hover {
text-decoration: underline !important;
}
+a.menuBar, a.menuBar:link, a.menuBar:visited, a.menuBar:hover {
+ color: inherit !important;
+}
+
.backLink {
color: #4A5D75;
@@ -97,22 +99,27 @@ a:hover {
}
-.TopSectionLink, .topsectionlinkselected {
- vertical-align: bottom;
- padding:5px;
- padding-left: 15px;
- padding-right: 15px;
+.inheritColor {
+ color: inherit !important;
+}
- cursor: pointer;
- font-size: 10pt;
- font-weight: bold;
- text-decoration: none;
- color: #4A5D75;
+.TopSectionLink, .TopSectionLinkSelected {
+ font-size: 12px !important;
+}
+
+.TopSectionLink {
+ color: #4A5D75 !important;
}
.TopSectionLinkSelected {
+ color: white !important;
+}
+
+.TopSectionLinkDiv {
+}
+
+.TopSectionLinkDivSelected {
background-image: url('images/header/header_bg_selected.png');
- color: white;
}
.BreadCrumb {