[prev in list] [next in list] [prev in thread] [next in thread] 

List:       rhq-commits
Subject:    [rhq] Branch 'release-3.0.0-test-build' - 14 commits - modules/core modules/enterprise modules/plugi
From:       jshaughn () fedoraproject ! org (Jay Shaughnessy)
Date:       2010-06-30 14:20:33
Message-ID: 20100630142033.71700120267 () lists ! fedorahosted ! org
[Download RAW message or body]

 modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml                       \
|    4   modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml               \
|    6   modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java \
|   96 -  modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/ResultState.java \
|   14   modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SenderResult.java \
|  156 +  modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java \
|   13   modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertNotifications.jsp \
|   20   modules/enterprise/gui/portal-war/src/main/webapp/rhq/entity/layout/main.xhtml \
|    4   modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml \
|   95 -  modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml \
|   53   modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java \
|  155 -  modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java \
|    3   modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/CallTimeDataManagerBean.java \
|   10   modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitor.java \
|   20   modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitorMBean.java \
|    8   modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java \
|    1   modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertManagerBeanTest.java \
|    3   modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/scheduler/jobs/DataPurgeJobTest.java \
|    3   modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java \
|   31   modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java \
|   14   modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java \
|   29   modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java \
|  144 -  modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java \
|    4   modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java \
|   15   modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java \
|   31   modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java \
|   34   modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsSender.java \
|   31   modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java \
|  105 -  modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java \
|  842 ++++------  modules/plugins/nss/pom.xml                                        \
|  102 -  modules/plugins/nss/src/main/resources/META-INF/rhq-plugin.xml              \
|    4   modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml        \
|   33   release.sh                                                                   \
|   34   33 files changed, 1000 insertions(+), 1117 deletions(-)

New commits:
commit f936128d43eddab1a2b754ba4821ef1a3e1ecb57
Merge: f9d920d... f4dd6af...
Author: Jay Shaughnessy <jshaughn at redhat.com>
Date:   Wed Jun 30 10:19:35 2010 -0400

    Merge branch 'release-3.0.0-test-build' of ssh://git.fedorahosted.org/git/rhq/rhq \
into release-3.0.0-test-build



commit f9d920d56d03b7a0185224e155dd30a10f5b5538
Author: Heiko W. Rupp <hwr at redhat.com>
Date:   Wed Jun 30 14:28:15 2010 +0200

    Monitor call time values separately.

diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/CallTimeDataManagerBean.java \
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/CallTimeDataManagerBean.java
 index 253765d..08f3418 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/CallTimeDataManagerBean.java
                
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/CallTimeDataManagerBean.java
 @@ -125,12 +125,15 @@ public class CallTimeDataManagerBean implements \
CallTimeDataManagerLocal, CallTi  }
 
         log.debug("Persisting call-time data for " + callTimeDataSet.size() + " \
schedules..."); +        long startTime = System.currentTimeMillis();
 
         // First make sure a single row exists in the key table for each reported \
call destination.  callTimeDataManager.insertCallTimeDataKeys(callTimeDataSet);
 
         // Finally, add the stats themselves to the value table.
         callTimeDataManager.insertCallTimeDataValues(callTimeDataSet);
+        MeasurementMonitor.getMBean().incrementCallTimeInsertTime(System.currentTimeMillis() \
- startTime); +
     }
 
     @SuppressWarnings("unchecked")
@@ -408,7 +411,12 @@ public class CallTimeDataManagerBean implements \
                CallTimeDataManagerLocal, CallTi
             notifyAlertConditionCacheManager("insertCallTimeDataValues", \
                callTimeDataSet
                 .toArray(new CallTimeData[callTimeDataSet.size()]));
 
-            log.debug("Inserted " + ((insertedRowCount >= 0) ? insertedRowCount : \
"?") + " call-time data value rows."); +            if (insertedRowCount>0) {
+                MeasurementMonitor.getMBean().incrementCalltimeValuesInserted(insertedRowCount);
 +
+                log.debug("Inserted " +  insertedRowCount  + " call-time data value \
rows."); +            }
+
         } catch (SQLException e) {
             logSQLException("Failed to persist call-time data values", e);
         } catch (Throwable t) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitor.java \
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitor.java
 index 9ad1f24..3ff3a17 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitor.java
                
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitor.java
 @@ -35,6 +35,10 @@ public class MeasurementMonitor implements \
MeasurementMonitorMBean, MBeanRegistr  
     private AtomicLong measurementsInserted = new AtomicLong();
 
+    private AtomicLong callTimeInsertTime = new AtomicLong();
+
+    private AtomicLong calltimeValuesInserted = new AtomicLong();
+
     private AtomicLong availabilityInsertTime = new AtomicLong();
 
     private AtomicLong availabilitiesInserted = new AtomicLong();
@@ -101,6 +105,22 @@ public class MeasurementMonitor implements \
MeasurementMonitorMBean, MBeanRegistr  this.measurementsInserted.addAndGet(delta);
     }
 
+    public long getCalltimeValuesInserted() {
+        return calltimeValuesInserted.get();
+    }
+
+    public void incrementCalltimeValuesInserted(long delta) {
+        this.calltimeValuesInserted.addAndGet(delta);
+    }
+
+    public long getCallTimeInsertTime() {
+        return callTimeInsertTime.get();
+    }
+
+    public void incrementCallTimeInsertTime(long delta) {
+        this.callTimeInsertTime.addAndGet(delta);
+    }
+
     public long getAvailabilityInsertTime() {
         return availabilityInsertTime.get();
     }
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitorMBean.java \
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitorMBean.java
 index 04fc6cd..df7b05c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitorMBean.java
                
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/instrumentation/MeasurementMonitorMBean.java
 @@ -31,6 +31,14 @@ public interface MeasurementMonitorMBean {
 
     void incrementMeasurementsInserted(long delta);
 
+    long getCallTimeInsertTime();
+
+    void incrementCallTimeInsertTime(long delta);
+
+    long getCalltimeValuesInserted();
+
+    void incrementCalltimeValuesInserted(long delta);
+
     int getScheduledMeasurementsPerMinute();
 
     long getPurgeTime();
diff --git a/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml \
b/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml index \
                94db789..2ad0785 100644
--- a/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/rhq-server/src/main/resources/META-INF/rhq-plugin.xml
@@ -23,7 +23,7 @@
          <c:simple-property name="nameTemplate" default="Alert Subsystem"/>
          <c:simple-property name="descriptionTemplate" default="Statistics for the \
RHQ Server Alerts Engine Subsystem."/>  </plugin-configuration>
-      
+
       <operation name="reloadCaches" description="Unloads then reloads all caches \
managed by the containing RHQ Server">  <results>
             <c:list-property name="reloadStatistics">
@@ -75,7 +75,7 @@
               description="The total amount of time spent by the alerts cache \
                processing resource configuration data"/>
       <metric property="OperationProcessingTime" units="milliseconds" \
                displayType="summary" measurementType="trendsup"
               description="The total amount of time spent by the alerts cache \
                processing operation history data"/>
-      
+
    </service>
 
    <service name="RHQ Server Measurement Subsystem"
@@ -94,8 +94,13 @@
          <c:simple-property name="descriptionTemplate" default="Statistics for the \
RHQ Server Measurement Subsystem."/>  </plugin-configuration>
 
+      <metric property="CalltimeValuesInserted" category="throughput" \
displayType="summary" measurementType="trendsup" +              description="The \
total number of call time data records inserted into the database by this RHQ Server \
instance since it was started"/> +       <metric property="CallTimeInsertTime" \
units="milliseconds" displayType="summary" measurementType="trendsup" +               \
description="The total amount of time taken to insert call time data into the \
database by this RHQ Server instance since it was started"/> +
       <metric property="MeasurementsInserted" category="throughput" \
                displayType="summary" measurementType="trendsup"
-              description="The total number of measurement records inserted into the \
database by this RHQ Server instance since it was started"/> +              \
description="The total number of measurement records (incl. Calltime data) inserted \
into the database by this RHQ Server instance since it was started"/>  <metric \
                property="ScheduledMeasurementsPerMinute"
               description="The average number of measurements expected to be \
                collected per minute"/>
       <metric property="MeasurementInsertTime" units="milliseconds" \
displayType="summary" measurementType="trendsup" @@ -118,23 +123,23 @@
       <metric property="FullAvailabilityReports" displayType="summary" \
                measurementType="trendsup"
               description="The number of full availability reports received and \
processed by this RHQ Server since it was started"/>  
-      <metric property="PurgedAlerts" displayType="summary" \
measurementType="dynamic" category="utilization" defaultInterval="900000"  +      \
<metric property="PurgedAlerts" displayType="summary" measurementType="dynamic" \
                category="utilization" defaultInterval="900000"
               description="Number of alerts purged by the last purge job"/>
-      <metric property="PurgedAlertConditions" displayType="summary" \
measurementType="dynamic" category="utilization" defaultInterval="900000"  +      \
<metric property="PurgedAlertConditions" displayType="summary" \
                measurementType="dynamic" category="utilization" \
                defaultInterval="900000"
               description="Number of alert conditions purged by the last purge \
                job"/>
-      <metric property="PurgedAlertNotifications" displayType="summary" \
measurementType="dynamic" category="utilization" defaultInterval="900000"  +      \
<metric property="PurgedAlertNotifications" displayType="summary" \
                measurementType="dynamic" category="utilization" \
                defaultInterval="900000"
               description="Number of alert notifications purged by the last purge \
                job"/>
-      <metric property="PurgedAvailabilities" displayType="summary" \
measurementType="dynamic" category="utilization" defaultInterval="900000"  +      \
<metric property="PurgedAvailabilities" displayType="summary" \
                measurementType="dynamic" category="utilization" \
                defaultInterval="900000"
               description="Number of availabilities purged by the last purge job"/>
-      <metric property="PurgedCallTimeData" displayType="summary" \
measurementType="dynamic" category="utilization" defaultInterval="900000"  +      \
<metric property="PurgedCallTimeData" displayType="summary" measurementType="dynamic" \
                category="utilization" defaultInterval="900000"
               description="Number of call time data purged by the last purge job"/>
-      <metric property="PurgedEvents" displayType="summary" \
measurementType="dynamic" category="utilization" defaultInterval="900000"  +      \
<metric property="PurgedEvents" displayType="summary" measurementType="dynamic" \
                category="utilization" defaultInterval="900000"
               description="Number of events purged by the last purge job"/>
-      <metric property="PurgedMeasurementTraits" displayType="summary" \
measurementType="dynamic" category="utilization" defaultInterval="900000"  +      \
<metric property="PurgedMeasurementTraits" displayType="summary" \
                measurementType="dynamic" category="utilization" \
                defaultInterval="900000"
               description="Number of traits purged by the last purge job"/>
-      
+
    </service>
-   
+
    <service name="RHQ Server Group Definition / DynaGroups Subsystem"
             discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
             class="GroupDefinitionResourceComponent"
@@ -144,13 +149,13 @@
       <runs-inside>
          <parent-resource-type name="JBossAS Server" plugin="JBossAS"/>
       </runs-inside>
-      
+
       <plugin-configuration>
          <c:simple-property name="objectName" readOnly="true" \
                default="rhq:service=GroupDefinitionRecalculationThreadMonitor"/>
          <c:simple-property name="nameTemplate" default="Group Definition \
                Subsystem"/>
          <c:simple-property name="descriptionTemplate" default="Statistics for the \
RHQ Server Group Definition / DynaGroups Subsystem."/>  </plugin-configuration>
-      
+
       <operation name="clear" displayName="Clear Statistics" description="Clear the \
collected statistics, and start collecting anew"/>  
       <operation name="retrieveStatistics" description="View a snapshot of \
statistical information about the recalculation cost of each GroupDefinition in the \
system">


commit 894b6792a5f614d63b10703a726a29e4aab603e0
Author: Joseph Marques <joseph at redhat.com>
Date:   Wed Jun 30 03:26:37 2010 -0400

    BZ-602123: BZ-602270: various tweaks for alert notification processing
    
    * never allow any exceptions to bubble up during notification processing
    
    * add new UNKNOWN status for AlertNotificationLogs
    ** use the UNKNOWN state to catching mishaving plugins during alert processing
    
    * add new DEFERRED status for AlertNotificationLogs
    ** use the DEFERRED state or operations
    ** since we don't wait for the operation to complete, we don't know it's \
termination state)  
    * add new PARTIAL status for AlertNotificationLogs
    ** use it to represent mixed success/failures during email sending
    * * do not defer email sending anymore, execute during each notification \
                processing
    ** by processing them all upfront, easier to reason about terminating ResultState

diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml \
b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml index \
                a9ad342..bce92a3 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
@@ -96,11 +96,9 @@
         <index name="RHQ_ALERT_IDX_ALERT" unique="false">
             <field ref="ALERT_ID"/>
         </index>
-        <column name="SENDER" required="false" size="200" type="VARCHAR2"/>
+        <column name="SENDER" required="false" size="100" type="VARCHAR2"/>
         <column name="RESULT_STATE" required="false" size="20" type="VARCHAR2"/>
         <column name="MESSAGE" required="false" size="4000" type="VARCHAR2"/>
-        <column name="ALL_EMAILS" required="false" size="4000" type="VARCHAR2"/>
-        <column name="EMAILS_FAILED" required="false" size="4000" type="VARCHAR2"/>
     </table>
 
     <table name="RHQ_ALERT_CONDITION_LOG" \
                tablespace="@@@LARGE_TABLESPACE_FOR_DATA@@@"
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml \
b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index \
                daf68f4..7f8f9da 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -2062,6 +2062,7 @@
             </schemaSpec>
             <schemaSpec version="2.70.1">
                 <schema-addColumn table="RHQ_ALERT_NOTIFICATION" \
column="SENDER_NAME" precision="100" columnType="VARCHAR2" /> +                \
<schema-alterColumn table="RHQ_ALERT_NOTIFICATION" column="SENDER_NAME" \
                nullable="FALSE" />
                 <schema-addColumn table="RHQ_ALERT_NOTIFICATION" \
                column="SENDER_CONFIG_ID" columnType="INTEGER" />
                 <schema-addColumn table="RHQ_ALERT_NOTIFICATION" \
column="EXTRA_CONFIG_ID" columnType="INTEGER" />  <schema-directSQL>
@@ -2082,11 +2083,10 @@
                 </schema-directSQL>
             </schemaSpec>
             <schemaSpec version="2.70.2">
-                <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="SENDER" \
columnType="VARCHAR2" precision="200" /> +                <schema-addColumn \
table="RHQ_ALERT_NOTIF_LOG" column="SENDER" columnType="VARCHAR2" precision="100" /> \
+                <schema-alterColumn table="RHQ_ALERT_NOTIF_LOG" column="SENDER" \
                nullable="FALSE" />
                 <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="RESULT_STATE" \
                columnType="VARCHAR2" precision="20" />
                 <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="MESSAGE" \
                columnType="VARCHAR2" precision="4000" />
-                <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="ALL_EMAILS" \
                columnType="VARCHAR2" precision="4000" />
-                <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="EMAILS_FAILED" \
columnType="VARCHAR2" precision="4000" />  </schemaSpec>
             <schemaSpec version="2.70.3">
                 <schema-directSQL>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java \
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
 index 6e25431..de07675 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
                
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
 @@ -23,8 +23,6 @@
 package org.rhq.core.domain.alert.notification;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
@@ -41,13 +39,11 @@ import javax.persistence.PrePersist;
 import javax.persistence.PreUpdate;
 import javax.persistence.SequenceGenerator;
 import javax.persistence.Table;
-import javax.persistence.Transient;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlTransient;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.util.StringUtils;
 
 @Entity
 @NamedQueries( { @NamedQuery(name = \
AlertNotificationLog.QUERY_DELETE_BY_ALERT_CTIME, // @@ -90,23 +86,16 @@ public class \
AlertNotificationLog implements Serializable {  @XmlTransient
     private Alert alert;
 
+    @Column(name = "SENDER")
     private String sender;
 
     @Column(name = "RESULT_STATE")
     @Enumerated(EnumType.STRING)
     private ResultState resultState;
 
+    @Column(name = "MESSAGE")
     private String message;
 
-    @Column(name = "ALL_EMAILS")
-    private String allEmails;
-
-    @Column(name = "EMAILS_FAILED")
-    private String badEmails;
-
-    @Transient
-    transient List<String> transientEmails = new ArrayList<String>();
-
     @PrePersist
     @PreUpdate
     public void trimMessage() {
@@ -122,24 +111,45 @@ public class AlertNotificationLog implements Serializable {
         this.alert = alert;
         this.sender = sender;
         this.resultState = senderResult.getState();
-        this.message = senderResult.getMessage();
-        if (resultState == ResultState.DEFERRED_EMAIL && senderResult.getEmails() != \
                null) {
-            this.transientEmails.addAll(senderResult.getEmails());
-            this.allEmails = StringUtils.getListAsString(senderResult.getEmails(), \
                ",");
-        }
-    }
-
-    public AlertNotificationLog(Alert alert, String sender) {
-        this.alert = alert;
-        this.sender = sender;
-        this.resultState = ResultState.FAILURE; // Default if nothing specified
+        this.message = getMessage(senderResult);
     }
 
     public AlertNotificationLog(Alert alert, String senderName, ResultState state, \
String message) {  this.alert = alert;
+        this.sender = senderName;
         this.resultState = state;
         this.message = message;
+    }
+
+    private String getMessage(SenderResult result) {
+        StringBuilder builder = new StringBuilder();
 
+        boolean first = true;
+
+        if (result.getSummary() != null) {
+            first = false;
+            builder.append(result.getSummary());
+        }
+
+        for (String success : result.getSuccessMessages()) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append("<br/>");
+            }
+            builder.append(success);
+        }
+
+        for (String failure : result.getFailureMessages()) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append("<br/>");
+            }
+            builder.append(failure);
+        }
+
+        return builder.toString();
     }
 
     public int getId() {
@@ -150,10 +160,6 @@ public class AlertNotificationLog implements Serializable {
         return alert;
     }
 
-    public void setAlert(Alert alert) {
-        this.alert = alert;
-    }
-
     public String getSender() {
         return sender;
     }
@@ -166,38 +172,6 @@ public class AlertNotificationLog implements Serializable {
         return message;
     }
 
-    public String getAllEmails() {
-        return allEmails;
-    }
-
-    public String getBadEmails() {
-        return badEmails;
-    }
-
-    public void setResultState(ResultState resultState) {
-        this.resultState = resultState;
-    }
-
-    public void setMessage(String message) {
-        this.message = message;
-    }
-
-    public void setAllEmails(String allEmails) {
-        this.allEmails = allEmails;
-    }
-
-    public void setBadEmails(String badEmails) {
-        this.badEmails = badEmails;
-    }
-
-    public List<String> getTransientEmails() {
-        return transientEmails;
-    }
-
-    public void setTransientEmails(List<String> transientEmails) {
-        this.transientEmails = transientEmails;
-    }
-
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
@@ -207,8 +181,6 @@ public class AlertNotificationLog implements Serializable {
         sb.append(", sender='").append(sender).append('\'');
         sb.append(", resultState=").append(resultState);
         sb.append(", message='").append(message).append('\'');
-        sb.append(", allEmails='").append(allEmails).append('\'');
-        sb.append(", badEmails='").append(badEmails).append('\'');
         sb.append('}');
         return sb.toString();
     }
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/ResultState.java \
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/ResultState.java
 index 0c8d1bc..a2de159 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/ResultState.java
                
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/ResultState.java
 @@ -24,12 +24,14 @@ package org.rhq.core.domain.alert.notification;
  * @see SenderResult
  */
 public enum ResultState {
-    /** Success: sending of the notification was a success  */
+    /** Success: sending of the notification was a known success */
     SUCCESS,
-    /** Deferred_email: this sender itself was successful, but l8er email sending \
                may fail */
-    DEFERRED_EMAIL,
-    /** Failure: sending of the notification failed */
+    /** Partial: sending of the notification has some failures */
+    PARTIAL,
+    /** Failure: sending of the notification was a known failure */
     FAILURE,
-    /** Sending one ore more emails from the plugin failed */
-    FAILED_EMAIL
+    /** Deferred: sender action was invoked, but response can not be immediately \
determined */ +    DEFERRED,
+    /** Unknown: alert sender returned a null result */
+    UNKNOWN
 }
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SenderResult.java \
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SenderResult.java
 index b4ec8e1..7191636 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SenderResult.java
                
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/SenderResult.java
 @@ -27,88 +27,156 @@ import java.util.List;
  */
 public class SenderResult {
 
-    /** Message returned for logging purposes */
-    private String message;
-    /** Was calling the AlertSender.send() method successful? */
-    private ResultState state;
-    /** A list of email addresses that should be notified */
-    private List<String> emails = new ArrayList<String>();
-
-    /**
-     * Default constructor. State is FAILURE by default
+    /*
+     * the state is UNKNOWN by default, but will be determined as messages are \
added.  if only success messages  +     * are added, then the result is considered a \
SUCCESS.  if only failure messages are added, then the result +     * is considered a \
FAILURE.  if a mixed of success and failure messages are added, then the result is \
considered +     * PARTIAL.  the user is free to manually set 
      */
+    private boolean deferred;
+    private String summary; // can be set, will not affect calculated ResultState
+    private List<String> successMessages = new ArrayList<String>();
+    private List<String> failureMessages = new ArrayList<String>();
+
     public SenderResult() {
-        this.message = "No message set";
-        this.state = ResultState.FAILURE;
+        this.deferred = false;
+    }
+
+    public static SenderResult getSimpleSuccess(String message) {
+        SenderResult result = new SenderResult();
+        result.addSuccessMessage(message);
+        return result;
     }
 
-    public SenderResult(ResultState state, String message) {
-        this.message = message;
-        this.state = state;
+    public static SenderResult getSimpleFailure(String message) {
+        SenderResult result = new SenderResult();
+        result.addFailureMessage(message);
+        return result;
     }
 
-    public SenderResult(ResultState state, String message, List<String> emails) {
-        this.message = message;
-        this.state = state;
-        this.emails = emails;
+    public static SenderResult getSimpleDeffered(String message) {
+        SenderResult result = new SenderResult();
+        result.setSummary(message);
+        result.setDeffered();
+        return result;
     }
 
-    public String getMessage() {
-        return message;
+    public void setSummary(String summary) {
+        this.summary = summary;
     }
 
-    public void setMessage(String message) {
-        this.message = message;
+    public String getSummary() {
+        return summary;
     }
 
     public ResultState getState() {
-        return state;
+        if (deferred) {
+            return ResultState.DEFERRED;
+        }
+
+        if (successMessages.size() != 0) {
+            if (failureMessages.size() == 0) {
+                return ResultState.SUCCESS;
+            } else {
+                return ResultState.PARTIAL;
+            }
+        } else {
+            if (failureMessages.size() != 0) {
+                return ResultState.FAILURE;
+            }
+        }
+
+        return ResultState.UNKNOWN;
     }
 
-    public void setState(ResultState state) {
-        this.state = state;
+    public void setDeffered() {
+        deferred = true;
     }
 
-    public List<String> getEmails() {
-        return emails;
+    public void addSuccessMessage(String message) {
+        successMessages.add(message);
     }
 
-    public void setEmails(List<String> emails) {
-        this.emails = emails;
+    public List<String> getSuccessMessages() {
+        return successMessages;
     }
 
-    public void addEmail(String email) {
-        emails.add(email);
+    public void addFailureMessage(String message) {
+        failureMessages.add(message);
+    }
+
+    public List<String> getFailureMessages() {
+        return failureMessages;
     }
 
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
         sb.append("SenderResult");
-        sb.append("{message='").append(message).append('\'');
-        sb.append(", state=").append(state);
-        sb.append(", emails=").append(emails);
+        sb.append("{state=").append(getState());
+        sb.append(", summary=").append(summary);
+        sb.append(", successMessages=").append(successMessages);
+        sb.append(", failureMessages=").append(failureMessages);
         sb.append('}');
         return sb.toString();
     }
 
     @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        SenderResult that = (SenderResult) o;
-
-        if (message != null ? !message.equals(that.message) : that.message != null) \
                return false;
-        if (state != that.state) return false;
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        SenderResult other = (SenderResult) obj;
+
+        if (getState() != other.getState()) {
+            return false;
+        }
+
+        if (summary == null) {
+            if (other.summary != null) {
+                return false;
+            }
+        } else if (!summary.equals(other.summary)) {
+            return false;
+        }
+
+        if (failureMessages == null) {
+            if (other.failureMessages != null) {
+                return false;
+            }
+        } else if (!failureMessages.equals(other.failureMessages)) {
+            return false;
+        }
+
+        if (successMessages == null) {
+            if (other.successMessages != null) {
+                return false;
+            }
+        } else if (!successMessages.equals(other.successMessages)) {
+            return false;
+        }
 
         return true;
     }
 
     @Override
     public int hashCode() {
-        int result = message != null ? message.hashCode() : 0;
-        result = 31 * result + (state != null ? state.hashCode() : 0);
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((summary == null) ? 0 : summary.hashCode());
+        result = prime * result + ((failureMessages == null) ? 0 : \
failureMessages.hashCode()); +        result = prime * result + ((successMessages == \
null) ? 0 : successMessages.hashCode()); +        result = prime * result + \
(getState() != null ? getState().hashCode() : 0);  return result;
     }
+
 }
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java \
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
 index de4d5ea..6e5430f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
                
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
 @@ -38,7 +38,6 @@ import com.smartgwt.client.data.fields.DataSourceBooleanField;
 import com.smartgwt.client.data.fields.DataSourceIntegerField;
 import com.smartgwt.client.data.fields.DataSourceTextField;
 import com.smartgwt.client.rpc.RPCResponse;
-import com.smartgwt.client.types.FieldType;
 import com.smartgwt.client.widgets.grid.ListGrid;
 import com.smartgwt.client.widgets.grid.ListGridRecord;
 
@@ -99,13 +98,9 @@ public class AlertDataSource extends RPCDataSource<Alert> {
         resourceName.setCanSortClientOnly(true);
         fields.add(resourceName);
 
-
-//        DataSourceTextField recoveryInfoField = new \
                DataSourceTextField("recoveryInfo", "Recovery Info");
-//        recoveryInfoField.setCanSortClientOnly(true);
-//        fields.add(recoveryInfoField);
-
-
-
+        //        DataSourceTextField recoveryInfoField = new \
DataSourceTextField("recoveryInfo", "Recovery Info"); +        //        \
recoveryInfoField.setCanSortClientOnly(true); +        //        \
fields.add(recoveryInfoField);  
         // TODO: Will using DataSourceEnumField here allow us to do
         //       record.setAttribute("priority", \
alert.getAlertDefinition().getPriority()), rather than @@ -269,8 +264,6 @@ public \
class AlertDataSource extends RPCDataSource<Alert> {  dc.setAttribute("sender", \
log.getSender());  dc.setAttribute("status", log.getResultState());
             dc.setAttribute("message", log.getMessage());
-            dc.setAttribute("allEmails", log.getAllEmails());
-            dc.setAttribute("badEmails", log.getBadEmails());
 
             notifications[i++] = dc;
 
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertNotifications.jsp \
b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertNotifications.jsp
 index f228d2b..282db80 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertNotifications.jsp
                
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertNotifications.jsp
 @@ -15,20 +15,21 @@
     <c:choose>
         <c:when test="${not empty aNotifLogs }">
             <tr>
-                <td class="BlockLeftAlignLabel" width="10%">Sender</td>
-                <td class="BlockLeftAlignLabel" width="10%">Result</td>
-                <td class="BlockLeftAlignLabel" width="30%">Message</td>
-                <td class="BlockLeftAlignLabel" width="25%">All emails</td>
-                <td class="BlockLeftAlignLabel" width="25%">Failed emails</td>
+                <td class="BlockLeftAlignLabel" width="15%">Sender</td>
+                <td class="BlockLeftAlignLabel" width="15%">Result</td>
+                <td class="BlockLeftAlignLabel" width="70%">Message</td>
+            </tr>
+            <tr>
+                <td colspan="3" class="BlockBottomLine"><html:img \
page="/images/spacer.gif" width="1" height="1" border="0"/></td>  </tr>
             <c:forEach var="notif" items="${aNotifLogs}">
                 <tr valign="top">
                     <td class="BlockContent"><c:out value="${notif.sender}"/></td>
                     <td class="BlockContent"><c:out \
                value="${notif.resultState}"/></td>
                     <td class="BlockContent"><c:out escapeXml="false" \
                value="${fn:replace(fn:replace(notif.message, '&lt;', '<'), '&gt;', \
                '>')}"/></td>
-                    <td class="BlockContent"><c:out \
                value="${notif.allEmails}"/></td>
-                    <td class="BlockContent"><c:out \
                value="${notif.badEmails}"/></td>
-                <p/>
+                </tr>
+                <tr>
+                    <td colspan="3" class="BlockBottomLine"><html:img \
page="/images/spacer.gif" width="1" height="1" border="0"/></td>  </tr>
             </c:forEach>
         </c:when>
@@ -37,6 +38,9 @@
                <td class="BlockContent">
                   <strong>No notifications were specified for this alert's \
definition</strong>  </td>
+               <tr>
+                  <td class="BlockBottomLine"><html:img page="/images/spacer.gif" \
width="1" height="1" border="0"/></td> +               </tr>
             </tr>
         </c:otherwise>
     </c:choose>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java \
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
 index c856a24..108e2d5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
                
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
 @@ -27,7 +27,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.LinkedHashSet;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -67,7 +67,6 @@ import org.rhq.core.domain.resource.Resource;
 import org.rhq.core.domain.util.PageControl;
 import org.rhq.core.domain.util.PageList;
 import org.rhq.core.domain.util.PageOrdering;
-import org.rhq.core.domain.util.StringUtils;
 import org.rhq.core.server.MeasurementConverter;
 import org.rhq.core.server.PersistenceUtility;
 import org.rhq.core.util.collection.ArrayUtils;
@@ -654,94 +653,48 @@ public class AlertManagerBean implements AlertManagerLocal, \
AlertManagerRemote {  try {
             log.debug("Sending alert notifications for " + alert.toSimpleString() + \
                "...");
             List<AlertNotification> alertNotifications = \
                alert.getAlertDefinition().getAlertNotifications();
-            Set<String> emailAddresses = new LinkedHashSet<String>();
+            //Set<String> emailAddresses = new LinkedHashSet<String>();
 
             AlertSenderPluginManager alertSenderPluginManager = \
getAlertPluginManager();  
             for (AlertNotification alertNotification : alertNotifications) {
+                AlertNotificationLog notificationLog = null;
 
-                // Send over the new AlertSender plugins
                 String senderName = alertNotification.getSenderName();
                 if (senderName == null) {
-                    log.error("Alert notification " + alertNotification + " has no \
                sender name defined");
-                    continue;
-                }
-
-                AlertNotificationLog alNoLo;
-                AlertSender<?> sender = \
                alertSenderPluginManager.getAlertSenderForNotification(alertNotification);
                
-
-                if (sender != null) {
-                    try {
-                        SenderResult result = sender.send(alert);
-
-                        if (result == null) {
-                            log.warn("- !! -- sender [" + senderName
-                                + "] did not return a SenderResult. Please fix this \
                -- !! - ");
-                            alNoLo = new AlertNotificationLog(alert, senderName);
-                            alNoLo.setMessage("Sender did not return a SenderResult, \
assuming failure"); +                    notificationLog = new \
AlertNotificationLog(alert, senderName, ResultState.FAILURE, "Sender '" +             \
+ senderName + "' is not defined"); +                } else {
 
-                        } else if (result.getState() == ResultState.DEFERRED_EMAIL) \
{ +                    AlertSender<?> notificationSender = alertSenderPluginManager
+                        .getAlertSenderForNotification(alertNotification);
+                    if (notificationSender == null) {
+                        notificationLog = new AlertNotificationLog(alert, \
senderName, ResultState.FAILURE, +                            "Failed to obtain a \
sender with given name"); +                    } else {
+                        try {
+                            SenderResult result = notificationSender.send(alert);
+                            if (log.isDebugEnabled()) {
+                                log.debug(result);
+                            }
 
-                            alNoLo = new AlertNotificationLog(alert, senderName, \
                result);
-                            if (result.getEmails() != null && \
                !result.getEmails().isEmpty()) {
-                                emailAddresses.addAll(result.getEmails());
+                            if (result == null) {
+                                notificationLog = new AlertNotificationLog(alert, \
senderName, ResultState.UNKNOWN, +                                    "Sender did not \
return any result"); +                            } else {
+                                notificationLog = new AlertNotificationLog(alert, \
senderName, result);  }
-                        } else {
-                            alNoLo = new AlertNotificationLog(alert, senderName, \
result); +                        } catch (Throwable t) {
+                            log.error("Notification processing terminated abruptly" \
+ t.getMessage()); +                            notificationLog = new \
AlertNotificationLog(alert, senderName, ResultState.FAILURE, +                        \
"Notification processing terminated abruptly, cause: " + t.getMessage());  }
-                        log.debug(result);
-                    } catch (Throwable t) {
-                        log.error("Sender failed: " + t.getMessage());
-                        if (log.isDebugEnabled())
-                            log.debug("Sender " + sender.toString() + "failed: \n", \
                t);
-                        alNoLo = new AlertNotificationLog(alert, senderName, \
                ResultState.FAILURE,
-                            "Failed with exception: " + t.getMessage());
                     }
-                } else {
-                    alNoLo = new AlertNotificationLog(alert, senderName, \
                ResultState.FAILURE,
-                        "Failed to obtain a sender with given name");
                 }
-                entityManager.persist(alNoLo);
-                alert.addAlertNotificatinLog(alNoLo);
-            }
 
-            // send them off
-            Collection<String> badAddresses = null;
-            try {
-                badAddresses = sendAlertNotificationEmails(alert, emailAddresses);
-            } catch (Throwable t) {
-                badAddresses = new ArrayList<String>();
-                log.error("Could not send emails to " + emailAddresses + " for " + \
                alert + ", cause:", t);
-            }
-            // TODO we may do the same for SMS in the future.
-
-            // log those bad addresses to the gui and their individual senders (if \
                possible)
-            if (!badAddresses.isEmpty()) {
-                for (AlertNotificationLog anl : alert.getAlertNotificationLogs()) {
-                    if (!(anl.getResultState() == ResultState.DEFERRED_EMAIL))
-                        continue;
-
-                    List<String> badList = new ArrayList<String>();
-                    for (String badOne : badAddresses) {
-                        if (anl.getTransientEmails().contains(badOne)) {
-                            anl.setResultState(ResultState.FAILED_EMAIL);
-                            badList.add(badOne);
-                        }
-                    }
-                    if (anl.getResultState() == ResultState.FAILED_EMAIL)
-                        anl.setBadEmails(StringUtils.getListAsString(badList, ","));
-                    if (anl.getResultState() == ResultState.DEFERRED_EMAIL && \
                badList.isEmpty())
-                        anl.setResultState(ResultState.SUCCESS);
-                }
-            } else { // No bad addresses
-                // Only set the result state to success for email sending \
                notifications
-                // We must not set them if the notification failed.
-                for (AlertNotificationLog anl : alert.getAlertNotificationLogs()) {
-                    if (anl.getResultState() == ResultState.DEFERRED_EMAIL)
-                        anl.setResultState(ResultState.SUCCESS);
-                }
+                entityManager.persist(notificationLog);
+                alert.addAlertNotificatinLog(notificationLog);
             }
-
         } catch (Throwable t) {
             log.error("Failed to send all notifications for " + \
alert.toSimpleString(), t);  }
@@ -767,35 +720,37 @@ public class AlertManagerBean implements AlertManagerLocal, \
AlertManagerRemote {  return manager;
     }
 
-    /**
-     *
-     * @param alert
-     * @param emailAddresses
-     * @return
-     */
-    private Collection<String> sendAlertNotificationEmails(Alert alert, Set<String> \
emailAddresses) { +    public Collection<String> sendAlertNotificationEmails(Alert \
alert, Collection<String> emailAddresses) { +        log.debug("Sending alert \
notifications for " + alert.toSimpleString() + "...");  
-        if (emailAddresses.size() == 0)
+        if (emailAddresses.size() == 0) {
             return new ArrayList<String>(0); // No email to send -> no bad addresses
-
-        log.debug("Sending alert notifications for " + alert.toSimpleString() + \
"..."); +        }
 
         AlertDefinition alertDefinition = alert.getAlertDefinition();
         Map<String, String> alertMessage = emailManager.getAlertEmailMessage(
-            prettyPrintResourceHierarchy(alertDefinition.getResource()), \
                alertDefinition.getResource().getName(),
-            alertDefinition.getName(), alertDefinition.getPriority().toString(), new \
                Date(alert.getCtime()).toString(),
-            prettyPrintAlertConditions(alert.getConditionLogs(), false), \
prettyPrintAlertURL(alert)); +            \
prettyPrintResourceHierarchy(alertDefinition.getResource()), // +            \
alertDefinition.getResource().getName(), // +            alertDefinition.getName(), \
// +            alertDefinition.getPriority().toString(), //
+            new Date(alert.getCtime()).toString(), //
+            prettyPrintAlertConditions(alert.getConditionLogs(), false), //
+            prettyPrintAlertURL(alert));
+
         String messageSubject = alertMessage.keySet().iterator().next();
         String messageBody = alertMessage.values().iterator().next();
 
-        Collection<String> badAddresses;
-        badAddresses = emailManager.sendEmail(emailAddresses, messageSubject, \
messageBody); +        Set<String> uniqueAddresses = new \
HashSet<String>(emailAddresses); +        Collection<String> badAddresses = \
emailManager.sendEmail(uniqueAddresses, messageSubject, messageBody); +
         if (log.isDebugEnabled()) {
-            if (badAddresses.isEmpty())
+            if (badAddresses.isEmpty()) {
                 log.debug("All notifications for " + alert.toSimpleString() + " \
                succeeded");
-            else
+            } else {
                 log.debug("Sending email notifications for " + badAddresses + " \
failed"); +            }
         }
+
         return badAddresses;
     }
 
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java \
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java
 index f32c82e..528fdf5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java
                
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java
 @@ -18,6 +18,7 @@
  */
 package org.rhq.enterprise.server.alert;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -109,6 +110,8 @@ public interface AlertManagerLocal {
      */
     boolean willDefinitionBeDisabled(Alert alert);
 
+    Collection<String> sendAlertNotificationEmails(Alert alert, Collection<String> \
emailAddresses); +
     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     //
     // The following are shared with the Remote Interface
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java \
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
 index 5a958b1..de35d54 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
                
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
 @@ -161,4 +161,5 @@ public abstract class AlertSender<T extends \
ServerPluginComponent> {  }
         return builder.toString();
     }
+
 }
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertManagerBeanTest.java \
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertManagerBeanTest.java
 index 3d6ab03..79fcb3b 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertManagerBeanTest.java
                
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertManagerBeanTest.java
 @@ -35,6 +35,7 @@ import org.rhq.core.domain.alert.AlertDefinition;
 import org.rhq.core.domain.alert.AlertPriority;
 import org.rhq.core.domain.alert.BooleanExpression;
 import org.rhq.core.domain.alert.notification.AlertNotificationLog;
+import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.auth.Subject;
 import org.rhq.core.domain.resource.Agent;
 import org.rhq.core.domain.resource.Resource;
@@ -115,7 +116,7 @@ public class AlertManagerBeanTest extends AbstractEJB3Test {
                 Alert a = new Alert(ad, now);
                 em.persist(a);
 
-                AlertNotificationLog anl = new AlertNotificationLog(a, "dummy");
+                AlertNotificationLog anl = new AlertNotificationLog(a, "dummy", \
ResultState.SUCCESS, "message");  em.persist(anl);
 
             } catch (Exception e) {
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/scheduler/jobs/DataPurgeJobTest.java \
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/scheduler/jobs/DataPurgeJobTest.java
 index 7f06451..6f6ec38 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/scheduler/jobs/DataPurgeJobTest.java
                
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/scheduler/jobs/DataPurgeJobTest.java
 @@ -49,6 +49,7 @@ import org.rhq.core.domain.alert.AlertDefinition;
 import org.rhq.core.domain.alert.AlertPriority;
 import org.rhq.core.domain.alert.BooleanExpression;
 import org.rhq.core.domain.alert.notification.AlertNotificationLog;
+import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.auth.Subject;
 import org.rhq.core.domain.event.Event;
 import org.rhq.core.domain.event.EventDefinition;
@@ -427,7 +428,7 @@ public class DataPurgeJobTest extends AbstractEJB3Test {
         Alert a = new Alert(ad, timestamp);
         em.persist(a);
 
-        AlertNotificationLog anl = new AlertNotificationLog(a, "dummy");
+        AlertNotificationLog anl = new AlertNotificationLog(a, "dummy", \
ResultState.SUCCESS, "message");  em.persist(anl);
 
         AlertCondition ac = ad.getConditions().iterator().next();
diff --git a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java \
b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java
 index 81b1383..5b07b7b 100644
--- a/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java
                
+++ b/modules/enterprise/server/plugins/alert-email/src/main/java/org/rhq/enterprise/server/plugins/alertEmail/EmailSender.java
 @@ -18,12 +18,16 @@
  */
 package org.rhq.enterprise.server.plugins.alertEmail;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
+import org.rhq.enterprise.server.util.LookupUtil;
 
 /**
  * Class to send emails. Actually it does not do the work
@@ -37,11 +41,32 @@ public class EmailSender extends AlertSender {
     public SenderResult send(Alert alert) {
         String emailAddressString = alertParameters.getSimpleValue("emailAddress", \
null);  if (emailAddressString == null) {
-            return new SenderResult(ResultState.FAILURE, "No email address given");
+            return SenderResult.getSimpleFailure("No email address given");
         }
 
         List<String> emails = AlertSender.unfence(emailAddressString, String.class, \
                ",");
-        return new SenderResult(ResultState.DEFERRED_EMAIL, "Sending to addresses: " \
+ emails, emails); +        try {
+            Set<String> uniqueEmails = new HashSet<String>(emails);
+            Collection<String> badEmails = LookupUtil.getAlertManager()
+                .sendAlertNotificationEmails(alert, uniqueEmails);
+
+            List<String> goodEmails = new ArrayList<String>(uniqueEmails);
+            goodEmails.removeAll(badEmails);
+
+            SenderResult result = new SenderResult();
+            result.setSummary("Target addresses were: " + uniqueEmails);
+            if (goodEmails.size() > 0) {
+                result.addSuccessMessage("Successfully sent to: " + goodEmails);
+            }
+            if (badEmails.size() > 0) {
+                result.addFailureMessage("Failed to send to: " + badEmails);
+            }
+            return result;
+        } catch (Throwable t) {
+            return SenderResult.getSimpleFailure("Error sending email notifications \
to " + emails + ", cause: " +                + t.getMessage());
+        }
+
     }
 
     @Override
diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java \
b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
 index 95abdb9..d0a48bf 100644
--- a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
                
+++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
 @@ -22,7 +22,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.enterprise.server.alert.AlertManagerLocal;
 import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
@@ -39,20 +38,17 @@ public class IrcSender extends AlertSender<IrcAlertComponent> {
 
     @Override
     public SenderResult send(Alert alert) {
-        SenderResult result;
         String channel = this.alertParameters.getSimpleValue("channel", null);
-        String server = preferences.getSimpleValue("server","-not set-");
+        String server = preferences.getSimpleValue("server", "-not set-");
         String chan = "irc://" + server + "/" + channel;
 
         try {
             this.pluginComponent.sendIrcMessage(channel, getIrcMessage(alert));
-            result = new SenderResult(ResultState.SUCCESS, "IRC Alert sent to \
                channel [" + chan + "].");
-        } catch (IllegalStateException e) {
-            log.error(e.getMessage());
-            result = new SenderResult(ResultState.FAILURE, "IRC Alert to [" + chan + \
"] failed! " + e.getMessage()); +            return \
SenderResult.getSimpleSuccess("IRC Alert sent to channel [" + chan + "]."); +        \
} catch (Throwable t) { +            log.error(t.getMessage());
+            return SenderResult.getSimpleFailure("IRC Alert to [" + chan + "] \
failed! " + t.getMessage());  }
-
-        return result;
     }
 
     private String getIrcMessage(Alert alert) {
diff --git a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java \
b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
 index b13763e..37f724a 100644
--- a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
                
+++ b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
 @@ -18,20 +18,19 @@
  */
 package org.rhq.enterprise.server.plugins.alertMicroblog;
 
-import twitter4j.Status;
-import twitter4j.Twitter;
-import twitter4j.TwitterException;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.enterprise.server.alert.AlertManagerLocal;
 import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
 import org.rhq.enterprise.server.util.LookupUtil;
 
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
 /**
  * Send alert notifications via Microblogging services like Twitter or laconi.ca
  * @author Heiko W. Rupp
@@ -43,12 +42,12 @@ public class MicroblogSender extends AlertSender {
     @Override
     public SenderResult send(Alert alert) {
 
-        String user = preferences.getSimpleValue("user",null);
-        String password = preferences.getSimpleValue("password",null);
-        String baseUrl = \
preferences.getSimpleValue("microblogServerUrl","http://twitter.com/"); +        \
String user = preferences.getSimpleValue("user", null); +        String password = \
preferences.getSimpleValue("password", null); +        String baseUrl = \
preferences.getSimpleValue("microblogServerUrl", "http://twitter.com/");  if \
                (!baseUrl.endsWith("/"))
-           baseUrl = baseUrl +"/";
-        Twitter twitter = new Twitter(user,password,baseUrl);
+            baseUrl = baseUrl + "/";
+        Twitter twitter = new Twitter(user, password, baseUrl);
         AlertManagerLocal alertManager = LookupUtil.getAlertManager();
         twitter.setSource("Jopr");
         StringBuilder b = new StringBuilder("Alert ");
@@ -61,22 +60,20 @@ public class MicroblogSender extends AlertSender {
         b.append("-by @JBossJopr"); // TODO not for production :-)
         // TODO use some alert url shortening service
 
-        SenderResult result ;
         String txt = "user at baseUrl [" + user + "@" + baseUrl + "]:";
         try {
             String msg = b.toString();
-            if (msg.length()>140)
-                msg = msg.substring(0,140);
+            if (msg.length() > 140)
+                msg = msg.substring(0, 140);
 
             Status status = twitter.updateStatus(msg);
 
-            result = new SenderResult(ResultState.SUCCESS,"Send notification to " + \
txt + ", msg-id: " + status.getId()); +            return \
SenderResult.getSimpleSuccess("Send notification to " + txt + ", msg-id: " + \
status.getId());  } catch (TwitterException e) {
 
             log.warn("Notification via Microblog failed for " + txt + " ", e);
-            result = new SenderResult(ResultState.FAILURE,"Sending failed :" + \
e.getMessage()); +            return SenderResult.getSimpleFailure("Sending failed :" \
+ e.getMessage());  
         }
-        return result;
     }
 }
diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java \
b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
 index b14c85d..4884e3a 100644
--- a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
                
+++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
 @@ -28,7 +28,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.core.domain.resource.Resource;
 import org.rhq.enterprise.server.alert.AlertManagerLocal;
@@ -46,13 +45,13 @@ public class MobicentsSender extends AlertSender {
     @Override
     public SenderResult send(Alert alert) {
 
-        String baseUrl = \
                preferences.getSimpleValue("mobicentsServerUrl","http://localhost:8080/mobicents");
                
-        String tel = alertParameters.getSimpleValue("targetAddress",null);
-        if (tel==null) {
+        String baseUrl = preferences.getSimpleValue("mobicentsServerUrl", \
"http://localhost:8080/mobicents"); +        String tel = \
alertParameters.getSimpleValue("targetAddress", null); +        if (tel == null) {
             log.warn("No number to call given, not sending");
-            return new SenderResult(ResultState.FAILURE, "No target address given");
+            return SenderResult.getSimpleFailure("No target address given");
         }
-        String kindString = alertParameters.getSimpleValue("kind","VOICE");
+        String kindString = alertParameters.getSimpleValue("kind", "VOICE");
         MobiKind kind = MobiKind.valueOf(kindString);
 
         Integer alertId = alert.getId();
@@ -61,81 +60,81 @@ public class MobicentsSender extends AlertSender {
         AlertManagerLocal alertManager = LookupUtil.getAlertManager();
 
         switch (kind) {
-            case VOICE:
-                b.append("Alert on resource ");
-                do {
-                    b.append(res.getName());
-                    res = res.getParentResource();
-                    if (res!=null)
-                        b.append(" with parent ");
-                } while (res!=null);
-                b.append(". Cause is ");
-
-                // Switch locale to english, as the voice synthesizer expects this \
                for now
-                Locale currentLocale = Locale.getDefault();
-                Locale.setDefault(Locale.ENGLISH);
-                b.append(alertManager.prettyPrintAlertConditions(alert, false));
-                Locale.setDefault(currentLocale);
-
-                boolean willBeDisabled = \
                alertManager.willDefinitionBeDisabled(alert);
-
-                if (willBeDisabled)
-                    b.append(" The alert definition will now be disabled. \n\n");
-
-    //            b.append(" Please press ");
-    //
-    //            if (willBeDisabled) {
-    //                b.append(AlertFeedback.REENABLE.getText());
-    //            } else {
-    //                b.append(AlertFeedback.DISABLE.getText());
-    //            }
-    //            b.append(", ");
-    //            b.append(AlertFeedback.DELETE.getText());
-    //            b.append(" or just hang up to do nothing.");
-                break;
-            case SMS:
-                b.append("Alert: ");
+        case VOICE:
+            b.append("Alert on resource ");
+            do {
                 b.append(res.getName());
-                b.append(",id=(").append(res.getId()).append(")");
-                b.append("Brought by RHQ");
-                break;
-            default:
-                log.warn("Unsupported Mobicents notification type for now");
+                res = res.getParentResource();
+                if (res != null)
+                    b.append(" with parent ");
+            } while (res != null);
+            b.append(". Cause is ");
+
+            // Switch locale to english, as the voice synthesizer expects this for \
now +            Locale currentLocale = Locale.getDefault();
+            Locale.setDefault(Locale.ENGLISH);
+            b.append(alertManager.prettyPrintAlertConditions(alert, false));
+            Locale.setDefault(currentLocale);
+
+            boolean willBeDisabled = alertManager.willDefinitionBeDisabled(alert);
+
+            if (willBeDisabled)
+                b.append(" The alert definition will now be disabled. \n\n");
+
+            //            b.append(" Please press ");
+            //
+            //            if (willBeDisabled) {
+            //                b.append(AlertFeedback.REENABLE.getText());
+            //            } else {
+            //                b.append(AlertFeedback.DISABLE.getText());
+            //            }
+            //            b.append(", ");
+            //            b.append(AlertFeedback.DELETE.getText());
+            //            b.append(" or just hang up to do nothing.");
+            break;
+        case SMS:
+            b.append("Alert: ");
+            b.append(res.getName());
+            b.append(",id=(").append(res.getId()).append(")");
+            b.append("Brought by RHQ");
+            break;
+        default:
+            log.warn("Unsupported Mobicents notification type for now");
         }
 
         URL url;
-        int code=0;
+        int code = 0;
         HttpURLConnection conn = null;
         try {
             tel = tel.trim();
-            String telEnc = URLEncoder.encode(tel,"UTF-8"); // url encode tel-no, as \
it can contain '+' +            String telEnc = URLEncoder.encode(tel, "UTF-8"); // \
url encode tel-no, as it can contain '+'  switch (kind) {
-                case SMS:
-                    baseUrl = baseUrl + "sms"; // No trailing '/' !
-                    break;
-                case VOICE:
-                    baseUrl = baseUrl + "call"; // No trailing '/' !
-                    break;
-                default:
-                    baseUrl = baseUrl + "--not-supported-yet--";
+            case SMS:
+                baseUrl = baseUrl + "sms"; // No trailing '/' !
+                break;
+            case VOICE:
+                baseUrl = baseUrl + "call"; // No trailing '/' !
+                break;
+            default:
+                baseUrl = baseUrl + "--not-supported-yet--";
             }
-            baseUrl = baseUrl +"?alertId="+alertId;
-            baseUrl = baseUrl +"&tel=";
-            if (kind==MobiKind.VOICE) {
+            baseUrl = baseUrl + "?alertId=" + alertId;
+            baseUrl = baseUrl + "&tel=";
+            if (kind == MobiKind.VOICE) {
                 if (!tel.startsWith("sip:")) {
-                    baseUrl = baseUrl +"sip:";
+                    baseUrl = baseUrl + "sip:";
                 }
             }
-            baseUrl = baseUrl +telEnc;
-            if (kind==MobiKind.VOICE) {
+            baseUrl = baseUrl + telEnc;
+            if (kind == MobiKind.VOICE) {
                 if (!tel.contains("@")) { // Append domain from preferences if user \
                has none provided
-                    String domain = \
preferences.getSimpleValue("defaultVoipDomain","localhost"); +                    \
String domain = preferences.getSimpleValue("defaultVoipDomain", "localhost");  \
baseUrl = baseUrl + "@" + domain;  }
             }
             // TODO SMS url
 
-            log.info("Mobicents alert ["+ kind + "] to baseUrl [" + baseUrl + "] \
with message:\n" + b.toString()); +            log.info("Mobicents alert [" + kind + \
"] to baseUrl [" + baseUrl + "] with message:\n" + b.toString());  url = new \
URL(baseUrl);  conn = (HttpURLConnection) url.openConnection();
             conn.setRequestMethod("POST");
@@ -151,20 +150,17 @@ public class MobicentsSender extends AlertSender {
             code = conn.getResponseCode();
         } catch (Exception e) {
             log.warn("Notification via VoIP failed: " + e);
-            return new SenderResult(ResultState.FAILURE,"Sending failed " + \
                e.getMessage());
-        }
-        finally {
-            if (conn!=null)
+            return SenderResult.getSimpleFailure("Sending failed " + \
e.getMessage()); +        } finally {
+            if (conn != null)
                 conn.disconnect();
         }
-        SenderResult result;
-        if (code!=200) {
+
+        if (code != 200) {
             log.info("Notification via Mobicents returned code " + code);
-            result=new SenderResult(ResultState.FAILURE,"Notification via Mobicents \
                returned code " + code);
-        }
-        else {
-            result=new SenderResult(ResultState.SUCCESS,"Mobicents alert ["+ kind + \
"] to baseUrl [" + baseUrl + "]" ); +            return \
SenderResult.getSimpleFailure("Notification via Mobicents returned code " + code); +  \
} else { +            return SenderResult.getSimpleSuccess("Mobicents alert [" + kind \
+ "] to baseUrl [" + baseUrl + "]");  }
-        return result;
     }
 }
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java \
b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
 index 21c3bfe..cdf03ac 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
                
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
 @@ -67,7 +67,9 @@ public class AlertTokenReplacer {
         String work = input;
         Matcher matcher = pattern.matcher(work);
         if (!matcher.find()) {
-            log.warn("No tokens found in " + input);
+            if (log.isDebugEnabled()) {
+                log.debug("No tokens found in " + input);
+            }
             return input;
         }
         matcher.reset();
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java \
b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
 index 83563e6..e50b143 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
                
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
 @@ -19,7 +19,6 @@
 package org.rhq.enterprise.server.plugins.alertOperations;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.core.domain.auth.Subject;
 import org.rhq.core.domain.configuration.Configuration;
@@ -47,7 +46,7 @@ public class OperationsSender extends AlertSender {
 
         OperationInfo info = OperationInfo.load(alertParameters, extraParameters);
         if (info.error != null) {
-            return new SenderResult(ResultState.FAILURE, info.error);
+            return SenderResult.getSimpleFailure(info.error);
         }
 
         Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO get \
real subject for authz? @@ -61,7 +60,7 @@ public class OperationsSender extends \
AlertSender {  } catch (Throwable t) {
             String message = getResultMessage(info, "could not calculate which \
resources to execute the operation on: "  + t.getMessage());
-            return new SenderResult(ResultState.FAILURE, message);
+            return SenderResult.getSimpleFailure(message);
         }
 
         Configuration replacedParameters = null;
@@ -79,7 +78,7 @@ public class OperationsSender extends AlertSender {
             }
         } catch (Exception e) {
             String message = getResultMessage(info, "parameterized argument \
                replacement failed with " + e.getMessage());
-            return new SenderResult(ResultState.FAILURE, message);
+            return SenderResult.getSimpleFailure(message);
         }
 
         // Now fire off the operation with no delay and no repetition.
@@ -89,13 +88,17 @@ public class OperationsSender extends AlertSender {
                 targetResource.getId(), operation.getName(), 0, 0, 0, 0, \
                replacedParameters, description);
             String message = getResultMessage(info, \
getHyperLinkForOperationSchedule(subject, targetResource.getId(),  \
                operation.getName(), schedule.getJobId()));
-            return new SenderResult(ResultState.SUCCESS, message);
+            return SenderResult.getSimpleDeffered(message);
         } catch (Throwable t) {
             String message = getResultMessage(info, "invocation failed with " + \
                t.getMessage());
-            return new SenderResult(ResultState.FAILURE, message);
+            return SenderResult.getSimpleFailure(message);
         }
     }
 
+    /* 
+     * if we actually execute the operation at the time of alert sending, we can \
report the +     * operation's failure/success accurately instead of just returning a \
"deferred" result +     */
     private String getHyperLinkForOperationSchedule(Subject subject, int resourceId, \
String operationName, JobId jobId) {  /*
         OperationManagerLocal operationManager = LookupUtil.getOperationManager();
diff --git a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java \
b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java
 index 2846266..35b558e 100644
--- a/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java
                
+++ b/modules/enterprise/server/plugins/alert-roles/src/main/java/org/rhq/enterprise/server/plugins/alertRoles/RolesSender.java
 @@ -19,10 +19,12 @@
 package org.rhq.enterprise.server.plugins.alertRoles;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.core.domain.auth.Subject;
 import org.rhq.core.domain.authz.Role;
@@ -45,12 +47,33 @@ public class RolesSender extends AlertSender {
     public SenderResult send(Alert alert) {
         List<Integer> roleIds = getRoleIdsFromConfiguration();
         if (roleIds == null) {
-            return new SenderResult(ResultState.FAILURE, "No roles defined");
+            return SenderResult.getSimpleFailure("No roles defined");
         }
 
-        List<String> emails = getRoleEmails(roleIds);
         List<String> names = getRoleNames(roleIds);
-        return new SenderResult(ResultState.DEFERRED_EMAIL, "Sending to roles: " + \
names, emails); +        List<String> emails = getRoleEmails(roleIds);
+
+        try {
+            Set<String> uniqueEmails = new HashSet<String>(emails);
+            Collection<String> badEmails = LookupUtil.getAlertManager()
+                .sendAlertNotificationEmails(alert, uniqueEmails);
+
+            List<String> goodEmails = new ArrayList<String>(uniqueEmails);
+            goodEmails.removeAll(badEmails);
+
+            SenderResult result = new SenderResult();
+            result.setSummary("Target roles were: " + names);
+            if (goodEmails.size() > 0) {
+                result.addSuccessMessage("Successfully sent to: " + goodEmails);
+            }
+            if (badEmails.size() > 0) {
+                result.addFailureMessage("Failed to send to: " + badEmails);
+            }
+            return result;
+        } catch (Throwable t) {
+            return SenderResult.getSimpleFailure("Error sending role notifications \
to " + names + ", cause: " +                + t.getMessage());
+        }
     }
 
     @Override
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java \
b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
 index 1639e81..627e23d 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
                
+++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
 @@ -25,7 +25,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.core.domain.resource.Resource;
 import org.rhq.enterprise.server.alert.AlertManagerLocal;
@@ -46,34 +45,29 @@ public class SnmpSender extends AlertSender {
 
         SnmpInfo info = SnmpInfo.load(alertParameters);
         if (info.error != null) {
-            return new SenderResult(ResultState.FAILURE, info.error);
+            return SenderResult.getSimpleFailure(info.error);
         }
         log.debug("Sending SNMP trap to: " + info);
 
-        AlertManagerLocal alertManager = LookupUtil.getAlertManager();
-        ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
+        try {
+            AlertManagerLocal alertManager = LookupUtil.getAlertManager();
+            ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
 
-        SnmpTrapSender snmpTrapSender = new SnmpTrapSender(preferences);
+            SnmpTrapSender snmpTrapSender = new SnmpTrapSender(preferences);
 
-        List<Resource> lineage = \
                resourceManager.getResourceLineage(alert.getAlertDefinition().getResource().getId());
                
-        String platformName = lineage.get(0).getName();
-        String conditions = alertManager.prettyPrintAlertConditions(alert, false);
-        String alertUrl = alertManager.prettyPrintAlertURL(alert);
+            List<Resource> lineage = \
resourceManager.getResourceLineage(alert.getAlertDefinition().getResource() +         \
.getId()); +            String platformName = lineage.get(0).getName();
+            String conditions = alertManager.prettyPrintAlertConditions(alert, \
false); +            String alertUrl = alertManager.prettyPrintAlertURL(alert);
 
-        String result;
-        SenderResult res;
-        try {
             Date bootTime = new Date(); // TODO: want to use \
                LookupUtil.getCoreServer().getBootTime() but ServiceMBean is not \
                visible
-            result = snmpTrapSender.sendSnmpTrap(alert, alertParameters, \
                platformName, conditions, bootTime, alertUrl);
-            res = new SenderResult(ResultState.SUCCESS, result);
+            String result = snmpTrapSender.sendSnmpTrap(alert, alertParameters, \
platformName, conditions, bootTime, +                alertUrl);
+            return SenderResult.getSimpleSuccess(result);
         } catch (Throwable t) {
-            result = "failed - cause: " + t;
-            res = new SenderResult(ResultState.FAILURE, result);
+            return SenderResult.getSimpleFailure("failed - cause: " + t);
         }
-
-        log.debug("Result of sending SNMP trap: " + result);
-
-        return res;
     }
 
     @Override
diff --git a/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsSender.java \
b/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsSender.java
 index 13f4f32..201e13f 100644
--- a/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsSender.java
                
+++ b/modules/enterprise/server/plugins/alert-subject/src/main/java/org/rhq/enterprise/server/plugins/alertSubject/SubjectsSender.java
 @@ -19,10 +19,12 @@
 package org.rhq.enterprise.server.plugins.alertSubject;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.rhq.core.domain.alert.Alert;
-import org.rhq.core.domain.alert.notification.ResultState;
 import org.rhq.core.domain.alert.notification.SenderResult;
 import org.rhq.core.domain.auth.Subject;
 import org.rhq.core.domain.configuration.PropertySimple;
@@ -44,12 +46,33 @@ public class SubjectsSender extends AlertSender {
     public SenderResult send(Alert alert) {
         List<Integer> subjectIds = getSubjectIdsFromConfiguration();
         if (subjectIds == null) {
-            return new SenderResult(ResultState.FAILURE, "No subjects defined");
+            return SenderResult.getSimpleFailure("No subjects defined");
         }
 
-        List<String> emails = getSubjectEmails(subjectIds);
         List<String> names = getSubjectNames(subjectIds);
-        return new SenderResult(ResultState.DEFERRED_EMAIL, "Sending to subjects: " \
+ names, emails); +        List<String> emails = getSubjectEmails(subjectIds);
+
+        try {
+            Set<String> uniqueEmails = new HashSet<String>(emails);
+            Collection<String> badEmails = LookupUtil.getAlertManager()
+                .sendAlertNotificationEmails(alert, uniqueEmails);
+
+            List<String> goodEmails = new ArrayList<String>(uniqueEmails);
+            goodEmails.removeAll(badEmails);
+
+            SenderResult result = new SenderResult();
+            result.setSummary("Target subjects were: " + names);
+            if (goodEmails.size() > 0) {
+                result.addSuccessMessage("Successfully sent to: " + goodEmails);
+            }
+            if (badEmails.size() > 0) {
+                result.addFailureMessage("Failed to send to: " + badEmails);
+            }
+            return result;
+        } catch (Throwable t) {
+            return SenderResult.getSimpleFailure("Error sending subject \
notifications to " + names + ", cause: " +                + t.getMessage());
+        }
     }
 
     @Override


commit 589acd80903f723af322f9ec68ea16c23efee224
Author: Jay Shaughnessy <jshaughn at redhat.com>
Date:   Tue Jun 29 23:05:09 2010 -0400

    fix conditional *again*

diff --git a/release.sh b/release.sh
index b800233..ccf6f72 100755
--- a/release.sh
+++ b/release.sh
@@ -336,7 +336,7 @@ else
     BUILD_BRANCH="${RELEASE_BRANCH}-test-build"
 # delete the branch if it exists, so we can recreate it fresh     
     EXISTING_BUILD_BRANCH=`git ls-remote --heads origin "$BUILD_BRANCH"`
-    if [ -n "$EXISTING_REMOTE_TAG" ]; then
+    if [ -n "$EXISTING_BUILD_BRANCH" ]; then
         echo "Deleting remote branch origin/$BUILD_BRANCH"    
         git branch -D -r "origin/$BUILD_BRANCH"
         echo "Deleting local branch $BUILD_BRANCH"        


commit 050ec9212aa8f3df421a5c9f7983252853b0d8bf
Author: Jay Shaughnessy <jshaughn at redhat.com>
Date:   Tue Jun 29 22:56:07 2010 -0400

    fix a script conditional

diff --git a/release.sh b/release.sh
index 5ce7396..b800233 100755
--- a/release.sh
+++ b/release.sh
@@ -336,7 +336,7 @@ else
     BUILD_BRANCH="${RELEASE_BRANCH}-test-build"
 # delete the branch if it exists, so we can recreate it fresh     
     EXISTING_BUILD_BRANCH=`git ls-remote --heads origin "$BUILD_BRANCH"`
-    if [ "$EXISTING_REMOTE_TAG" ]; then
+    if [ -n "$EXISTING_REMOTE_TAG" ]; then
         echo "Deleting remote branch origin/$BUILD_BRANCH"    
         git branch -D -r "origin/$BUILD_BRANCH"
         echo "Deleting local branch $BUILD_BRANCH"        


commit 92ce59765e28e91b02aa7a6583ae402615a39693
Author: Jay Shaughnessy <jshaughn at redhat.com>
Date:   Tue Jun 29 22:37:01 2010 -0400

    Revise tag deletion logic

diff --git a/release.sh b/release.sh
index c4b9e46..5ce7396 100755
--- a/release.sh
+++ b/release.sh
@@ -327,15 +327,6 @@ if [ ! -d "$WORKING_DIR" ]; then
 fi
 
 
-# If the specified tag already exists then abort. It should not exist since \
                production runs should have
-# unique tags and test runs should have been done in a temporary branch
-
-EXISTING_REMOTE_TAG=`git ls-remote --tags origin "$RELEASE_TAG"`
-if [ -n "$EXISTING_REMOTE_TAG" ]; then
-   abort "A remote tag named $RELEASE_TAG already exists - aborting, perhaps a bad \
                build configuration..."      
-fi
-
-
 # if this is a test build then create a temporary build branch off of \
RELEASE_BRANCH.  This allows checkins to  # continue in RELEASE_BRANCH without \
affecting the release plugin work, which will fail if the branch contents  # change \
before it completes. @@ -360,7 +351,28 @@ fi
              
 # We should now have the build_branch checked out
 echo "Current Branch is $BUILD_BRANCH"
- 
+
+# If the specified tag already exists remotely and we're in production mode, then \
abort. If it exists and  +# we're in test mode, delete it
+
+EXISTING_REMOTE_TAG=`git ls-remote --tags origin "$RELEASE_TAG"`
+if [ -n "$EXISTING_REMOTE_TAG" ] && [ "$MODE" = "production" ]; then
+   abort "A remote tag named $RELEASE_TAG already exists - aborting, since we are in \
production mode..."  +fi   
+
+if [ -n "$EXISTING_REMOTE_TAG" ] && [ "$MODE" = "test" ]; then
+   echo "A remote tag named $RELEASE_TAG already exists - deleting it, since we are \
in test mode..."       +   git push origin ":refs/tags/$RELEASE_TAG"
+   [ "$?" -ne 0 ] && abort "Failed to delete remote tag ($RELEASE_TAG)."
+fi   
+
+# See if the specified tag already exists locally - if so, delete it (even if in \
production mode). +EXISTING_LOCAL_TAG=`git tag -l "$RELEASE_TAG"`
+if [ -n "$EXISTING_LOCAL_TAG" ]; then
+   echo "A local tag named $RELEASE_TAG already exists - deleting it..."      
+   git tag -d "$RELEASE_TAG"
+   [ "$?" -ne 0 ] && abort "Failed to delete local tag ($RELEASE_TAG)."
+fi 
  
 # Run a test build before tagging. This will publish the snapshot artifacts to the \
local repo to "bootstrap" the repo.  


commit 9122675265f8107fa4ff616a6e8ea522297cd1bc
Author: Jay Shaughnessy <jshaughn at redhat.com>
Date:   Tue Jun 29 22:39:44 2010 -0400

    LT commit

diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java \
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
 index 74130b4..fb292ee 100644
--- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
                
+++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
 @@ -1,420 +1,420 @@
-/*
-* Jopr Management Platform
-* Copyright (C) 2005-2009 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.plugins.jbossas5;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import org.jboss.deployers.spi.management.ManagementView;
-import org.jboss.deployers.spi.management.deploy.DeploymentManager;
-import org.jboss.deployers.spi.management.deploy.DeploymentProgress;
-import org.jboss.deployers.spi.management.deploy.DeploymentStatus;
-import org.jboss.managed.api.ComponentType;
-import org.jboss.managed.api.ManagedComponent;
-import org.jboss.managed.api.ManagedDeployment;
-import org.jboss.managed.api.ManagedOperation;
-import org.jboss.managed.api.ManagedProperty;
-import org.jboss.managed.api.RunState;
-import org.jboss.metatype.api.values.ArrayValue;
-import org.jboss.metatype.api.values.CollectionValue;
-import org.jboss.metatype.api.values.CompositeValue;
-import org.jboss.metatype.api.values.EnumValue;
-import org.jboss.metatype.api.values.MetaValue;
-import org.jboss.metatype.api.values.SimpleValue;
-
-import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
-import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.DataType;
-import org.rhq.core.domain.measurement.MeasurementDataNumeric;
-import org.rhq.core.domain.measurement.MeasurementDataTrait;
-import org.rhq.core.domain.measurement.MeasurementReport;
-import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
-import org.rhq.core.domain.operation.OperationDefinition;
-import org.rhq.core.domain.resource.ResourceType;
-import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
-import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
-import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
-import org.rhq.core.pluginapi.inventory.ResourceContext;
-import org.rhq.core.pluginapi.measurement.MeasurementFacet;
-import org.rhq.core.pluginapi.operation.OperationFacet;
-import org.rhq.core.pluginapi.operation.OperationResult;
-import org.rhq.core.util.exception.ThrowableUtil;
-import org.rhq.plugins.jbossas5.util.ConversionUtils;
-import org.rhq.plugins.jbossas5.util.DebugUtils;
-import org.rhq.plugins.jbossas5.util.DeploymentUtils;
-import org.rhq.plugins.jbossas5.util.ManagedComponentUtils;
-import org.rhq.plugins.jbossas5.util.ResourceComponentUtils;
-import org.rhq.plugins.jbossas5.util.ResourceTypeUtils;
-
-/**
- * Service ResourceComponent for all {@link ManagedComponent}s in a Profile.
- *
- * @author Ian Springer
- * @author Jason Dobies
- * @author Mark Spritzler
- */
-public class ManagedComponentComponent extends AbstractManagedComponent implements \
                ConfigurationFacet,
-    DeleteResourceFacet, OperationFacet, MeasurementFacet {
-    public static interface Config {
-        String COMPONENT_TYPE = "componentType";
-        String COMPONENT_SUBTYPE = "componentSubtype";
-        String COMPONENT_NAME = "componentName";
-        String TEMPLATE_NAME = "templateName";
-        String COMPONENT_NAME_PROPERTY = "componentNameProperty";
-    }
-
-    protected static final char PREFIX_DELIMITER = '|';
-
-    private final Log log = LogFactory.getLog(this.getClass());
-
-    private String componentName;
-    private ComponentType componentType;
-
-    // ResourceComponent Implementation  \
                --------------------------------------------
-
-    public AvailabilityType getAvailability() {
-        RunState runState = null;
-        try {
-            runState = getManagedComponent().getRunState();
-        } catch (Throwable t) {
-            log.debug("Could not get component state, cause: ", t);
-            return AvailabilityType.DOWN;
-        }
-
-        if (runState == RunState.RUNNING) {
-            return AvailabilityType.UP;
-        } else {
-            log.debug("Component was not running, state was: " + runState);
-            return AvailabilityType.DOWN;
-        }
-    }
-
-    public void start(ResourceContext<ProfileServiceComponent> resourceContext) \
                throws Exception {
-        super.start(resourceContext);
-        this.componentType = \
                ConversionUtils.getComponentType(getResourceContext().getResourceType());
                
-        Configuration pluginConfig = resourceContext.getPluginConfiguration();
-        this.componentName = \
                pluginConfig.getSimple(Config.COMPONENT_NAME).getStringValue();
-        log.trace("Started ResourceComponent for " + getResourceDescription() + ", \
                managing " + this.componentType
-            + " component '" + this.componentName + "'.");
-    }
-
-    public void stop() {
-        return;
-    }
-
-    // ConfigurationComponent Implementation  \
                --------------------------------------------
-
-    public Configuration loadResourceConfiguration() {
-        Configuration resourceConfig;
-        try {
-            Map<String, ManagedProperty> managedProperties = \
                getManagedComponent().getProperties();
-            Map<String, PropertySimple> customProps = \
                ResourceComponentUtils.getCustomProperties(getResourceContext()
-                .getPluginConfiguration());
-            if (this.log.isDebugEnabled())
-                this.log.debug("*** AFTER LOAD:\n" + \
                DebugUtils.convertPropertiesToString(managedProperties));
-            resourceConfig = \
                ConversionUtils.convertManagedObjectToConfiguration(managedProperties, \
                customProps,
-                getResourceContext().getResourceType());
-        } catch (Exception e) {
-            RunState runState = getManagedComponent().getRunState();
-            if (runState == RunState.RUNNING) {
-                this.log.error("Failed to load configuration for " + \
                getResourceDescription() + ".", e);
-            } else {
-                this.log.debug("Failed to load configuration for " + \
                getResourceDescription()
-                    + ", but managed component is not in the RUNNING state.", e);
-            }
-            throw new RuntimeException(ThrowableUtil.getAllMessages(e));
-        }
-        return resourceConfig;
-    }
-
-    public void updateResourceConfiguration(ConfigurationUpdateReport \
                configurationUpdateReport) {
-        Configuration resourceConfig = configurationUpdateReport.getConfiguration();
-        Configuration pluginConfig = getResourceContext().getPluginConfiguration();
-        try {
-            ManagedComponent managedComponent = getManagedComponent();
-            Map<String, ManagedProperty> managedProperties = \
                managedComponent.getProperties();
-            Map<String, PropertySimple> customProps = \
                ResourceComponentUtils.getCustomProperties(pluginConfig);
-            if (this.log.isDebugEnabled())
-                this.log.debug("*** BEFORE UPDATE:\n" + \
                DebugUtils.convertPropertiesToString(managedProperties));
-            ConversionUtils.convertConfigurationToManagedProperties(managedProperties, \
                resourceConfig,
-                getResourceContext().getResourceType(), customProps);
-            if (this.log.isDebugEnabled())
-                this.log.debug("*** AFTER UPDATE:\n" + \
                DebugUtils.convertPropertiesToString(managedProperties));
-            updateComponent(managedComponent);
-            configurationUpdateReport.setStatus(ConfigurationUpdateStatus.SUCCESS);
-        } catch (Exception e) {
-            this.log.error("Failed to update configuration for " + \
                getResourceDescription() + ".", e);
-            configurationUpdateReport.setStatus(ConfigurationUpdateStatus.FAILURE);
-            configurationUpdateReport.setErrorMessage(ThrowableUtil.getAllMessages(e));
                
-        }
-    }
-
-    // DeleteResourceFacet Implementation  \
                --------------------------------------------
-
-    public void deleteResource() throws Exception {
-        DeploymentManager deploymentManager = \
                getConnection().getDeploymentManager();
-        if (!deploymentManager.isRedeploySupported())
-            throw new UnsupportedOperationException("Deletion of " + \
                getResourceContext().getResourceType().getName()
-                + " Resources is not currently supported.");
-        ManagedComponent managedComponent = getManagedComponent();
-        log.debug("Removing " + getResourceDescription() + " with component " + \
                toString(managedComponent) + "...");
-        ManagementView managementView = getConnection().getManagementView();
-        managementView.removeComponent(managedComponent);
-        ManagedDeployment parentDeployment = managedComponent.getDeployment();
-        log.debug("Redeploying parent deployment '" + parentDeployment.getName()
-            + "' in order to complete removal of component " + \
                toString(managedComponent) + "...");
-        DeploymentProgress progress = \
                deploymentManager.redeploy(parentDeployment.getName());
-        DeploymentStatus redeployStatus = DeploymentUtils.run(progress);
-        if (redeployStatus.isFailed()) {
-            log.error("Failed to redeploy parent deployment '" + \
                parentDeployment.getName()
-                + "during removal of component " + toString(managedComponent)
-                + " - removal may not persist when the app server is restarted.", \
                redeployStatus.getFailure());
-        }
-        managementView.load();
-    }
-
-    // OperationFacet Implementation  --------------------------------------------
-
-    public OperationResult invokeOperation(String name, Configuration parameters) \
                throws Exception {
-        OperationDefinition operationDefinition = getOperationDefinition(name);
-        ManagedOperation managedOperation = \
                getManagedOperation(operationDefinition);
-        // Convert parameters into MetaValue array.
-        MetaValue[] parameterMetaValues = \
                ConversionUtils.convertOperationsParametersToMetaValues(managedOperation,
                
-            parameters, operationDefinition);
-        // invoke() takes a varargs, so we need to pass an empty array, rather than \
                null.
-        MetaValue resultMetaValue = managedOperation.invoke(parameterMetaValues);
-        OperationResult result = new OperationResult();
-        // Convert result MetaValue to corresponding Property type.
-        ConversionUtils.convertManagedOperationResults(managedOperation, \
                resultMetaValue, result.getComplexResults(),
-            operationDefinition);
-        return result;
-    }
-
-    // MeasurementFacet Implementation  --------------------------------------------
-
-    public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> \
                metrics) throws Exception {
-        ManagedComponent managedComponent = getManagedComponent();
-        RunState runState = managedComponent.getRunState();
-        for (MeasurementScheduleRequest request : metrics) {
-            try {
-                if (request.getName().equals("runState")) {
-                    report.addData(new MeasurementDataTrait(request, \
                runState.name()));
-                } else {
-                    Object value = getSimpleValue(managedComponent, request);
-                    addValueToMeasurementReport(report, request, value);
-                }
-            } catch (Exception e) {
-                if (runState == RunState.RUNNING) {
-                    log.error("Failed to collect metric for " + request, e);
-                } else {
-                    log.debug("Failed to collect metric for " + request
-                        + ", but managed component is not in the RUNNING state.", \
                e);
-                }
-            }
-        }
-    }
-
-    protected void updateComponent(ManagedComponent managedComponent) throws \
                Exception {
-        log.trace("Updating " + getResourceDescription() + " with component " + \
                toString(managedComponent) + "...");
-        ManagementView managementView = getConnection().getManagementView();
-        managementView.updateComponent(managedComponent);
-        managementView.load();
-    }
-
-    // ------------------------------------------------------------------------------
                
-
-    /**
-     * The name of the measurement schedule request (i.e. the metric name) can be in \
                one of two forms:
-     * <p/>
-     * [prefix'|']simplePropertyName (e.g. "maxTime" or \
                "ThreadPool|currentThreadCount")
-     * [prefix'|']compositePropertyName'.'key (e.g. "consumerCount" or \
                "messageStatistics.count")
-     *
-     * @param managedComponent a managed component
-     * @param request          a measurement schedule request
-     * @return the metric value
-     */
-    @Nullable
-    protected Object getSimpleValue(ManagedComponent managedComponent, \
                MeasurementScheduleRequest request) {
-        String metricName = request.getName();
-        int pipeIndex = metricName.indexOf(PREFIX_DELIMITER);
-        // Remove the prefix if there is one (e.g. "ThreadPool|currentThreadCount" \
                -> "currentThreadCount").
-        String compositePropName = (pipeIndex == -1) ? metricName : \
                metricName.substring(pipeIndex + 1);
-        int dotIndex = compositePropName.indexOf('.');
-        String metricPropName = (dotIndex == -1) ? compositePropName : \
                compositePropName.substring(0, dotIndex);
-        ManagedProperty metricProp = managedComponent.getProperty(metricPropName);
-        if (metricProp == null) {
-            return null;
-        }
-        MetaValue metaValue;
-        if (dotIndex == -1) {
-            metaValue = metricProp.getValue();
-        } else {
-            CompositeValue compositeValue = (CompositeValue) metricProp.getValue();
-            String key = compositePropName.substring(dotIndex + 1);
-            metaValue = compositeValue.get(key);
-        }
-        return getInnerValue(metaValue);
-    }
-
-    // TODO: Move this to a utility class.
-    @Nullable
-    private static Object getInnerValue(MetaValue metaValue) {
-        if (metaValue == null) {
-            return null;
-        }
-        Object value;
-        if (metaValue.getMetaType().isSimple()) {
-            SimpleValue simpleValue = (SimpleValue) metaValue;
-            value = simpleValue.getValue();
-        } else if (metaValue.getMetaType().isEnum()) {
-            EnumValue enumValue = (EnumValue) metaValue;
-            value = enumValue.getValue();
-        } else if (metaValue.getMetaType().isArray()) {
-            ArrayValue arrayValue = (ArrayValue) metaValue;
-            value = arrayValue.getValue();
-        } else if (metaValue.getMetaType().isCollection()) {
-            CollectionValue collectionValue = (CollectionValue) metaValue;
-            List list = new ArrayList();
-            for (MetaValue element : collectionValue.getElements()) {
-                list.add(getInnerValue(element));
-            }
-            value = list;
-        } else {
-            value = metaValue.toString();
-        }
-        return value;
-    }
-
-    protected void addValueToMeasurementReport(MeasurementReport report, \
                MeasurementScheduleRequest request,
-        Object value) {
-        if (value == null) {
-            return;
-        }
-        String stringValue = toString(value);
-
-        DataType dataType = request.getDataType();
-        switch (dataType) {
-        case MEASUREMENT:
-            try {
-                MeasurementDataNumeric dataNumeric = new \
                MeasurementDataNumeric(request, Double.valueOf(stringValue));
-                report.addData(dataNumeric);
-            } catch (NumberFormatException e) {
-                log.error("Profile service did not return a numeric value as \
                expected for metric [" + request.getName()
-                    + "] - value returned was " + value + ".", e);
-            }
-            break;
-        case TRAIT:
-            MeasurementDataTrait dataTrait = new MeasurementDataTrait(request, \
                stringValue);
-            report.addData(dataTrait);
-            break;
-        default:
-            throw new IllegalStateException("Unsupported measurement data type: " + \
                dataType);
-        }
-    }
-
-    protected ComponentType getComponentType() {
-        return componentType;
-    }
-
-    protected String getComponentName() {
-        return componentName;
-    }
-
-    protected ManagedComponent getManagedComponent() {
-        ManagedComponent managedComponent;
-        try {
-            ManagementView managementView = getConnection().getManagementView();
-            managedComponent = \
                ManagedComponentUtils.getManagedComponent(managementView, \
                this.componentType,
-                this.componentName);
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to load [" + this.componentType + "] \
                ManagedComponent ["
-                + this.componentName + "].", e);
-        }
-        if (managedComponent == null)
-            throw new IllegalStateException("Failed to find [" + this.componentType \
                + "] ManagedComponent named ["
-                + this.componentName + "].");
-        log.trace("Retrieved " + toString(managedComponent) + ".");
-        return managedComponent;
-    }
-
-    @NotNull
-    private OperationDefinition getOperationDefinition(String operationName) {
-        ResourceType resourceType = getResourceContext().getResourceType();
-        OperationDefinition operationDefinition = \
                ResourceTypeUtils.getOperationDefinition(resourceType, \
                operationName);
-        if (operationDefinition == null)
-            throw new IllegalStateException("Operation named '" + operationName
-                + "' is not defined for Resource type '" + resourceType.getName() + \
                "' in the '"
-                + resourceType.getPlugin() + "' plugin's descriptor.");
-        return operationDefinition;
-    }
-
-    @NotNull
-    private ManagedOperation getManagedOperation(OperationDefinition \
                operationDefinition) {
-        ManagedComponent managedComponent = getManagedComponent();
-        Set<ManagedOperation> operations = managedComponent.getOperations();
-        for (ManagedOperation operation : operations) {
-            ConfigurationDefinition paramsConfigDef = \
                operationDefinition.getParametersConfigurationDefinition();
-            int paramCount = (paramsConfigDef != null) ? \
                paramsConfigDef.getPropertyDefinitions().size() : 0;
-            if (operation.getName().equals(operationDefinition.getName())
-                && (operation.getParameters().length == paramCount))
-                return operation;
-        }
-        throw new IllegalStateException("ManagedOperation named '" + \
                operationDefinition.getName()
-            + "' not found on ManagedComponent [" + getManagedComponent() + "].");
-    }
-
-    private static String toString(ManagedComponent managedComponent) {
-        Map<String, ManagedProperty> properties = managedComponent.getProperties();
-        return managedComponent.getClass().getSimpleName() + "@" + \
                System.identityHashCode(managedComponent) + "["
-            + "type=" + managedComponent.getType() + ", name=" + \
                managedComponent.getName() + ", properties="
-            + properties.getClass().getSimpleName() + "@" + \
                System.identityHashCode(properties) + "]";
-    }
-
-    private static String toString(@NotNull Object value) {
-        if (value.getClass().isArray()) {
-            StringBuilder buffer = new StringBuilder();
-            int lastIndex = Array.getLength(value) - 1;
-            for (int i = 0; i < Array.getLength(value); i++) {
-                buffer.append(String.valueOf(Array.get(value, i)));
-                if (i == lastIndex) {
-                    break;
-                }
-                buffer.append(", ");
-            }
-            return buffer.toString();
-        } else {
-            return value.toString();
-        }
-    }
-}
+/*
+* Jopr Management Platform
+* Copyright (C) 2005-2009 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.plugins.jbossas5;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import org.jboss.deployers.spi.management.ManagementView;
+import org.jboss.deployers.spi.management.deploy.DeploymentManager;
+import org.jboss.deployers.spi.management.deploy.DeploymentProgress;
+import org.jboss.deployers.spi.management.deploy.DeploymentStatus;
+import org.jboss.managed.api.ComponentType;
+import org.jboss.managed.api.ManagedComponent;
+import org.jboss.managed.api.ManagedDeployment;
+import org.jboss.managed.api.ManagedOperation;
+import org.jboss.managed.api.ManagedProperty;
+import org.jboss.managed.api.RunState;
+import org.jboss.metatype.api.values.ArrayValue;
+import org.jboss.metatype.api.values.CollectionValue;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.EnumValue;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.metatype.api.values.SimpleValue;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.measurement.DataType;
+import org.rhq.core.domain.measurement.MeasurementDataNumeric;
+import org.rhq.core.domain.measurement.MeasurementDataTrait;
+import org.rhq.core.domain.measurement.MeasurementReport;
+import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
+import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
+import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
+import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.measurement.MeasurementFacet;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.util.exception.ThrowableUtil;
+import org.rhq.plugins.jbossas5.util.ConversionUtils;
+import org.rhq.plugins.jbossas5.util.DebugUtils;
+import org.rhq.plugins.jbossas5.util.DeploymentUtils;
+import org.rhq.plugins.jbossas5.util.ManagedComponentUtils;
+import org.rhq.plugins.jbossas5.util.ResourceComponentUtils;
+import org.rhq.plugins.jbossas5.util.ResourceTypeUtils;
+
+/**
+ * Service ResourceComponent for all {@link ManagedComponent}s in a Profile.
+ *
+ * @author Ian Springer
+ * @author Jason Dobies
+ * @author Mark Spritzler
+ */
+public class ManagedComponentComponent extends AbstractManagedComponent implements \
ConfigurationFacet, +    DeleteResourceFacet, OperationFacet, MeasurementFacet {
+    public static interface Config {
+        String COMPONENT_TYPE = "componentType";
+        String COMPONENT_SUBTYPE = "componentSubtype";
+        String COMPONENT_NAME = "componentName";
+        String TEMPLATE_NAME = "templateName";
+        String COMPONENT_NAME_PROPERTY = "componentNameProperty";
+    }
+
+    protected static final char PREFIX_DELIMITER = '|';
+
+    private final Log log = LogFactory.getLog(this.getClass());
+
+    private String componentName;
+    private ComponentType componentType;
+
+    // ResourceComponent Implementation  \
-------------------------------------------- +
+    public AvailabilityType getAvailability() {
+        RunState runState = null;
+        try {
+            runState = getManagedComponent().getRunState();
+        } catch (Throwable t) {
+            log.debug("Could not get component state, cause: ", t);
+            return AvailabilityType.DOWN;
+        }
+
+        if (runState == RunState.RUNNING) {
+            return AvailabilityType.UP;
+        } else {
+            log.debug("Component was not running, state was: " + runState);
+            return AvailabilityType.DOWN;
+        }
+    }
+
+    public void start(ResourceContext<ProfileServiceComponent> resourceContext) \
throws Exception { +        super.start(resourceContext);
+        this.componentType = \
ConversionUtils.getComponentType(getResourceContext().getResourceType()); +        \
Configuration pluginConfig = resourceContext.getPluginConfiguration(); +        \
this.componentName = pluginConfig.getSimple(Config.COMPONENT_NAME).getStringValue(); \
+        log.trace("Started ResourceComponent for " + getResourceDescription() + ", \
managing " + this.componentType +            + " component '" + this.componentName + \
"'."); +    }
+
+    public void stop() {
+        return;
+    }
+
+    // ConfigurationComponent Implementation  \
-------------------------------------------- +
+    public Configuration loadResourceConfiguration() {
+        Configuration resourceConfig;
+        try {
+            Map<String, ManagedProperty> managedProperties = \
getManagedComponent().getProperties(); +            Map<String, PropertySimple> \
customProps = ResourceComponentUtils.getCustomProperties(getResourceContext() +       \
.getPluginConfiguration()); +            if (this.log.isDebugEnabled())
+                this.log.debug("*** AFTER LOAD:\n" + \
DebugUtils.convertPropertiesToString(managedProperties)); +            resourceConfig \
= ConversionUtils.convertManagedObjectToConfiguration(managedProperties, customProps, \
+                getResourceContext().getResourceType()); +        } catch (Exception \
e) { +            RunState runState = getManagedComponent().getRunState();
+            if (runState == RunState.RUNNING) {
+                this.log.error("Failed to load configuration for " + \
getResourceDescription() + ".", e); +            } else {
+                this.log.debug("Failed to load configuration for " + \
getResourceDescription() +                    + ", but managed component is not in \
the RUNNING state.", e); +            }
+            throw new RuntimeException(ThrowableUtil.getAllMessages(e));
+        }
+        return resourceConfig;
+    }
+
+    public void updateResourceConfiguration(ConfigurationUpdateReport \
configurationUpdateReport) { +        Configuration resourceConfig = \
configurationUpdateReport.getConfiguration(); +        Configuration pluginConfig = \
getResourceContext().getPluginConfiguration(); +        try {
+            ManagedComponent managedComponent = getManagedComponent();
+            Map<String, ManagedProperty> managedProperties = \
managedComponent.getProperties(); +            Map<String, PropertySimple> \
customProps = ResourceComponentUtils.getCustomProperties(pluginConfig); +            \
if (this.log.isDebugEnabled()) +                this.log.debug("*** BEFORE UPDATE:\n" \
+ DebugUtils.convertPropertiesToString(managedProperties)); +            \
ConversionUtils.convertConfigurationToManagedProperties(managedProperties, \
resourceConfig, +                getResourceContext().getResourceType(), \
customProps); +            if (this.log.isDebugEnabled())
+                this.log.debug("*** AFTER UPDATE:\n" + \
DebugUtils.convertPropertiesToString(managedProperties)); +            \
updateComponent(managedComponent); +            \
configurationUpdateReport.setStatus(ConfigurationUpdateStatus.SUCCESS); +        } \
catch (Exception e) { +            this.log.error("Failed to update configuration for \
" + getResourceDescription() + ".", e); +            \
configurationUpdateReport.setStatus(ConfigurationUpdateStatus.FAILURE); +            \
configurationUpdateReport.setErrorMessage(ThrowableUtil.getAllMessages(e)); +        \
} +    }
+
+    // DeleteResourceFacet Implementation  \
-------------------------------------------- +
+    public void deleteResource() throws Exception {
+        DeploymentManager deploymentManager = \
getConnection().getDeploymentManager(); +        if \
(!deploymentManager.isRedeploySupported()) +            throw new \
UnsupportedOperationException("Deletion of " + \
getResourceContext().getResourceType().getName() +                + " Resources is \
not currently supported."); +        ManagedComponent managedComponent = \
getManagedComponent(); +        log.debug("Removing " + getResourceDescription() + " \
with component " + toString(managedComponent) + "..."); +        ManagementView \
managementView = getConnection().getManagementView(); +        \
managementView.removeComponent(managedComponent); +        ManagedDeployment \
parentDeployment = managedComponent.getDeployment(); +        log.debug("Redeploying \
parent deployment '" + parentDeployment.getName() +            + "' in order to \
complete removal of component " + toString(managedComponent) + "..."); +        \
DeploymentProgress progress = deploymentManager.redeploy(parentDeployment.getName()); \
+        DeploymentStatus redeployStatus = DeploymentUtils.run(progress); +        if \
(redeployStatus.isFailed()) { +            log.error("Failed to redeploy parent \
deployment '" + parentDeployment.getName() +                + "during removal of \
component " + toString(managedComponent) +                + " - removal may not \
persist when the app server is restarted.", redeployStatus.getFailure()); +        }
+        managementView.load();
+    }
+
+    // OperationFacet Implementation  --------------------------------------------
+
+    public OperationResult invokeOperation(String name, Configuration parameters) \
throws Exception { +        OperationDefinition operationDefinition = \
getOperationDefinition(name); +        ManagedOperation managedOperation = \
getManagedOperation(operationDefinition); +        // Convert parameters into \
MetaValue array. +        MetaValue[] parameterMetaValues = \
ConversionUtils.convertOperationsParametersToMetaValues(managedOperation, +           \
parameters, operationDefinition); +        // invoke() takes a varargs, so we need to \
pass an empty array, rather than null. +        MetaValue resultMetaValue = \
managedOperation.invoke(parameterMetaValues); +        OperationResult result = new \
OperationResult(); +        // Convert result MetaValue to corresponding Property \
type. +        ConversionUtils.convertManagedOperationResults(managedOperation, \
resultMetaValue, result.getComplexResults(), +            operationDefinition);
+        return result;
+    }
+
+    // MeasurementFacet Implementation  --------------------------------------------
+
+    public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> \
metrics) throws Exception { +        ManagedComponent managedComponent = \
getManagedComponent(); +        RunState runState = managedComponent.getRunState();
+        for (MeasurementScheduleRequest request : metrics) {
+            try {
+                if (request.getName().equals("runState")) {
+                    report.addData(new MeasurementDataTrait(request, \
runState.name())); +                } else {
+                    Object value = getSimpleValue(managedComponent, request);
+                    addValueToMeasurementReport(report, request, value);
+                }
+            } catch (Exception e) {
+                if (runState == RunState.RUNNING) {
+                    log.error("Failed to collect metric for " + request, e);
+                } else {
+                    log.debug("Failed to collect metric for " + request
+                        + ", but managed component is not in the RUNNING state.", \
e); +                }
+            }
+        }
+    }
+
+    protected void updateComponent(ManagedComponent managedComponent) throws \
Exception { +        log.trace("Updating " + getResourceDescription() + " with \
component " + toString(managedComponent) + "..."); +        ManagementView \
managementView = getConnection().getManagementView(); +        \
managementView.updateComponent(managedComponent); +        managementView.load();
+    }
+
+    // ------------------------------------------------------------------------------
 +
+    /**
+     * The name of the measurement schedule request (i.e. the metric name) can be in \
one of two forms: +     * <p/>
+     * [prefix'|']simplePropertyName (e.g. "maxTime" or \
"ThreadPool|currentThreadCount") +     * [prefix'|']compositePropertyName'.'key (e.g. \
"consumerCount" or "messageStatistics.count") +     *
+     * @param managedComponent a managed component
+     * @param request          a measurement schedule request
+     * @return the metric value
+     */
+    @Nullable
+    protected Object getSimpleValue(ManagedComponent managedComponent, \
MeasurementScheduleRequest request) { +        String metricName = request.getName();
+        int pipeIndex = metricName.indexOf(PREFIX_DELIMITER);
+        // Remove the prefix if there is one (e.g. "ThreadPool|currentThreadCount" \
-> "currentThreadCount"). +        String compositePropName = (pipeIndex == -1) ? \
metricName : metricName.substring(pipeIndex + 1); +        int dotIndex = \
compositePropName.indexOf('.'); +        String metricPropName = (dotIndex == -1) ? \
compositePropName : compositePropName.substring(0, dotIndex); +        \
ManagedProperty metricProp = managedComponent.getProperty(metricPropName); +        \
if (metricProp == null) { +            return null;
+        }
+        MetaValue metaValue;
+        if (dotIndex == -1) {
+            metaValue = metricProp.getValue();
+        } else {
+            CompositeValue compositeValue = (CompositeValue) metricProp.getValue();
+            String key = compositePropName.substring(dotIndex + 1);
+            metaValue = compositeValue.get(key);
+        }
+        return getInnerValue(metaValue);
+    }
+
+    // TODO: Move this to a utility class.
+    @Nullable
+    private static Object getInnerValue(MetaValue metaValue) {
+        if (metaValue == null) {
+            return null;
+        }
+        Object value;
+        if (metaValue.getMetaType().isSimple()) {
+            SimpleValue simpleValue = (SimpleValue) metaValue;
+            value = simpleValue.getValue();
+        } else if (metaValue.getMetaType().isEnum()) {
+            EnumValue enumValue = (EnumValue) metaValue;
+            value = enumValue.getValue();
+        } else if (metaValue.getMetaType().isArray()) {
+            ArrayValue arrayValue = (ArrayValue) metaValue;
+            value = arrayValue.getValue();
+        } else if (metaValue.getMetaType().isCollection()) {
+            CollectionValue collectionValue = (CollectionValue) metaValue;
+            List list = new ArrayList();
+            for (MetaValue element : collectionValue.getElements()) {
+                list.add(getInnerValue(element));
+            }
+            value = list;
+        } else {
+            value = metaValue.toString();
+        }
+        return value;
+    }
+
+    protected void addValueToMeasurementReport(MeasurementReport report, \
MeasurementScheduleRequest request, +        Object value) {
+        if (value == null) {
+            return;
+        }
+        String stringValue = toString(value);
+
+        DataType dataType = request.getDataType();
+        switch (dataType) {
+        case MEASUREMENT:
+            try {
+                MeasurementDataNumeric dataNumeric = new \
MeasurementDataNumeric(request, Double.valueOf(stringValue)); +                \
report.addData(dataNumeric); +            } catch (NumberFormatException e) {
+                log.error("Profile service did not return a numeric value as \
expected for metric [" + request.getName() +                    + "] - value returned \
was " + value + ".", e); +            }
+            break;
+        case TRAIT:
+            MeasurementDataTrait dataTrait = new MeasurementDataTrait(request, \
stringValue); +            report.addData(dataTrait);
+            break;
+        default:
+            throw new IllegalStateException("Unsupported measurement data type: " + \
dataType); +        }
+    }
+
+    protected ComponentType getComponentType() {
+        return componentType;
+    }
+
+    protected String getComponentName() {
+        return componentName;
+    }
+
+    protected ManagedComponent getManagedComponent() {
+        ManagedComponent managedComponent;
+        try {
+            ManagementView managementView = getConnection().getManagementView();
+            managedComponent = \
ManagedComponentUtils.getManagedComponent(managementView, this.componentType, +       \
this.componentName); +        } catch (Exception e) {
+            throw new RuntimeException("Failed to load [" + this.componentType + "] \
ManagedComponent [" +                + this.componentName + "].", e);
+        }
+        if (managedComponent == null)
+            throw new IllegalStateException("Failed to find [" + this.componentType \
+ "] ManagedComponent named [" +                + this.componentName + "].");
+        log.trace("Retrieved " + toString(managedComponent) + ".");
+        return managedComponent;
+    }
+
+    @NotNull
+    private OperationDefinition getOperationDefinition(String operationName) {
+        ResourceType resourceType = getResourceContext().getResourceType();
+        OperationDefinition operationDefinition = \
ResourceTypeUtils.getOperationDefinition(resourceType, operationName); +        if \
(operationDefinition == null) +            throw new IllegalStateException("Operation \
named '" + operationName +                + "' is not defined for Resource type '" + \
resourceType.getName() + "' in the '" +                + resourceType.getPlugin() + \
"' plugin's descriptor."); +        return operationDefinition;
+    }
+
+    @NotNull
+    private ManagedOperation getManagedOperation(OperationDefinition \
operationDefinition) { +        ManagedComponent managedComponent = \
getManagedComponent(); +        Set<ManagedOperation> operations = \
managedComponent.getOperations(); +        for (ManagedOperation operation : \
operations) { +            ConfigurationDefinition paramsConfigDef = \
operationDefinition.getParametersConfigurationDefinition(); +            int \
paramCount = (paramsConfigDef != null) ? \
paramsConfigDef.getPropertyDefinitions().size() : 0; +            if \
(operation.getName().equals(operationDefinition.getName()) +                && \
(operation.getParameters().length == paramCount)) +                return operation;
+        }
+        throw new IllegalStateException("ManagedOperation named '" + \
operationDefinition.getName() +            + "' not found on ManagedComponent [" + \
getManagedComponent() + "]."); +    }
+
+    private static String toString(ManagedComponent managedComponent) {
+        Map<String, ManagedProperty> properties = managedComponent.getProperties();
+        return managedComponent.getClass().getSimpleName() + "@" + \
System.identityHashCode(managedComponent) + "[" +            + "type=" + \
managedComponent.getType() + ", name=" + managedComponent.getName() + ", properties=" \
+            + properties.getClass().getSimpleName() + "@" + \
System.identityHashCode(properties) + "]"; +    }
+
+    private static String toString(@NotNull Object value) {
+        if (value.getClass().isArray()) {
+            StringBuilder buffer = new StringBuilder();
+            int lastIndex = Array.getLength(value) - 1;
+            for (int i = 0; i < Array.getLength(value); i++) {
+                buffer.append(String.valueOf(Array.get(value, i)));
+                if (i == lastIndex) {
+                    break;
+                }
+                buffer.append(", ");
+            }
+            return buffer.toString();
+        } else {
+            return value.toString();
+        }
+    }
+}


commit 49344810743edbf032ab6506de606c8e881f62bf
Author: Joseph Marques <joseph at redhat.com>
Date:   Tue Jun 29 19:38:35 2010 -0400

    fix typo in log message

diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java \
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
 index de39733..e7a1194 100644
--- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
                
+++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
 @@ -119,7 +119,7 @@ public abstract class AbstractManagedDeploymentComponent extends \
AbstractManaged  if (deploymentState == DeploymentState.STARTED) {
             return AvailabilityType.UP;
         } else {
-            log.debug("Deployment was not running, state was: " + deploymentState);
+            log.debug("Deployment was not STARTED, state was: " + deploymentState);
             return AvailabilityType.DOWN;
         }
     }


commit ab54c29d4306abe51df706b72f90b6454d20a057
Author: Joseph Marques <joseph at redhat.com>
Date:   Tue Jun 29 18:15:20 2010 -0400

    improve availability checking routines for JBossAS5 managed components
    
    * be tolerant of the underlying API changes - catch throwable
    * when getting the state object back, log if it's not UP/STARTED/RUNNING

diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java \
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
 index 09892a0..de39733 100644
--- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
                
+++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
 @@ -39,7 +39,6 @@ import org.jboss.deployers.spi.management.deploy.ProgressListener;
 import org.jboss.managed.api.DeploymentState;
 import org.jboss.managed.api.ManagedDeployment;
 import org.jboss.profileservice.spi.NoSuchDeploymentException;
-import org.jboss.remoting.CannotConnectException;
 
 import org.rhq.core.domain.configuration.Configuration;
 import org.rhq.core.domain.measurement.AvailabilityType;
@@ -105,14 +104,22 @@ public abstract class AbstractManagedDeploymentComponent \
extends AbstractManaged  }
 
     public AvailabilityType getAvailability() {
+        DeploymentState deploymentState = null;
         try {
-            return (getManagedDeployment().getDeploymentState() == \
                DeploymentState.STARTED) ? AvailabilityType.UP
-                : AvailabilityType.DOWN;
+            deploymentState = getManagedDeployment().getDeploymentState();
         } catch (NoSuchDeploymentException e) {
             log.warn(this.deploymentType + " deployment '" + this.deploymentName + \
"' not found. Cause: "  + e.getLocalizedMessage());
             return AvailabilityType.DOWN;
-        } catch (CannotConnectException e) {
+        } catch (Throwable t) {
+            log.debug("Could not get deployment state, cause: ", t);
+            return AvailabilityType.DOWN;
+        }
+
+        if (deploymentState == DeploymentState.STARTED) {
+            return AvailabilityType.UP;
+        } else {
+            log.debug("Deployment was not running, state was: " + deploymentState);
             return AvailabilityType.DOWN;
         }
     }
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java \
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
 index 0bf55c2..74130b4 100644
--- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
                
+++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
 @@ -49,7 +49,6 @@ import org.jboss.metatype.api.values.CompositeValue;
 import org.jboss.metatype.api.values.EnumValue;
 import org.jboss.metatype.api.values.MetaValue;
 import org.jboss.metatype.api.values.SimpleValue;
-import org.jboss.remoting.CannotConnectException;
 
 import org.rhq.core.domain.configuration.Configuration;
 import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
@@ -105,13 +104,20 @@ public class ManagedComponentComponent extends \
                AbstractManagedComponent implemen
     // ResourceComponent Implementation  \
--------------------------------------------  
     public AvailabilityType getAvailability() {
-        RunState runState;
+        RunState runState = null;
         try {
             runState = getManagedComponent().getRunState();
-        } catch (CannotConnectException e) {
+        } catch (Throwable t) {
+            log.debug("Could not get component state, cause: ", t);
+            return AvailabilityType.DOWN;
+        }
+
+        if (runState == RunState.RUNNING) {
+            return AvailabilityType.UP;
+        } else {
+            log.debug("Component was not running, state was: " + runState);
             return AvailabilityType.DOWN;
         }
-        return (runState == RunState.RUNNING) ? AvailabilityType.UP : \
AvailabilityType.DOWN;  }
 
     public void start(ResourceContext<ProfileServiceComponent> resourceContext) \
throws Exception {


commit 80ac41afa88f74bc69a2032b74efad2d542d1e4a
Author: Joseph Marques <joseph at redhat.com>
Date:   Tue Jun 29 18:05:03 2010 -0400

    cosmetic - automatic relayout of code

diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java \
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
 index b2963cd..09892a0 100644
--- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
                
+++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/AbstractManagedDeploymentComponent.java
 @@ -28,6 +28,7 @@ import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.jboss.deployers.spi.management.KnownDeploymentTypes;
 import org.jboss.deployers.spi.management.ManagementView;
 import org.jboss.deployers.spi.management.deploy.DeploymentManager;
@@ -56,10 +57,8 @@ import org.rhq.plugins.jbossas5.util.DeploymentUtils;
  * @author Mark Spritzler
  * @author Ian Springer
  */
-public abstract class AbstractManagedDeploymentComponent
-        extends AbstractManagedComponent
-        implements MeasurementFacet, OperationFacet, ProgressListener
-{
+public abstract class AbstractManagedDeploymentComponent extends \
AbstractManagedComponent implements MeasurementFacet, +    OperationFacet, \
                ProgressListener {
     public static final String DEPLOYMENT_NAME_PROPERTY = "deploymentName";
     public static final String DEPLOYMENT_TYPE_NAME_PROPERTY = "deploymentTypeName";
     public static final String EXTENSION_PROPERTY = "extension";
@@ -85,8 +84,7 @@ public abstract class AbstractManagedDeploymentComponent
 
     // ----------- ResourceComponent Implementation ------------
 
-    public void start(ResourceContext<ProfileServiceComponent> resourceContext) \
                throws Exception
-    {
+    public void start(ResourceContext<ProfileServiceComponent> resourceContext) \
throws Exception {  super.start(resourceContext);
         Configuration pluginConfig = getResourceContext().getPluginConfiguration();
         this.deploymentName = \
pluginConfig.getSimple(DEPLOYMENT_NAME_PROPERTY).getStringValue(); @@ -94,41 +92,35 \
                @@ public abstract class AbstractManagedDeploymentComponent
         String deploymentTypeName = \
                pluginConfig.getSimple(DEPLOYMENT_TYPE_NAME_PROPERTY).getStringValue();
                
         this.deploymentType = KnownDeploymentTypes.valueOf(deploymentTypeName);
         log.trace("Started ResourceComponent for " + getResourceDescription() + ", \
                managing " + this.deploymentType
-                + " deployment '" + this.deploymentName + "' with path '" + \
                this.deploymentFile + "'.");
-        
+            + " deployment '" + this.deploymentName + "' with path '" + \
this.deploymentFile + "'."); +
         try {
             getManagedDeployment();
         } catch (Exception e) {
-        	log.warn("The underlying file [" + this.deploymentFile + "] no longer \
exists. It may have been deleted from the filesystem external to Jopr. If you wish to \
remove this Resource from inventory, you may add &debug=true to the URL for the \
Browse Resources > Services page and then click the UNINVENTORY button next to this \
Resource"); +            log
+                .warn("The underlying file ["
+                    + this.deploymentFile
+                    + "] no longer exists. It may have been deleted from the \
filesystem external to Jopr. If you wish to remove this Resource from inventory, you \
may add &debug=true to the URL for the Browse Resources > Services page and then \
click the UNINVENTORY button next to this Resource");  }
     }
 
-    public AvailabilityType getAvailability()
-    {
-        try
-        {
-            return (getManagedDeployment().getDeploymentState() == \
                DeploymentState.STARTED) ? AvailabilityType.UP :
-                    AvailabilityType.DOWN;
-        }
-        catch (NoSuchDeploymentException e)
-        {
+    public AvailabilityType getAvailability() {
+        try {
+            return (getManagedDeployment().getDeploymentState() == \
DeploymentState.STARTED) ? AvailabilityType.UP +                : \
AvailabilityType.DOWN; +        } catch (NoSuchDeploymentException e) {
             log.warn(this.deploymentType + " deployment '" + this.deploymentName + \
                "' not found. Cause: "
-                    + e.getLocalizedMessage());
+                + e.getLocalizedMessage());
             return AvailabilityType.DOWN;
-        }
-        catch (CannotConnectException e)
-        {
+        } catch (CannotConnectException e) {
             return AvailabilityType.DOWN;
         }
     }
 
     // ------------ MeasurementFacet Implementation ------------
 
-    public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> \
                requests)
-            throws Exception
-    {
-        if (this.deploymentType == KnownDeploymentTypes.JavaEEWebApplication)
-        {
+    public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> \
requests) throws Exception { +        if (this.deploymentType == \
                KnownDeploymentTypes.JavaEEWebApplication) {
             WarMeasurementFacetDelegate warMeasurementFacetDelegate = new \
WarMeasurementFacetDelegate(this);  warMeasurementFacetDelegate.getValues(report, \
requests);  }
@@ -136,43 +128,32 @@ public abstract class AbstractManagedDeploymentComponent
 
     // ------------ OperationFacet Implementation ------------
 
-    public OperationResult invokeOperation(String name, Configuration parameters) \
                throws Exception
-    {
+    public OperationResult invokeOperation(String name, Configuration parameters) \
                throws Exception {
         DeploymentManager deploymentManager = \
getConnection().getDeploymentManager();  DeploymentProgress progress;
-        if (name.equals("start"))
-        {
-        	//FIXME: This is a workaround until JOPR-309 will be fixed.
-        	if(getAvailability() != AvailabilityType.UP)
-        	{
-        		progress = deploymentManager.start(this.deploymentName);
-        	}
-        	else
-        	{
-        		log.warn("Operation '" + name + "' on " + getResourceDescription() + " \
                failed because the Resource is already started.");
-        		OperationResult result = new OperationResult();
-        		result.setErrorMessage(this.deploymentFile.getName() + " is already \
                started.");
-        		return result;
-        	}
-        }
-        else if (name.equals("stop"))
-        {
+        if (name.equals("start")) {
+            //FIXME: This is a workaround until JOPR-309 will be fixed.
+            if (getAvailability() != AvailabilityType.UP) {
+                progress = deploymentManager.start(this.deploymentName);
+            } else {
+                log.warn("Operation '" + name + "' on " + getResourceDescription()
+                    + " failed because the Resource is already started.");
+                OperationResult result = new OperationResult();
+                result.setErrorMessage(this.deploymentFile.getName() + " is already \
started."); +                return result;
+            }
+        } else if (name.equals("stop")) {
             progress = deploymentManager.stop(this.deploymentName);
-        }
-        else if (name.equals("restart"))
-        {
+        } else if (name.equals("restart")) {
             progress = deploymentManager.stop(this.deploymentName);
             DeploymentStatus stopStatus = DeploymentUtils.run(progress);
             // Still try to start, even if stop fails (maybe the app wasn't running \
to begin with).  progress = deploymentManager.start(this.deploymentName);
-        }
-        else
-        {
+        } else {
             throw new UnsupportedOperationException(name);
         }
         DeploymentStatus status = DeploymentUtils.run(progress);
-        log.debug("Operation '" + name + "' on " + getResourceDescription() + " \
                returned status [" + status
-                + "].");
+        log.debug("Operation '" + name + "' on " + getResourceDescription() + " \
returned status [" + status + "].");  if (status.isFailed()) {
             throw status.getFailure();
         }
@@ -181,8 +162,7 @@ public abstract class AbstractManagedDeploymentComponent
 
     // ------------ ProgressListener implementation -------------
 
-    public void progressEvent(ProgressEvent event)
-    {
+    public void progressEvent(ProgressEvent event) {
         log.debug(event);
     }
 
@@ -196,15 +176,13 @@ public abstract class AbstractManagedDeploymentComponent
         return deploymentType;
     }
 
-    protected ManagedDeployment getManagedDeployment() throws \
                NoSuchDeploymentException
-    {
+    protected ManagedDeployment getManagedDeployment() throws \
                NoSuchDeploymentException {
         ManagementView managementView = getConnection().getManagementView();
         managementView.load();
         return managementView.getDeployment(this.deploymentName);
     }
 
-    private File getDeploymentFile()
-    {
+    private File getDeploymentFile() {
         // e.g.: vfszip:/C:/opt/jboss-5.0.0.GA/server/default/deploy/foo.war
         URI vfsURI = URI.create(this.deploymentName);
         // e.g.: foo.war
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java \
b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
 index aefb351..0bf55c2 100644
--- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
                
+++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/ManagedComponentComponent.java
 @@ -30,6 +30,9 @@ import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
 import org.jboss.deployers.spi.management.ManagementView;
 import org.jboss.deployers.spi.management.deploy.DeploymentManager;
 import org.jboss.deployers.spi.management.deploy.DeploymentProgress;
@@ -48,12 +51,9 @@ import org.jboss.metatype.api.values.MetaValue;
 import org.jboss.metatype.api.values.SimpleValue;
 import org.jboss.remoting.CannotConnectException;
 
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
 import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.configuration.PropertySimple;
 import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.configuration.PropertySimple;
 import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
 import org.rhq.core.domain.measurement.AvailabilityType;
 import org.rhq.core.domain.measurement.DataType;
@@ -72,11 +72,11 @@ import org.rhq.core.pluginapi.operation.OperationFacet;
 import org.rhq.core.pluginapi.operation.OperationResult;
 import org.rhq.core.util.exception.ThrowableUtil;
 import org.rhq.plugins.jbossas5.util.ConversionUtils;
+import org.rhq.plugins.jbossas5.util.DebugUtils;
 import org.rhq.plugins.jbossas5.util.DeploymentUtils;
 import org.rhq.plugins.jbossas5.util.ManagedComponentUtils;
-import org.rhq.plugins.jbossas5.util.ResourceTypeUtils;
 import org.rhq.plugins.jbossas5.util.ResourceComponentUtils;
-import org.rhq.plugins.jbossas5.util.DebugUtils;
+import org.rhq.plugins.jbossas5.util.ResourceTypeUtils;
 
 /**
  * Service ResourceComponent for all {@link ManagedComponent}s in a Profile.
@@ -93,7 +93,7 @@ public class ManagedComponentComponent extends \
AbstractManagedComponent implemen  String COMPONENT_NAME = "componentName";
         String TEMPLATE_NAME = "templateName";
         String COMPONENT_NAME_PROPERTY = "componentNameProperty";
-    }    
+    }
 
     protected static final char PREFIX_DELIMITER = '|';
 
@@ -129,53 +129,45 @@ public class ManagedComponentComponent extends \
AbstractManagedComponent implemen  
     // ConfigurationComponent Implementation  \
--------------------------------------------  
-    public Configuration loadResourceConfiguration()
-    {
+    public Configuration loadResourceConfiguration() {
         Configuration resourceConfig;
-        try
-        {
+        try {
             Map<String, ManagedProperty> managedProperties = \
                getManagedComponent().getProperties();
-            Map<String, PropertySimple> customProps =
-                    \
ResourceComponentUtils.getCustomProperties(getResourceContext().getPluginConfiguration());
                
-            if (this.log.isDebugEnabled()) this.log.debug("*** AFTER LOAD:\n"
-                    + DebugUtils.convertPropertiesToString(managedProperties));
-            resourceConfig = \
                ConversionUtils.convertManagedObjectToConfiguration(managedProperties,
                
-                    customProps, getResourceContext().getResourceType());
-        }
-        catch (Exception e)
-        {
+            Map<String, PropertySimple> customProps = \
ResourceComponentUtils.getCustomProperties(getResourceContext() +                \
.getPluginConfiguration()); +            if (this.log.isDebugEnabled())
+                this.log.debug("*** AFTER LOAD:\n" + \
DebugUtils.convertPropertiesToString(managedProperties)); +            resourceConfig \
= ConversionUtils.convertManagedObjectToConfiguration(managedProperties, customProps, \
+                getResourceContext().getResourceType()); +        } catch (Exception \
e) {  RunState runState = getManagedComponent().getRunState();
             if (runState == RunState.RUNNING) {
-               this.log.error("Failed to load configuration for " + \
getResourceDescription() + ".", e); +                this.log.error("Failed to load \
configuration for " + getResourceDescription() + ".", e);  } else {
-               this.log.debug("Failed to load configuration for " + \
                getResourceDescription()
-                            + ", but managed component is not in the RUNNING \
state.", e); +                this.log.debug("Failed to load configuration for " + \
getResourceDescription() +                    + ", but managed component is not in \
the RUNNING state.", e);  }
             throw new RuntimeException(ThrowableUtil.getAllMessages(e));
         }
         return resourceConfig;
     }
 
-    public void updateResourceConfiguration(ConfigurationUpdateReport \
                configurationUpdateReport)
-    {
+    public void updateResourceConfiguration(ConfigurationUpdateReport \
                configurationUpdateReport) {
         Configuration resourceConfig = configurationUpdateReport.getConfiguration();
         Configuration pluginConfig = getResourceContext().getPluginConfiguration();
-        try
-        {
+        try {
             ManagedComponent managedComponent = getManagedComponent();
             Map<String, ManagedProperty> managedProperties = \
                managedComponent.getProperties();
             Map<String, PropertySimple> customProps = \
                ResourceComponentUtils.getCustomProperties(pluginConfig);
-            if (this.log.isDebugEnabled()) this.log.debug("*** BEFORE UPDATE:\n"
-                    + DebugUtils.convertPropertiesToString(managedProperties));
+            if (this.log.isDebugEnabled())
+                this.log.debug("*** BEFORE UPDATE:\n" + \
                DebugUtils.convertPropertiesToString(managedProperties));
             ConversionUtils.convertConfigurationToManagedProperties(managedProperties, \
                resourceConfig,
-                    getResourceContext().getResourceType(), customProps);
-            if (this.log.isDebugEnabled()) this.log.debug("*** AFTER UPDATE:\n"
-                    + DebugUtils.convertPropertiesToString(managedProperties));
+                getResourceContext().getResourceType(), customProps);
+            if (this.log.isDebugEnabled())
+                this.log.debug("*** AFTER UPDATE:\n" + \
DebugUtils.convertPropertiesToString(managedProperties));  \
                updateComponent(managedComponent);
             configurationUpdateReport.setStatus(ConfigurationUpdateStatus.SUCCESS);
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             this.log.error("Failed to update configuration for " + \
                getResourceDescription() + ".", e);
             configurationUpdateReport.setStatus(ConfigurationUpdateStatus.FAILURE);
             configurationUpdateReport.setErrorMessage(ThrowableUtil.getAllMessages(e));
 @@ -241,7 +233,7 @@ public class ManagedComponentComponent extends \
                AbstractManagedComponent implemen
                     log.error("Failed to collect metric for " + request, e);
                 } else {
                     log.debug("Failed to collect metric for " + request
-                            + ", but managed component is not in the RUNNING \
state.", e); +                        + ", but managed component is not in the \
RUNNING state.", e);  }
             }
         }


commit 1dab7fe90f9f6e477878751dbeb50c56166de3f9
Author: Ian Springer <ian.springer at redhat.com>
Date:   Tue Jun 29 17:21:51 2010 -0400

    make nsswitch plugin pom and descriptor follow same conventions as the other \
agent plugins

diff --git a/modules/plugins/nss/pom.xml b/modules/plugins/nss/pom.xml
index 47b015b..0b8578a 100644
--- a/modules/plugins/nss/pom.xml
+++ b/modules/plugins/nss/pom.xml
@@ -6,109 +6,19 @@
 
    <modelVersion>4.0.0</modelVersion>
 
+   <parent>
+      <groupId>org.rhq</groupId>
+      <artifactId>rhq-plugins-parent</artifactId>
+      <version>3.0.0-SNAPSHOT</version>
+   </parent>
+
    <groupId>org.rhq.plugin.nss</groupId>
    <artifactId>nameservices-switch-plugin</artifactId>
-   <version>0.0.7</version>
    <packaging>jar</packaging>
 
    <name>Name Service Switch</name>
    <description>A Plugin for managing the Name Service Switch infrastructure of a \
Linux System</description>  
-   <properties>
-      <rhq.version>1.4.0-SNAPSHOT</rhq.version>
-   </properties>
-
-   <dependencies>
-
-      <!-- Below are the core modules that are required dependencies of all plugins \
                -->
-      <dependency>
-         <groupId>org.rhq</groupId>
-         <artifactId>rhq-core-domain</artifactId>
-         <version>${rhq.version}</version>
-         <scope>provided</scope> <!-- provided by the agent/plugin-container -->
-      </dependency>
-
-      <dependency>
-         <groupId>org.rhq</groupId>
-         <artifactId>rhq-core-plugin-api</artifactId>
-         <version>${rhq.version}</version>
-         <scope>provided</scope> <!-- provided by the agent/plugin-container -->
-      </dependency>
-
-      <dependency>
-         <groupId>org.rhq</groupId>
-         <artifactId>rhq-core-native-system</artifactId>
-         <version>${rhq.version}</version>
-         <scope>provided</scope> <!-- provided by the agent/plugin-container -->
-      </dependency>
-
-      <!-- Fix for the Javac bug requiring annotations to be available when \
                compiling classes. (fixed in JDK 6) -->
-      <dependency>
-         <groupId>javax.persistence</groupId>
-         <artifactId>persistence-api</artifactId>
-         <version>1.0</version>
-         <scope>provided</scope> <!-- provided by the agent/plugin-container -->
-      </dependency>
-
-      <!-- Fix for the Javac bug requiring annotations to be available when \
                compiling classes. (fixed in JDK 6) -->
-      <dependency>
-         <groupId>hibernate-annotations</groupId>
-         <artifactId>hibernate-annotations</artifactId>
-         <version>3.2.1.GA</version>
-         <scope>provided</scope> <!-- provided by the agent/plugin-container -->
-      </dependency>
-
-      <!-- Fix for the Javac bug requiring annotations to be available when \
                compiling classes. (fixed in JDK 6) -->
-      <dependency>
-         <groupId>javax.xml.bind</groupId>
-         <artifactId>jaxb-api</artifactId>
-         <version>2.1</version>
-         <scope>provided</scope> <!-- provided by the agent/plugin-container -->
-      </dependency>
-
-      <!--
-         Uncomment the one of the three logging systems your plugin uses: log4j, \
                commons-logging or i18nlog
-         All three are provided to your plugin by the agent/plugin-container.
-      -->
-      <dependency>
-         <groupId>commons-logging</groupId>
-         <artifactId>commons-logging</artifactId>
-         <version>1.1</version>
-         <scope>provided</scope>
-      </dependency>
-
-      <!-- Define any third-party dependencies your plugin has here. -->
-      <!--
-      <dependency>
-         <groupId>group-id-of-dependency-goes-here</groupId>
-         <artifactId>artifact-id-of-dependency-goes-here</artifactId>
-         <version>version-of-dependency-goes-here</version>
-      </dependency>
-      -->
-
-   </dependencies>
-
-   <build>
-      <plugins>
-
-         <plugin>
-            <artifactId>maven-compiler-plugin</artifactId>
-            <configuration>
-               <source>1.5</source>
-               <target>1.5</target>
-            </configuration>
-         </plugin>
-
-         <plugin>
-            <groupId>org.rhq</groupId>
-            <artifactId>rhq-plugin-validator</artifactId>
-            <version>${rhq.version}</version>
-         </plugin>
-
-
-      </plugins>
-   </build>
-
    <profiles>
       <profile>
          <id>dev</id>
diff --git a/modules/plugins/nss/src/main/resources/META-INF/rhq-plugin.xml \
b/modules/plugins/nss/src/main/resources/META-INF/rhq-plugin.xml index \
                305129e..2ad376e 100644
--- a/modules/plugins/nss/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/nss/src/main/resources/META-INF/rhq-plugin.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 
-<plugin name=""
+<plugin name="NSS"
         displayName="Name Service Switch"
         version="1.0"
         package="org.rhq.plugin.nss"
@@ -30,4 +30,6 @@
          <c:simple-property name="aliases"    displayName="aliases"    default="" /> \
  </resource-configuration>
    </server>
+
 </plugin>
+


commit e4637fefe54591d1b7a8001dd153755f388d382a
Author: Ian Springer <ian.springer at redhat.com>
Date:   Tue Jun 29 17:20:56 2010 -0400

    disable raw config support in GUI \
(https://bugzilla.redhat.com/show_bug.cgi?id=609211)

diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml \
b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml
 index d10c5f4..9aafddc 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml
                
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/edit.xhtml
 @@ -25,27 +25,6 @@ THIS TEXT WILL BE REMOVED.
   <ui:param name="selectedTabName" value="Configuration.Current"/>
 
   <ui:define name="content">
-    <script type="text/javascript">
-      function cursor_wait() {
-        document.body.style.cursor = 'wait';
-      }
-
-      function cursor_clear() {
-        document.body.style.cursor = 'default';
-      }
-
-      var currentFileModified = false;
-
-      var selectedFile = '';
-
-      function setCurrentFileModified() {
-        currentFileModified = true;
-      }
-
-      function resetCurrentFile() {
-        currentFileModified;
-      }
-    </script>
 
     <h:panelGroup layout="block" styleClass="InfoBlock"
                   rendered="#{configurationEditor.updateInProgress}">
@@ -82,64 +61,11 @@ THIS TEXT WILL BE REMOVED.
         </h:panelGrid>
       </h:panelGrid>
 
-      <c:choose>
-        <c:when test="${configurationEditor.rawSupported}">
-          <rich:tabPanel>
-            <rich:tab label="Advanced Mode" onlabelclick="cursor_wait();" \
                oncomplete="cursor_clear();">
-              <ui:include src="raw.xhtml">
-                <ui:param name="readOnly" value="false"/>
-              </ui:include>  
-            </rich:tab>
-          </rich:tabPanel>
-        </c:when>
-
-        <c:when test="${configurationEditor.structuredSupported}">
-          <rich:tabPanel>
-            <rich:tab label="Basic Mode" onlabelclick="cursor_wait();" \
                oncomplete="cursor_clear();">
-              <ui:include src="structured.xhtml">
-                <ui:param name="readOnly" value="false"/>
-              </ui:include>
-
-              <ui:remove>
-              <h:panelGrid columns="2" styleClass="buttons-table" \
                columnClasses="button-cell"
-                           rendered="#{resourceConfiguration != null}">
-                <h:commandButton value="SAVE" \
                action="#{configurationEditor.updateConfiguration}"
-                                 title="Click to Save Changes" \
                styleClass="buttonmed"
-                                 \
                rendered="${ResourceUIBean.permissions.configure}"/>
-                <h:commandButton value="RESET" type="reset" immediate="true"
-                                 title="Click to Reset Fields" \
                styleClass="buttonmed"/>
-              </h:panelGrid>
-              </ui:remove>
-            </rich:tab>
-          </rich:tabPanel>
-        </c:when>
-
-        <c:when test="${configurationEditor.structuredAndRawSupported}">
-          <rich:tabPanel id="configTabPanel"
-                         selectedTab="#{configurationEditor.selectedTab}"
-                         switchType="ajax"
-                         valueChangeListener="#{configurationEditor.changeTabs}">
-            <rich:tab id="structuredTab"
-                      label="Basic Mode"
-                      reRender="lowerCommitPanel,upperCommitPanel,modalEditor"
-                      onlabelclick="cursor_wait();"
-                      oncomplete="cursor_clear();">
-              <ui:include src="structured.xhtml">
-                <ui:param name="readOnly" value="false"/>
-              </ui:include>
-            </rich:tab>
-            <rich:tab id="rawTab"
-                      label="Advanced Mode"
-                      \
                reRender="fileMenuPanel,upperCommitPanel,lowerCommitPanel,modalEditor"
                
-                      onlabelclick="cursor_wait();"
-                      oncomplete="cursor_clear();">
-              <ui:include src="raw.xhtml">
-                <ui:param name="readOnly" value="false"/>
-              </ui:include>
-            </rich:tab>
-          </rich:tabPanel>
-        </c:when>
-      </c:choose>
+      <c:if test="${configurationEditor.structuredSupported or \
configurationEditor.structuredAndRawSupported}"> +          <ui:include \
src="structured.xhtml"> +              <ui:param name="readOnly" value="false"/>
+          </ui:include>
+      </c:if>
 
       <h:panelGrid columns="1" style="width:100%" columnClasses="raw-edit-footer">
         <h:panelGroup id="lowerCommitPanel" style="text-align:right">
@@ -163,19 +89,8 @@ THIS TEXT WILL BE REMOVED.
         </h:panelGroup>
       </h:panelGrid>
 
-      <ui:include src="view-raw-modal.xhtml">
-        <ui:param name="readOnly" value="false"/>
-      </ui:include>
-
-      <ui:include src="error-window.xhtml"/>
     </h:form>
 
-    <!--
-      upload-modal.xhtml needs to be included outside the above form because the \
                file upload component requires its
-      own, separate form.
-    -->
-    <ui:include src="upload-modal.xhtml"/>
-
   </ui:define>
 
 </ui:composition>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml \
b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml
 index 6541456..7a40797 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml
                
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/configuration/view.xhtml
 @@ -27,15 +27,6 @@ THIS TEXT WILL BE REMOVED.
   <ui:param name="selectedTabName" value="Configuration.Current"/>
 
   <ui:define name="content">
-    <script type="text/javascript">
-      function cursor_wait() {
-        document.body.style.cursor = 'wait';
-      }
-
-      function cursor_clear() {
-        document.body.style.cursor = 'default';
-      }
-    </script>
 
     <h:panelGroup layout="block" styleClass="InfoBlock"
                   rendered="#{configurationViewer.updateInProgress}">
@@ -60,46 +51,9 @@ THIS TEXT WILL BE REMOVED.
         </h:panelGrid>
       </h:panelGrid>
 
-      <c:choose>
-        <c:when test="${configurationViewer.rawSupported}">
-          <rich:tabPanel>
-            <rich:tab label="Advanced Mode">
-              <ui:include src="raw.xhtml"/>
-            </rich:tab>
-          </rich:tabPanel>
-        </c:when>
-
-        <c:when test="${configurationViewer.structuredSupported}">
-          <rich:tabPanel>
-            <rich:tab label="Basic Mode">
-              <ui:include src="structured.xhtml"/>
-            </rich:tab>
-          </rich:tabPanel>
-        </c:when>
-
-        <c:when test="${configurationViewer.structuredAndRawSupported}">
-          <rich:tabPanel id="resourceConfigurationTabPanel"
-                         switchType="ajax"
-                         valueChangeListener="#{configurationViewer.changeTabs}">
-            <rich:tab id="structuredTab"
-                      label="Basic Mode"
-                      onlabelclick="cursor_wait();"
-                      oncomplete="cursor_clear();"
-                      limitToList="true"
-                      reRender="upperEditButton,lowerEditButton,modalEditor">
-              <ui:include src="structured.xhtml"/>
-            </rich:tab>
-            <rich:tab id="rawTab"
-                      label="Advanced Mode"
-                      onlabelclick="cursor_wait();"
-                      oncomplete="cursor_clear();"
-                      limitToList="true" 
-                      reRender="upperEditButton,lowerEditButton,modalEditor">
-              <ui:include src="raw.xhtml"/>
-            </rich:tab>
-          </rich:tabPanel>
-        </c:when>
-      </c:choose>
+      <c:if test="${configurationViewer.structuredSupported or \
configurationViewer.structuredAndRawSupported}"> +          <ui:include \
src="structured.xhtml"/> +      </c:if>
 
       <h:panelGrid columns="1" style="width:100%" columnClasses="raw-edit-footer">
         <h:panelGroup style="text-align:right">
@@ -114,7 +68,6 @@ THIS TEXT WILL BE REMOVED.
         </h:panelGroup>
       </h:panelGrid>
 
-      <ui:include src="view-raw-modal.xhtml"/>
     </h:form>
   </ui:define>
 


commit e6438c474e3eb5788b913893ab8c5db270dbbe3a
Author: Ian Springer <ian.springer at redhat.com>
Date:   Tue Jun 29 17:18:30 2010 -0400

    fix issue caused by original fix for IE scrollbar issue \
                (https://bugzilla.redhat.com/show_bug.cgi?id=601744)
     which was causing vertical scrollbar on Resource tab pages to be displayed by FF \
at 2/3 of the correct width

diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/entity/layout/main.xhtml \
b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/entity/layout/main.xhtml \
                index 7629fd7..e249621 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/entity/layout/main.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/entity/layout/main.xhtml
@@ -49,8 +49,8 @@ id - the id of the Resource being accessed
                 </div>
             </div>
             <div id="centerContent" class="column" style="width: #{100 - \
                UserPreferencesUIBean.leftResourceNavState}%;">
-                <div id="centerContentWrapper" class="content-right" \
                style="position: relative">
-                    <div style="left: 0; right: 0; height: 100%;">
+                <div id="centerContentWrapper" class="content-right">
+                    <div style="left: 0; right: 0; height: 100%; position: \
                relative">
                         <ui:insert name="summary"><p>Default Entity \
                Summary</p></ui:insert>
                         <ui:insert name="tabBar"><p>Default Entity \
                TabBar</p></ui:insert>
                         <ui:insert name="content"><p>Default Entity \
Content</p></ui:insert>


commit eee5ad2d562b8377c670f44a07fa1a0d59257c95
Author: Joseph Marques <joseph at redhat.com>
Date:   Tue Jun 29 17:08:05 2010 -0400

    BZ-607672: add more silience during notfication processing
    
    * gracefully handle cases when server-plugin plugin container is in one of \
                various initializing states
    * do not bomb during alert notification sender if server-side plugin container \
hasn't started completely

diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java \
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
 index 0fc7840..c856a24 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
                
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
 @@ -656,6 +656,8 @@ public class AlertManagerBean implements AlertManagerLocal, \
                AlertManagerRemote {
             List<AlertNotification> alertNotifications = \
alert.getAlertDefinition().getAlertNotifications();  Set<String> emailAddresses = new \
LinkedHashSet<String>();  
+            AlertSenderPluginManager alertSenderPluginManager = \
getAlertPluginManager(); +
             for (AlertNotification alertNotification : alertNotifications) {
 
                 // Send over the new AlertSender plugins
@@ -666,7 +668,7 @@ public class AlertManagerBean implements AlertManagerLocal, \
AlertManagerRemote {  }
 
                 AlertNotificationLog alNoLo;
-                AlertSender sender = getAlertSender(alertNotification);
+                AlertSender<?> sender = \
alertSenderPluginManager.getAlertSenderForNotification(alertNotification);  
                 if (sender != null) {
                     try {
@@ -704,7 +706,13 @@ public class AlertManagerBean implements AlertManagerLocal, \
AlertManagerRemote {  }
 
             // send them off
-            Collection<String> badAddresses = sendAlertNotificationEmails(alert, \
emailAddresses); +            Collection<String> badAddresses = null;
+            try {
+                badAddresses = sendAlertNotificationEmails(alert, emailAddresses);
+            } catch (Throwable t) {
+                badAddresses = new ArrayList<String>();
+                log.error("Could not send emails to " + emailAddresses + " for " + \
alert + ", cause:", t); +            }
             // TODO we may do the same for SMS in the future.
 
             // log those bad addresses to the gui and their individual senders (if \
possible) @@ -734,8 +742,8 @@ public class AlertManagerBean implements \
AlertManagerLocal, AlertManagerRemote {  }
             }
 
-        } catch (Exception e) {
-            log.error("Failed to send all notifications for " + \
alert.toSimpleString(), e); +        } catch (Throwable t) {
+            log.error("Failed to send all notifications for " + \
alert.toSimpleString(), t);  }
     }
 
@@ -745,18 +753,20 @@ public class AlertManagerBean implements AlertManagerLocal, \
                AlertManagerRemote {
      */
     public AlertSenderPluginManager getAlertPluginManager() {
         MasterServerPluginContainer container = \
LookupUtil.getServerPluginService().getMasterPluginContainer(); +        if \
(container == null) { +            \
log.warn(MasterServerPluginContainer.class.getSimpleName() + " is not started yet"); \
+            return null; +        }
         AlertServerPluginContainer pc = \
container.getPluginContainerByClass(AlertServerPluginContainer.class); +        if \
(pc == null) { +            log.warn(AlertServerPluginContainer.class.getSimpleName() \
+ " has not been loaded by the " +                + \
MasterServerPluginContainer.class.getSimpleName() + " yet"); +            return \
null; +        }
         AlertSenderPluginManager manager = (AlertSenderPluginManager) \
                pc.getPluginManager();
-
         return manager;
     }
 
-    AlertSender getAlertSender(AlertNotification notification) {
-        AlertSenderPluginManager manager = getAlertPluginManager();
-        AlertSender sender = manager.getAlertSenderForNotification(notification);
-        return sender;
-    }
-
     /**
      *
      * @param alert
@@ -765,9 +775,9 @@ public class AlertManagerBean implements AlertManagerLocal, \
                AlertManagerRemote {
      */
     private Collection<String> sendAlertNotificationEmails(Alert alert, Set<String> \
emailAddresses) {  
-        if (emailAddresses.size()==0)
+        if (emailAddresses.size() == 0)
             return new ArrayList<String>(0); // No email to send -> no bad addresses
-        
+
         log.debug("Sending alert notifications for " + alert.toSimpleString() + \
"...");  
         AlertDefinition alertDefinition = alert.getAlertDefinition();


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic