[rhq] Branch 'release/jon3.2.x' - modules/plugins
by lkrejci
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 37 +++++-----
1 file changed, 21 insertions(+), 16 deletions(-)
New commits:
commit d7c63e2cecf690918c5f0d59de6a6e06eaf91237
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue Nov 26 18:52:31 2013 +0100
Bug 1034218 - EAR subdeployments are not discovered for DomainDeployment
(cherry picked from commit d28e22f0c77f127efe6ff3f63f0f82e22c20083a)
Signed-off-by: Lukas Krejci <lkrejci(a)redhat.com>
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 7cfe9da..df168ac 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -8874,10 +8874,10 @@
<c:simple-property name="archive" type="boolean" readOnly="true" required="false" description="Flag indicating whether unmanaged content is a zip archive (true) or exploded (false)."/>
</c:map-property>
</c:list-property>
- <c:simple-property name="enabled" required="true" type="boolean" readOnly="true" description="Boolean indicating whether the deployment content is currently deployed in the runtime (or should be deployed in the runtime the next time the server starts.)"/>
- <c:simple-property name="name" required="true" type="string" readOnly="true" description="Unique identifier of the deployment. Must be unique across all deployments."/>
- <c:simple-property name="persistent" required="true" type="boolean" readOnly="true" description="Boolean indicating whether the existence of the deployment should be recorded in the persistent server configuration. Only relevant to a standalone mode server. Default is 'true'. A deployment managed by a deployment scanner would have this set to 'false' to ensure the deployment is only deployed at server start if the scanner again detects the deployment."/>
- <c:simple-property name="runtime-name" required="true" type="string" readOnly="true" description="Name by which the deployment should be known within a server runtime. This would be equivalent to the file name of a deployment file, and would form the basis for such things as default Java Enterprise Edition application and module names. This would typically be the same as 'name', but in some cases users may wish to have two deployments with the same runtime-name (e.g. two versions of foo.war) both available in the deployment content repository, in which case the deployments would need to have distinct name; values but would have the same runtime-name."/>
+ <c:simple-property name="enabled" required="false" type="boolean" readOnly="true" description="Boolean indicating whether the deployment content is currently deployed in the runtime (or should be deployed in the runtime the next time the server starts.)"/>
+ <c:simple-property name="name" required="false" type="string" readOnly="true" description="Unique identifier of the deployment. Must be unique across all deployments."/>
+ <c:simple-property name="persistent" required="false" type="boolean" readOnly="true" description="Boolean indicating whether the existence of the deployment should be recorded in the persistent server configuration. Only relevant to a standalone mode server. Default is 'true'. A deployment managed by a deployment scanner would have this set to 'false' to ensure the deployment is only deployed at server start if the scanner again detects the deployment."/>
+ <c:simple-property name="runtime-name" required="false" type="string" readOnly="true" description="Name by which the deployment should be known within a server runtime. This would be equivalent to the file name of a deployment file, and would form the basis for such things as default Java Enterprise Edition application and module names. This would typically be the same as 'name', but in some cases users may wish to have two deployments with the same runtime-name (e.g. two versions of foo.war) both available in the deployment content repository, in which case the deployments would need to have distinct name; values but would have the same runtime-name."/>
</resource-configuration>
</service>
@@ -8957,6 +8957,7 @@
<runs-inside>
<parent-resource-type name="Deployment" plugin="&pluginName;"/>
<parent-resource-type name="Subdeployment" plugin="&pluginName;"/>
+ <parent-resource-type name="ManagedServerDeployment" plugin="&pluginName;"/>
</runs-inside>
<plugin-configuration>
@@ -8997,7 +8998,7 @@
<c:simple-property name="background-validation-millis" required="false" type="long" readOnly="true" description="The background-validation-millis element specifies the amount of time, in milliseconds, that background validation will run. Changing this value can be done only on disabled datasource, requires a server restart otherwise"/>
<c:simple-property name="blocking-timeout-wait-millis" required="false" type="long" readOnly="true" description="The blocking-timeout-millis element specifies the maximum time, in milliseconds, to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for locking a connection, and will never throw an exception if creating a new connection takes an inordinately long time"/>
<c:simple-property name="check-valid-connection-sql" required="false" type="string" readOnly="true" description="Specify an SQL statement to check validity of a pool connection. This may be called when managed connection is obtained from the pool"/>
- <c:simple-property name="driver-name" required="true" type="string" readOnly="true" description="Defines the JDBC driver the datasource should use. It is a symbolic name matching the the name of installed driver. In case the driver is deployed as jar, the name is the name of deployment unit"/>
+ <c:simple-property name="driver-name" required="false" type="string" readOnly="true" description="Defines the JDBC driver the datasource should use. It is a symbolic name matching the the name of installed driver. In case the driver is deployed as jar, the name is the name of deployment unit"/>
<c:simple-property name="enabled" required="false" type="boolean" readOnly="true" description="Specifies if the datasource should be enabled"/>
<c:simple-property name="exception-sorter-class-name" required="false" type="string" readOnly="true" description="An org.jboss.jca.adapters.jdbc.ExceptionSorter that provides an isExceptionFatal(SQLException) method to validate if an exception should broadcast an error"/>
<c:map-property name="exception-sorter-properties" description="The exception sorter properties">
@@ -9012,7 +9013,7 @@
</c:simple-property>
<c:simple-property name="idle-timeout-minutes" required="false" type="long" readOnly="true" description="The idle-timeout-minutes elements specifies the maximum time, in minutes, a connection may be idle before being closed. The actual maximum time depends also on the IdleRemover scan time, which is half of the smallest idle-timeout-minutes value of any pool. Changing this value can be done only on disabled datasource, requires a server restart otherwise."/>
<c:simple-property name="interleaving" required="false" type="boolean" readOnly="true" defaultValue="false" description="An element to enable interleaving for XA connections. The default value is false."/>
- <c:simple-property name="jndi-name" required="true" type="string" readOnly="true" description="Specifies the JNDI name for the datasource"/>
+ <c:simple-property name="jndi-name" required="false" type="string" readOnly="true" description="Specifies the JNDI name for the datasource"/>
<c:simple-property name="jta" required="false" type="boolean" readOnly="true" defaultValue="true" description="Enable JTA integration. The default value is true."/>
<c:simple-property name="max-pool-size" required="false" type="integer" readOnly="true" defaultValue="20" description="The max-pool-size element specifies the maximum number of connections for a pool. No more connections will be created in each sub-pool. The default value is 20."/>
<c:simple-property name="min-pool-size" required="false" type="integer" readOnly="true" defaultValue="0" description="The min-pool-size element specifies the minimum number of connections for a pool. The default value is 0."/>
@@ -9120,10 +9121,10 @@
<c:simple-property name="background-validation-millis" required="false" type="long" readOnly="true" description="The background-validation-millis element specifies the amount of time, in milliseconds, that background validation will run. Changing this value can be done only on disabled datasource, requires a server restart otherwise"/>
<c:simple-property name="blocking-timeout-wait-millis" required="false" type="long" readOnly="true" description="The blocking-timeout-millis element specifies the maximum time, in milliseconds, to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for locking a connection, and will never throw an exception if creating a new connection takes an inordinately long time"/>
<c:simple-property name="check-valid-connection-sql" required="false" type="string" readOnly="true" description="Specify an SQL statement to check validity of a pool connection. This may be called when managed connection is obtained from the pool"/>
- <c:simple-property name="connection-url" required="true" type="string" readOnly="true" description="The JDBC driver connection URL"/>
+ <c:simple-property name="connection-url" required="false" type="string" readOnly="true" description="The JDBC driver connection URL"/>
<c:simple-property name="datasource-class" required="false" type="string" readOnly="true" description="The fully qualifed name of the JDBC datasource class"/>
<c:simple-property name="driver-class" required="false" type="string" readOnly="true" description="The fully qualifed name of the JDBC driver class"/>
- <c:simple-property name="driver-name" required="true" type="string" readOnly="true" description="Defines the JDBC driver the datasource should use. It is a symbolic name matching the the name of installed driver. In case the driver is deployed as jar, the name is the name of deployment unit"/>
+ <c:simple-property name="driver-name" required="false" type="string" readOnly="true" description="Defines the JDBC driver the datasource should use. It is a symbolic name matching the the name of installed driver. In case the driver is deployed as jar, the name is the name of deployment unit"/>
<c:simple-property name="enabled" required="false" type="boolean" readOnly="true" description="Specifies if the datasource should be enabled"/>
<c:simple-property name="exception-sorter-class-name" required="false" type="string" readOnly="true" description="An org.jboss.jca.adapters.jdbc.ExceptionSorter that provides an isExceptionFatal(SQLException) method to validate if an exception should broadcast an error"/>
<c:map-property name="exception-sorter-properties" description="The exception sorter properties">
@@ -9137,7 +9138,7 @@
</c:property-options>
</c:simple-property>
<c:simple-property name="idle-timeout-minutes" required="false" type="long" readOnly="true" description="The idle-timeout-minutes elements specifies the maximum time, in minutes, a connection may be idle before being closed. The actual maximum time depends also on the IdleRemover scan time, which is half of the smallest idle-timeout-minutes value of any pool. Changing this value can be done only on disabled datasource, requires a server restart otherwise."/>
- <c:simple-property name="jndi-name" required="true" type="string" readOnly="true" description="Specifies the JNDI name for the datasource"/>
+ <c:simple-property name="jndi-name" required="false" type="string" readOnly="true" description="Specifies the JNDI name for the datasource"/>
<c:simple-property name="jta" required="false" type="boolean" readOnly="true" defaultValue="true" description="Enable JTA integration. The default value is true."/>
<c:simple-property name="max-pool-size" required="false" type="integer" readOnly="true" defaultValue="20" description="The max-pool-size element specifies the maximum number of connections for a pool. No more connections will be created in each sub-pool. The default value is 20."/>
<c:simple-property name="min-pool-size" required="false" type="integer" readOnly="true" defaultValue="0" description="The min-pool-size element specifies the minimum number of connections for a pool. The default value is 0."/>
@@ -9204,6 +9205,7 @@
<runs-inside>
<parent-resource-type name="Deployment" plugin="&pluginName;"/>
<parent-resource-type name="Subdeployment" plugin="&pluginName;"/>
+ <parent-resource-type name="ManagedServerDeployment" plugin="&pluginName;"/>
</runs-inside>
<plugin-configuration>
@@ -9667,7 +9669,7 @@
<metric property="temporary" dataType="trait" description="Whether the queue is temporary."/>
<resource-configuration>
- <c:list-property name="entries" required="true" readOnly="true" description="The jndi names the queue will be bound to.">
+ <c:list-property name="entries" required="false" readOnly="true" description="The jndi names the queue will be bound to.">
<c:simple-property name="entry" type="string" description="A single JNDI entry"/>
</c:list-property>
</resource-configuration>
@@ -9784,7 +9786,7 @@
<metric property="topic-address" dataType="trait" description="The address the topic points to."/>
<resource-configuration>
- <c:list-property name="entries" required="true" readOnly="true" displayName="JNDI Names" description="The jndi names the queue will be bound to.">
+ <c:list-property name="entries" required="false" readOnly="true" displayName="JNDI Names" description="The jndi names the queue will be bound to.">
<c:simple-property name="entry" type="string" description="A single JNDI entry"/>
</c:list-property>
</resource-configuration>
@@ -9803,6 +9805,7 @@
<runs-inside>
<parent-resource-type name="Deployment" plugin="&pluginName;"/>
<parent-resource-type name="Subdeployment" plugin="&pluginName;"/>
+ <parent-resource-type name="ManagedServerDeployment" plugin="&pluginName;"/>
</runs-inside>
<plugin-configuration>
@@ -10001,6 +10004,7 @@
<runs-inside>
<parent-resource-type name="Deployment" plugin="&pluginName;"/>
<parent-resource-type name="Subdeployment" plugin="&pluginName;"/>
+ <parent-resource-type name="ManagedServerDeployment" plugin="&pluginName;"/>
</runs-inside>
<plugin-configuration>
@@ -10025,11 +10029,11 @@
<metric property="total-processing-time" description="Total endpoint processing time."/>
<resource-configuration>
- <c:simple-property name="class" required="true" type="string" readOnly="true" description="Webservice endpoint class."/>
- <c:simple-property name="context" required="true" type="string" readOnly="true" description="Webservice endpoint context."/>
- <c:simple-property name="name" required="true" type="string" readOnly="true" description="Webservice endpoint name."/>
- <c:simple-property name="type" required="true" type="string" readOnly="true" description="Webservice endpoint type."/>
- <c:simple-property name="wsdl-url" required="true" type="string" readOnly="true" description="Webservice endpoint WSDL URL."/>
+ <c:simple-property name="class" required="false" type="string" readOnly="true" description="Webservice endpoint class."/>
+ <c:simple-property name="context" required="false" type="string" readOnly="true" description="Webservice endpoint context."/>
+ <c:simple-property name="name" required="false" type="string" readOnly="true" description="Webservice endpoint name."/>
+ <c:simple-property name="type" required="false" type="string" readOnly="true" description="Webservice endpoint type."/>
+ <c:simple-property name="wsdl-url" required="false" type="string" readOnly="true" description="Webservice endpoint WSDL URL."/>
</resource-configuration>
</service>
@@ -10045,6 +10049,7 @@
<runs-inside>
<parent-resource-type name="Deployment" plugin="&pluginName;"/>
<parent-resource-type name="Subdeployment" plugin="&pluginName;"/>
+ <parent-resource-type name="ManagedServerDeployment" plugin="&pluginName;"/>
</runs-inside>
<plugin-configuration>
10 years, 4 months
[rhq] modules/enterprise
by John Sanda
modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java | 16 ++-
modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java | 47 ++++++++--
2 files changed, 49 insertions(+), 14 deletions(-)
New commits:
commit 05fa7f2955d76f1b7af4b39c210462c8cebd554f
Author: John Sanda <jsanda(a)redhat.com>
Date: Thu Jan 16 10:49:02 2014 +0100
[BZ 1009945] fix broken tests and regression for missed aggregation run
diff --git a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
index 1b43dc7..3b0231c 100644
--- a/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
+++ b/modules/enterprise/server/server-metrics/src/main/java/org/rhq/server/metrics/MetricsServer.java
@@ -481,16 +481,22 @@ public class MetricsServer {
try {
DateTime theHour = currentHour();
- if (pastAggregationMissed) {
- theHour = roundDownToHour(mostRecentRawDataPriorToStartup).plusHours(1);
- pastAggregationMissed = false;
- }
-
if (useAsyncAggregation) {
+ if (pastAggregationMissed) {
+ DateTime missedHour = roundDownToHour(mostRecentRawDataPriorToStartup);
+ new Aggregator(aggregationWorkers, dao, configuration, dateTimeService, missedHour,
+ aggregationBatchSize, writePermits, readPermits).run();
+ pastAggregationMissed = false;
+ }
+
DateTime timeSlice = theHour.minus(configuration.getRawTimeSliceDuration());
return new Aggregator(aggregationWorkers, dao, configuration, dateTimeService, timeSlice,
aggregationBatchSize, writePermits, readPermits).run();
} else {
+ if (pastAggregationMissed) {
+ calculateAggregates(roundDownToHour(mostRecentRawDataPriorToStartup).plusHours(1).getMillis());
+ pastAggregationMissed = false;
+ }
return calculateAggregates(theHour.getMillis());
}
} finally {
diff --git a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
index b3ffb66..3809a59 100644
--- a/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
+++ b/modules/enterprise/server/server-metrics/src/test/java/org/rhq/server/metrics/MetricsServerTest.java
@@ -80,7 +80,7 @@ public class MetricsServerTest extends CassandraIntegrationTest {
private MetricsDAO dao;
- private DateTimeService dateTimeService;
+ private DateTimeServiceStub dateTimeService;
private MetricsConfiguration configuration = new MetricsConfiguration();
@@ -101,12 +101,37 @@ public class MetricsServerTest extends CassandraIntegrationTest {
}
+ private static class DateTimeServiceStub extends DateTimeService {
+
+ private DateTime now;
+
+ public void setNow(DateTime now) {
+ this.now = now;
+ }
+
+ @Override
+ public DateTime now() {
+ if (now == null) {
+ return super.now();
+ }
+ return now;
+ }
+
+ @Override
+ public long nowInMillis() {
+ if (now == null) {
+ return super.nowInMillis();
+ }
+ return now.getMillis();
+ }
+ }
+
@BeforeMethod
public void initServer() throws Exception {
metricsServer = new MetricsServerStub();
metricsServer.setConfiguration(configuration);
- dateTimeService = new DateTimeService();
+ dateTimeService = new DateTimeServiceStub();
dateTimeService.setConfiguration(configuration);
metricsServer.setDateTimeService(dateTimeService);
@@ -116,6 +141,11 @@ public class MetricsServerTest extends CassandraIntegrationTest {
purgeDB();
}
+ private void setNow(DateTime now) {
+ metricsServer.setCurrentHour(now.minusHours(1));
+ dateTimeService.setNow(now);
+ }
+
private void purgeDB() throws Exception {
session.execute("TRUNCATE " + MetricsTable.RAW);
session.execute("TRUNCATE " + MetricsTable.ONE_HOUR);
@@ -184,7 +214,7 @@ public class MetricsServerTest extends CassandraIntegrationTest {
WaitForRawInserts waitForRawInserts = new WaitForRawInserts(data.size());
- metricsServer.setCurrentHour(hour6);
+ setNow(hour6.plusHours(1));
metricsServer.addNumericData(data, waitForRawInserts);
waitForRawInserts.await("Failed to insert raw data");
@@ -240,7 +270,7 @@ public class MetricsServerTest extends CassandraIntegrationTest {
}
waitForIndexUpdates.await("Failed to update metrics index for raw data");
- metricsServer.setCurrentHour(hour9);
+ setNow(hour9.plusHours(1));
metricsServer.calculateAggregates();
// verify that the 1 hour aggregates are calculated
@@ -272,7 +302,6 @@ public class MetricsServerTest extends CassandraIntegrationTest {
int scheduleId = 123;
DateTime hour0 = hour0();
- DateTime hour12 = hour0.plusHours(12);
DateTime hour6 = hour0.plusHours(6);
DateTime hour7 = hour0.plusHours(7);
DateTime hour8 = hour0.plusHours(8);
@@ -302,7 +331,7 @@ public class MetricsServerTest extends CassandraIntegrationTest {
dao.updateMetricsIndex(MetricsTable.SIX_HOUR, indexUpdates);
// execute the system under test
- metricsServer.setCurrentHour(hour12);
+ setNow(hour0().plusHours(13));
metricsServer.calculateAggregates();
// verify the results
@@ -352,7 +381,7 @@ public class MetricsServerTest extends CassandraIntegrationTest {
//
// 2) re-initialize the metrics server
// 3) insert some more raw data
- metricsServer.setCurrentHour(hour15);
+ setNow(hour0().plusHours(16));
metricsServer.init();
rawData = new HashSet<MeasurementDataNumeric>();
@@ -417,7 +446,7 @@ public class MetricsServerTest extends CassandraIntegrationTest {
//
// 2) re-initialize the metrics server
// 3) insert some more raw data
- metricsServer.setCurrentHour(hour9);
+ setNow(hour0().plusHours(10));
metricsServer.init();
rawData = new HashSet<MeasurementDataNumeric>();
@@ -494,7 +523,7 @@ public class MetricsServerTest extends CassandraIntegrationTest {
dao.updateMetricsIndex(MetricsTable.TWENTY_FOUR_HOUR, indexUpdates);
// execute the system under test
- metricsServer.setCurrentHour(hour24);
+ setNow(hour24.plusHours(1));
metricsServer.calculateAggregates();
// verify the results
10 years, 4 months
[rhq] Changes to 'bug/1034218'
by Thomas Segismont
New branch 'bug/1034218' available with the following commits:
commit f93fa4c72831225a79788fc049d4164caa1c831a
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Tue Nov 26 18:52:31 2013 +0100
Bug 1034218 - EAR subdeployments are not discovered for DomainDeployment (cherr-picked from master d28e22f0c77f127efe6ff3f63f0f82e22c20083a)
10 years, 4 months
[rhq] Branch 'stefan/angulardemo' - angular/app.html angular/app.js angular/.gitignore angular/package.json
by snegrea
angular/.gitignore | 1
angular/app.html | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++
angular/app.js | 14 ++
angular/package.json | 7 +
4 files changed, 327 insertions(+)
New commits:
commit bd8802fccff2a540697ed93a666b1a1251f9c5fc
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Sat Jan 11 23:51:51 2014 -0600
Angular sample ....
diff --git a/angular/.gitignore b/angular/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/angular/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/angular/app.html b/angular/app.html
new file mode 100644
index 0000000..21ac993
--- /dev/null
+++ b/angular/app.html
@@ -0,0 +1,305 @@
+<html>
+
+<head>
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
+<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/2.0.1/js/toastr.min.js"></script>
+<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/2.0.1/css/toastr.min.css">
+<script src="//code.angularjs.org/1.2.5/angular.js"></script>
+<script src="//code.angularjs.org/1.2.5/angular-resource.js"></script>
+
+<style>
+.circle {
+ position: absolute;
+ border-radius: 50%;
+ background-color: #d9edf7;
+ border: 4px solid #fff;
+ box-shadow: 0 0 0 5px #bce8f1;
+ text-align: center;
+ font-size: 18px;
+ font-weight: bold;
+}
+
+.btn {
+ border: 0px solid transparent;
+ font-size: 12px;
+}
+
+.panel-heading {
+ padding: 3px 5px;
+}
+</style>
+
+
+<script type="text/javascript">
+var m = angular.module('StorageClusterApp', [
+ 'ngResource'
+]);
+
+m.factory('MathFun', function($window){
+ return {
+ getBubbleDimensions: function(){
+ return {
+ width: 140,
+ height: 70
+ };
+ },
+ getCircleDimensions: function(numberOfPoints){
+ circle = {};
+ if(numberOfPoints && numberOfPoints >= 4){
+ circle.size = 250 + 40 * (numberOfPoints - 3);
+ } else {
+ circle.size = 250;
+ }
+
+ //for page centering
+ //circle.top = (($window.innerHeight)/2) - (circle.size/2);
+ //circle.left = (($window.innerWidth)/2) - (circle.size/2);
+ circle.top = 50;
+ circle.left = 100;
+
+ if(circle.top<(this.getBubbleDimensions().height/2)){
+ circle.top = this.getBubbleDimensions().height/2;
+ }
+
+ if(circle.left<(this.getBubbleDimensions().width/2)){
+ circle.left = this.getBubbleDimensions().width/2;
+ }
+
+ return circle;
+ },
+ findPointOnCircle: function(pointIndex, totalPoints, circleRadius){
+ var step = ((3.14159265 * 2) / totalPoints);
+ return {
+ x: Math.sin(step * pointIndex) * circleRadius,
+ y: Math.cos(step * pointIndex) * circleRadius
+ }
+ },
+ findBubblePosition: function(pointIndex, numberOfPoints, bubble, circle){
+ var point = this.findPointOnCircle(pointIndex, numberOfPoints, circle.size/2);
+ return {
+ top: circle.size/2 + circle.top + point.y - bubble.height/2,
+ left: circle.size/2 + circle.left + point.x - bubble.width/2
+ }
+ }
+ }
+});
+
+m.factory('CONFIG', function($window){
+ return {
+ apiRoot: 'http://'+$window.location.hostname+':7080/rest'
+ };
+});
+
+m.filter('capitalize', function() {
+ return function(input) {
+ if(input){
+ return input.substring(0,1).toUpperCase()+input.substring(1);
+ }
+ }
+});
+
+m.filter('fixName', function() {
+ return function(input, scope) {
+ if(input){
+ return [input.slice(0, input.indexOf('(')),' ',input.slice(input.indexOf('('))].join('');
+ }
+ }
+});
+
+m.factory('restHook', function($rootScope, $window) {
+ return {
+ request: function(config) {
+ config.headers['Access-Control-Allow-Origin'] = '*';
+ config.headers['Access-Control-Allow-Headers'] = 'Access-Control-Allow-Methods, Authorization';
+ config.headers['Accept'] = 'application/json';
+ config.headers['Authorization'] = 'Basic ' + $window.btoa('rhqadmin' + ':' + 'rhqadmin');
+ return config;
+ }
+ };
+});
+
+m.factory('Resource', function($resource, CONFIG) {
+ return $resource(
+ CONFIG.apiRoot + '/resource', {}, {
+ all: {method: 'GET', isArray: true}
+ });
+});
+
+m.factory('Availability', function($resource, CONFIG){
+ return $resource(
+ CONFIG.apiRoot + '/resource/:id/availability', {}, {
+ get: {method: 'GET'}
+ });
+});
+
+m.factory('OperationDefinitions', function($resource, CONFIG){
+ return $resource(
+ CONFIG.apiRoot + '/operation/definitions', {}, {
+ get: {method: 'GET', isArray: true}
+ });
+});
+
+m.factory('OperationScheduleDefinition', function($resource, CONFIG){
+ return $resource(
+ CONFIG.apiRoot + '/operation/definition/:operationId/', {
+ operationId: '@operationId',
+ resourceId: '@resourceId'
+ }, {
+ create: {method: 'POST'}
+ });
+});
+
+m.factory('OperationExecution', function($resource, CONFIG){
+ return $resource(
+ CONFIG.apiRoot + '/operation/:operationId', {
+ operationId: '@operationId'
+ }, {
+ execute: {method: 'PUT'}
+ });
+});
+
+m.controller('AppController', function($scope, $window, $timeout, Resource, Availability, OperationDefinitions, OperationScheduleDefinition, OperationExecution, MathFun) {
+ $scope.circle = MathFun.getCircleDimensions();
+ $scope.bubble = MathFun.getBubbleDimensions();
+
+ Resource.all({})
+ .$promise
+ .then(function(resources){
+ $scope.resources = resources.filter(function(resource){
+ return resource.typeName.indexOf('Storage Node') != -1;
+ });
+
+ for(var i=6;i--;){
+ $scope.resources.push(JSON.parse(JSON.stringify($scope.resources[0])));
+ }
+
+ $scope.resources.forEach(function(resource, index){
+ resource.operationDefinitions = OperationDefinitions.get({resourceId: resource.resourceId});
+ });
+
+ $scope.resources.forEach(function(resource, index){
+ if(index>4){
+ resource.currentAvailability = {type: 'DOWN'};
+ return;
+ }
+ $scope.refreshAvailability(resource);
+ });
+
+ $scope.positionUI();
+ });
+
+ $scope.positionUI = function(){
+ $scope.circle = MathFun.getCircleDimensions($scope.resources.length);
+ $scope.circle.style = $scope.getCircleStyle();
+
+ $scope.resources.forEach(function(resource, index){
+ resource.style = $scope.getBubbleStyle(index);
+ });
+ };
+
+ $scope.getBubbleStyle = function(index){
+ var bubblePos = MathFun.findBubblePosition(index, $scope.resources.length, $scope.bubble, $scope.circle);
+ return {
+ position: 'absolute',
+ top: bubblePos.top,
+ left: bubblePos.left,
+ width: $scope.bubble.width+'px'
+ };
+ };
+
+ $scope.getCircleStyle = function(){
+ return {
+ height: $scope.circle.size+'px',
+ width: $scope.circle.size+'px',
+ 'line-height': $scope.circle.size+'px',
+ top: $scope.circle.top + 'px',
+ left: $scope.circle.left + 'px'
+ }
+ };
+
+ $scope.executeOperation = function(resource, operation){
+ OperationScheduleDefinition.create({operationId: operation.id, resourceId: resource.resourceId},{})
+ .$promise
+ .then(function(execution){
+ execution.readyToSubmit = true;
+ OperationExecution.execute({operationId: execution.id},execution)
+ .$promise
+ .then(function(response){
+ toastr.success("Operation '" + operation.name +"' executed for " + resource.resourceName);
+ });
+ });
+ };
+
+ $scope.refreshAvailability = function(resource){
+ Availability.get({id: resource.resourceId}).$promise.then(function(result){
+ if(!resource.currentAvailability || resource.currentAvailability.type !== result.type){
+ resource.currentAvailability = result;
+ }
+ });
+ };
+
+ var refresher = function(){
+ $scope.resources.forEach(function(resource, index){
+ $scope.refreshAvailability(resource);
+ });
+ $timeout(refresher,5000);
+ };
+ $timeout(refresher,5000);
+
+ angular.element($window).bind('resize',function(){
+ $scope.$apply(function(){
+ $scope.positionUI();
+ });
+ });
+});
+
+m.config(function($httpProvider) {
+ $httpProvider.interceptors.unshift('restHook');
+ toastr.options = {
+ "closeButton": false,
+ "debug": false,
+ "positionClass": "toast-bottom-full-width",
+ "onclick": null,
+ "showDuration": "3000",
+ "hideDuration": "1000",
+ "timeOut": "2000",
+ "extendedTimeOut": "1000",
+ "showEasing": "swing",
+ "hideEasing": "linear",
+ "showMethod": "fadeIn",
+ "hideMethod": "fadeOut"
+ };
+});
+</script>
+</head>
+
+<body ng-app="StorageClusterApp" ng-controller="AppController">
+ <div class="circle" ng-style="circle.style">RHQ Storage Cluster</div>
+
+ <div class="panel" ng-class="{'panel-primary': resource.currentAvailability.type == 'UP', 'panel-danger': resource.currentAvailability.type !== 'UP'}" ng-style="resource.style" ng-repeat="resource in resources">
+ <div class="panel-heading">
+ <span>{{resource.resourceName | fixName}}</span>
+ <i ng-show="resource.currentAvailability.type === 'UP'" class="glyphicon glyphicon-ok"></i>
+ <i ng-show="resource.currentAvailability.type !== 'UP'" class="glyphicon glyphicon-remove"></i>
+ </div>
+ <div class="btn-group btn-group-justified">
+ <a type="button" class="btn btn-default" ng-click="refreshAvailability(resource)">
+ {{resource.currentAvailability.type}} <i class="glyphicon glyphicon-refresh"></i>
+ </a>
+ <div class="btn-group">
+ <a type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+ Ops
+ <i class="glyphicon glyphicon-flash"></i>
+ </a>
+ <ul class="dropdown-menu" role="menu">
+ <li ng-repeat="operation in resource.operationDefinitions" ng-show="operation.params.length==0">
+ <a href="#" ng-click="executeOperation(resource,operation)">{{operation.name | capitalize}}</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/angular/app.js b/angular/app.js
new file mode 100644
index 0000000..dc6c27e
--- /dev/null
+++ b/angular/app.js
@@ -0,0 +1,14 @@
+var express = require('express');
+var app = express();
+var port = process.env.PORT || 8087;
+
+app.disable('x-powered-by');
+app.use(express.compress());
+
+app.get('*', function(req, res) {
+ return res.sendfile(__dirname + '/app.html');
+});
+
+app.listen(port, function() {
+ console.log('server up on %d', port);
+});
diff --git a/angular/package.json b/angular/package.json
new file mode 100644
index 0000000..a5f85ae
--- /dev/null
+++ b/angular/package.json
@@ -0,0 +1,7 @@
+{
+ "main": "app.js",
+ "private": true,
+ "dependencies": {
+ "express": "~3.4.7"
+ }
+}
10 years, 4 months
[rhq] Changes to 'stefan/angulardemo'
by snegrea
New branch 'stefan/angulardemo' available with the following commits:
commit 3194333fc313e523643f8de4f6c07a0804cc944b
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jan 10 13:10:33 2014 -0600
Add Plugin based UI that loads an iframe with specific UI.
commit d4d9d1329613cea15dfececd28563aa2fdfd641e
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Fri Jan 10 13:09:39 2014 -0600
Add CORS filter to allow correct response for CORS pre-flight requests.
10 years, 4 months
[rhq] Branch 'release/jon3.2.x' - 3 commits - modules/enterprise
by Jay Shaughnessy
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/DashboardView.java | 32
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java | 442 +++++-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java | 263 +----
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties | 3
11 files changed, 341 insertions(+), 420 deletions(-)
New commits:
commit 8932ffebcdeec5c2277e77ab05b9d632637ab0fa
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Jan 10 13:57:14 2014 -0500
[BZ 1038067] - Resource Summary/Activity shows summary of disabled
metrics - fixing the issue for resource groups (Autogroups and
compatible ones).
Also doing some refactoring, because the same code was in the portlet
for resource and for group, so I moved the common functionality to the
group portled and resource portlet overrides the different parts. What
would be even better is to introduce a common abstract class in the new
package
org.rhq.coregui.client.dashboard.portlets.common (the same way it is
done in the org.rhq.coregui.client.inventory.common package). However,
all the portlets follow this pattern (ResourcePortlet extends
GroupPortles), so it would be inconsistent.
After the refactoring, the code is more flat because the callback hell is
not so evil when using own methods for each callback. The toll for it is
the number of arguments that has to be passed to those methods
representing the state that is needed inside the method.
Cherry-Pick master ab5629677b79df0286df8ced99e919264e0b6aba
Signed-off-by: Jay Shaughnessy <jshaughn(a)redhat.com>
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
index c1d7269..e9ee86c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/groups/GroupMetricsPortlet.java
@@ -20,9 +20,9 @@ package org.rhq.coregui.client.dashboard.portlets.groups;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.Timer;
@@ -49,14 +49,15 @@ import com.smartgwt.client.widgets.layout.VLayout;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.criteria.MeasurementScheduleCriteria;
import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementSchedule;
import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
-import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.GroupCategory;
-import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.coregui.client.LinkManager;
import org.rhq.coregui.client.components.measurement.CustomConfigMeasurementRangeEditor;
@@ -73,9 +74,10 @@ import org.rhq.coregui.client.inventory.common.detail.summary.AbstractActivityVi
import org.rhq.coregui.client.inventory.common.graph.CustomDateRangeState;
import org.rhq.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView;
import org.rhq.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3MultiLineGraph;
-import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.coregui.client.util.BrowserUtility;
import org.rhq.coregui.client.util.Log;
+import org.rhq.coregui.client.util.async.Command;
+import org.rhq.coregui.client.util.async.CountDownLatch;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
/**
@@ -101,6 +103,9 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements CustomSettin
//instance ui widgets
protected Timer refreshTimer;
+
+ private volatile List<MeasurementSchedule> enabledSchedules = null;
+ private volatile boolean renderChart = false;
// final version needed to pass to anon classes
// so we can call refresh in anon callback handler
@@ -221,10 +226,80 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements CustomSettin
*/
protected void getRecentMetrics() {
+ renderChart = true;
+
//display container
final VLayout column = new VLayout();
column.setHeight(10);//pack
+ final CountDownLatch latch = CountDownLatch.create(2, new Command() {
+ @Override
+ public void execute() {
+ if (enabledSchedules.isEmpty() || !renderChart) {
+ DynamicForm row = getEmptyDataForm();
+ column.addMember(row);
+ return;
+ }
+ //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
+ final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
+ for (MeasurementSchedule schedule : enabledSchedules) {
+ measurementDefMap.put(schedule.getDefinition().getDisplayName(), schedule.getDefinition());
+ }
+ Set<String> displayNamesSet = measurementDefMap.keySet();
+ //bundle definition ids for async call.
+ int[] definitionArrayIds = new int[displayNamesSet.size()];
+ final String[] displayOrder = new String[displayNamesSet.size()];
+ displayNamesSet.toArray(displayOrder);
+ //sort the charting data ex. Free Memory, Free Swap Space,..System Load
+ Arrays.sort(displayOrder);
+
+ //organize definitionArrayIds for ordered request on server.
+ int index = 0;
+ for (String definitionToDisplay : displayOrder) {
+ definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay)
+ .getId();
+ }
+
+ fetchEnabledMetrics(enabledSchedules, definitionArrayIds, displayOrder, measurementDefMap, column);
+ }
+ });
+
+ //fetch only enabled schedules
+ fetchEnabledSchedules(latch);
+
+ //fetch the resource type
+ fetchResourceType(latch, column);
+
+ //cleanup
+ for (Canvas child : recentMeasurementsContent.getChildren()) {
+ child.destroy();
+ }
+ recentMeasurementsContent.addChild(column);
+ recentMeasurementsContent.markForRedraw();
+ }
+
+ private void fetchEnabledSchedules(final CountDownLatch latch) {
+ MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
+ criteria.addFilterEnabled(true);
+ criteria.fetchDefinition(true);
+ criteria.setPageControl(PageControl.getUnlimitedInstance());
+ addFilterKey(criteria);
+ GWTServiceLookup.getMeasurementDataService().findMeasurementSchedulesByCriteria(criteria, new AsyncCallback<PageList<MeasurementSchedule>>() {
+
+ @Override
+ public void onSuccess(PageList<MeasurementSchedule> result) {
+ enabledSchedules = result;
+ latch.countDown();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ latch.countDown();
+ }
+ });
+ }
+
+ protected void fetchResourceType(final CountDownLatch latch, final VLayout layout) {
//locate resourceGroupRef
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
criteria.addFilterId(this.groupId);
@@ -251,211 +326,18 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements CustomSettin
Log.debug("Error retrieving resource group composite for group [" + groupId + "]:"
+ caught.getMessage());
setRefreshing(false);
+ latch.countDown();
}
@Override
public void onSuccess(PageList<ResourceGroupComposite> results) {
- if (!results.isEmpty()) {
- final ResourceGroupComposite groupComposite = results.get(0);
- final ResourceGroup group = groupComposite.getResourceGroup();
- if (group.getGroupCategory() == GroupCategory.COMPATIBLE) {
- // Load the fully fetched ResourceType.
- ResourceType groupType = group.getResourceType();
- ResourceTypeRepository.Cache.getInstance().getResourceTypes(
- groupType.getId(),
- EnumSet.of(ResourceTypeRepository.MetadataType.content,
- ResourceTypeRepository.MetadataType.operations,
- ResourceTypeRepository.MetadataType.measurements,
- ResourceTypeRepository.MetadataType.events,
- ResourceTypeRepository.MetadataType.resourceConfigurationDefinition),
- new ResourceTypeRepository.TypeLoadedCallback() {
- public void onTypesLoaded(ResourceType type) {
- group.setResourceType(type);
- //metric definitions
- Set<MeasurementDefinition> definitions = type.getMetricDefinitions();
-
- //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
- }
- //bundle definition ids for asynch call.
- int[] definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
- //sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
-
- //organize definitionArrayIds for ordered request on server.
- int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay)
- .getId();
- }
-
- GWTServiceLookup.getMeasurementDataService().findDataForCompatibleGroup(
- groupId, definitionArrayIds,
- CustomDateRangeState.getInstance().getStartTime(),
- CustomDateRangeState.getInstance().getEndTime(), 60,
- new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent metrics charting data for group ["
- + groupId + "]:" + caught.getMessage());
- setRefreshing(false);
- }
-
- @Override
- public void onSuccess(
- List<List<MeasurementDataNumericHighLowComposite>> results) {
- if (!results.isEmpty()) {
- boolean someChartedData = false;
- //iterate over the retrieved charting data
- for (int index = 0; index < displayOrder.length; index++) {
- //retrieve the correct measurement definition
- final MeasurementDefinition md = measurementDefMap
- .get(displayOrder[index]);
-
- //load the data results for the given metric definition
- List<MeasurementDataNumericHighLowComposite> data = results
- .get(index);
-
- //locate last and minimum values.
- double lastValue = -1;
- double minValue = Double.MAX_VALUE;//
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (!String.valueOf(d.getValue()).contains("NaN"))) {
- if (d.getValue() < minValue) {
- minValue = d.getValue();
- }
- lastValue = d.getValue();
- }
- }
-
- //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
- String commaDelimitedList = "";
-
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (!String.valueOf(d.getValue()).contains("NaN"))) {
- commaDelimitedList += d.getValue() + ",";
- }
- }
- DynamicForm row = new DynamicForm();
- row.setNumCols(3);
- row.setColWidths(65, "*", 100);
- row.setWidth100();
- row.setAutoHeight();
- row.setOverflow(Overflow.VISIBLE);
- HTMLFlow graph = new HTMLFlow();
- // String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0'>"
- // + commaDelimitedList + "</span>";
- String contents = "<span id='sparkline_" + index
- + "' class='dynamicsparkline' width='0' " + "values='"
- + commaDelimitedList + "'>...</span>";
- graph.setContents(contents);
- graph.setContentsType(ContentsType.PAGE);
- //disable scrollbars on span
- graph.setScrollbarSize(0);
-
- CanvasItem graphContainer = new CanvasItem();
- graphContainer.setShowTitle(false);
- graphContainer.setHeight(16);
- graphContainer.setWidth(60);
- graphContainer.setCanvas(graph);
-
- final String title = md.getDisplayName();
- LinkItem link = AbstractActivityView.newLinkItem(title,
- null);
- link.setTooltip(title);
- link.setTitleVAlign(VerticalAlignment.TOP);
- link.setAlign(Alignment.LEFT);
- link.setClipValue(true);
- link.setWrap(true);
- link.setHeight(26);
- if (!BrowserUtility.isBrowserPreIE9()) {
-
- link.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- ChartViewWindow window = new ChartViewWindow(
- title, "", refreshablePortlet);
- CompositeGroupD3GraphListView graph = new CompositeGroupD3MultiLineGraph(
- groupId, md.getId(), isAutoGroup);
- window.addItem(graph);
- graph.populateData();
- window.show();
- }
- });
- } else {
- link.disable();
- }
-
- //Value
- String convertedValue = AbstractActivityView
- .convertLastValueForDisplay(lastValue, md);
- StaticTextItem value = AbstractActivityView
- .newTextItem(convertedValue);
- value.setVAlign(VerticalAlignment.TOP);
- value.setAlign(Alignment.RIGHT);
- value.setWidth("100%");
-
- row.setItems(graphContainer, link, value);
- row.setWidth100();
- //if graph content returned
- if ((!md.getName().trim().contains("Trait."))
- && (lastValue != -1)) {
- column.addMember(row);
- someChartedData = true;
- }
- }
- if (!someChartedData) {// when there are results but no chartable entries.
- DynamicForm row = AbstractActivityView
- .createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
- column.addMember(row);
- } else {
- //insert see more link
- DynamicForm row = new DynamicForm();
- String link = LinkManager
- .getGroupMonitoringGraphsLink(context);
- AbstractActivityView.addSeeMoreLink(row, link, column);
- }
- //call out to 3rd party javascript lib
- new Timer() {
- @Override
- public void run() {
- BrowserUtility.graphSparkLines();
- }
- }.schedule(200);
-
- } else {
- DynamicForm row = AbstractActivityView.createEmptyDisplayRow(
- AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
- column.addMember(row);
- }
- setRefreshing(false);
- }
- }
- );
- }
- });
- }
- } else {
- DynamicForm row = AbstractActivityView
- .createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
- column.addMember(row);
- setRefreshing(false);
+ if (results.isEmpty()
+ || results.get(0).getResourceGroup().getGroupCategory() != GroupCategory.COMPATIBLE) {
+ renderChart = false;
}
+ latch.countDown();
}
});
-
- //cleanup
- for (Canvas child : recentMeasurementsContent.getChildren()) {
- child.destroy();
- }
- recentMeasurementsContent.addChild(column);
- recentMeasurementsContent.markForRedraw();
}
@Override
@@ -497,10 +379,10 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements CustomSettin
protected void setRefreshing(boolean currentlyRefreshing) {
this.currentlyLoading = currentlyRefreshing;
}
- public static class ChartViewWindow extends Window {
+ public static class ChartViewWindow extends Window {
- public ChartViewWindow(String title, String windowTitle,final GroupMetricsPortlet portlet) {
+ public ChartViewWindow(String title, String windowTitle, final GroupMetricsPortlet portlet) {
super();
if ((windowTitle != null) && (!windowTitle.trim().isEmpty())) {
setTitle(windowTitle + ": " + title);
@@ -533,4 +415,156 @@ public class GroupMetricsPortlet extends EnhancedVLayout implements CustomSettin
}
}
+
+ protected void fetchEnabledMetrics(List<MeasurementSchedule> schedules, int[] definitionArrayIds,
+ final String[] displayOrder, final Map<String, MeasurementDefinition> measurementDefMap, final VLayout layout) {
+ GWTServiceLookup.getMeasurementDataService().findDataForCompatibleGroup(groupId, definitionArrayIds,
+ CustomDateRangeState.getInstance().getStartTime(), CustomDateRangeState.getInstance().getEndTime(), 60,
+ new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent metrics charting data for group [" + groupId + "]:"
+ + caught.getMessage());
+ setRefreshing(false);
+ }
+
+ @Override
+ public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
+ renderData(results, displayOrder, measurementDefMap, layout);
+ }
+ });
+ }
+
+
+ protected void renderData(List<List<MeasurementDataNumericHighLowComposite>> results, String[] displayOrder, Map<String, MeasurementDefinition> measurementDefMap, VLayout layout) {
+ if (!results.isEmpty() && !measurementDefMap.isEmpty()) {
+ boolean someChartedData = false;
+ //iterate over the retrieved charting data
+ for (int index = 0; index < displayOrder.length; index++) {
+ //retrieve the correct measurement definition
+ final MeasurementDefinition md = measurementDefMap
+ .get(displayOrder[index]);
+
+ //load the data results for the given metric definition
+ List<MeasurementDataNumericHighLowComposite> data = results
+ .get(index);
+
+ //locate last and minimum values.
+ double lastValue = -1;
+ double minValue = Double.MAX_VALUE;
+ //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
+ String commaDelimitedList = "";
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue()))
+ && (!String.valueOf(d.getValue()).contains("NaN"))) {
+ commaDelimitedList += d.getValue() + ",";
+ if (d.getValue() < minValue) {
+ minValue = d.getValue();
+ }
+ lastValue = d.getValue();
+ }
+ }
+ DynamicForm row = new DynamicForm();
+ row.setNumCols(3);
+ row.setColWidths(65, "*", 100);
+ row.setWidth100();
+ row.setAutoHeight();
+ row.setOverflow(Overflow.VISIBLE);
+ HTMLFlow graph = new HTMLFlow();
+ String contents = "<span id='sparkline_" + index
+ + "' class='dynamicsparkline' width='0' " + "values='"
+ + commaDelimitedList + "'>...</span>";
+ graph.setContents(contents);
+ graph.setContentsType(ContentsType.PAGE);
+ //disable scrollbars on span
+ graph.setScrollbarSize(0);
+
+ CanvasItem graphContainer = new CanvasItem();
+ graphContainer.setShowTitle(false);
+ graphContainer.setHeight(16);
+ graphContainer.setWidth(60);
+ graphContainer.setCanvas(graph);
+
+ final String title = md.getDisplayName();
+ LinkItem link = AbstractActivityView.newLinkItem(title,
+ null);
+ link.setTooltip(title);
+ link.setTitleVAlign(VerticalAlignment.TOP);
+ link.setAlign(Alignment.LEFT);
+ link.setClipValue(true);
+ link.setWrap(true);
+ link.setHeight(26);
+ if (!BrowserUtility.isBrowserPreIE9()) {
+
+ link.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ showPopupWithChart(title, md);
+ }
+ });
+ } else {
+ link.disable();
+ }
+
+ //Value
+ String convertedValue = AbstractActivityView
+ .convertLastValueForDisplay(lastValue, md);
+ StaticTextItem value = AbstractActivityView
+ .newTextItem(convertedValue);
+ value.setVAlign(VerticalAlignment.TOP);
+ value.setWidth("100%");
+
+ row.setItems(graphContainer, link, value);
+ row.setWidth100();
+ //if graph content returned
+ if ((!md.getName().trim().contains("Trait."))
+ && (lastValue != -1)) {
+ layout.addMember(row);
+ someChartedData = true;
+ }
+ }
+ if (!someChartedData) {// when there are results but no chartable entries.
+ DynamicForm row = getEmptyDataForm();
+ layout.addMember(row);
+ } else {
+ //insert see more link
+ DynamicForm row = new DynamicForm();
+ String link = getSeeMoreLink();
+ AbstractActivityView.addSeeMoreLink(row, link, layout);
+ }
+ //call out to 3rd party javascript lib
+ new Timer() {
+ @Override
+ public void run() {
+ BrowserUtility.graphSparkLines();
+ }
+ }.schedule(200);
+
+ } else {
+ DynamicForm row = getEmptyDataForm();
+ layout.addMember(row);
+ }
+ setRefreshing(false);
+ }
+
+ protected void showPopupWithChart(final String title, final MeasurementDefinition md) {
+ ChartViewWindow window = new ChartViewWindow(title, "", refreshablePortlet);
+ CompositeGroupD3GraphListView graph = new CompositeGroupD3MultiLineGraph(groupId, md.getId(), isAutoGroup());
+ window.addItem(graph);
+ graph.populateData();
+ window.show();
+ }
+
+ protected DynamicForm getEmptyDataForm() {
+ return AbstractActivityView.createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_GROUP_NONE);
+ }
+
+ protected String getSeeMoreLink() {
+ return LinkManager.getGroupMonitoringGraphsLink(context);
+ }
+
+ protected MeasurementScheduleCriteria addFilterKey(MeasurementScheduleCriteria criteria) {
+ criteria.addFilterResourceGroupId(groupId);
+ return criteria;
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
index df4e659..93d2d7c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
@@ -18,27 +18,12 @@
*/
package org.rhq.coregui.client.dashboard.portlets.resource;
-import java.util.Arrays;
import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
-import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.ContentsType;
-import com.smartgwt.client.types.Overflow;
-import com.smartgwt.client.types.VerticalAlignment;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.fields.CanvasItem;
-import com.smartgwt.client.widgets.form.fields.LinkItem;
-import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
-import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;
import org.rhq.core.domain.common.EntityContext;
@@ -50,7 +35,6 @@ import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowCo
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
-import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.coregui.client.LinkManager;
import org.rhq.coregui.client.dashboard.Portlet;
@@ -61,9 +45,7 @@ import org.rhq.coregui.client.inventory.common.detail.summary.AbstractActivityVi
import org.rhq.coregui.client.inventory.common.graph.CustomDateRangeState;
import org.rhq.coregui.client.inventory.resource.detail.monitoring.D3GraphListView;
import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository;
-import org.rhq.coregui.client.util.BrowserUtility;
import org.rhq.coregui.client.util.Log;
-import org.rhq.coregui.client.util.async.Command;
import org.rhq.coregui.client.util.async.CountDownLatch;
/**
@@ -77,18 +59,14 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
public static final String KEY = "ResourceMetrics";
// A default displayed, persisted name for the portlet
public static final String NAME = MSG.view_portlet_defaultName_resource_metrics();
-
- private int resourceId = -1;
- private ChartViewWindow window;
- private D3GraphListView graphView;
+ private int resourceId = -1;
public ResourceMetricsPortlet(int resourceId) {
super(EntityContext.forResource(-1));
this.resourceId = resourceId;
}
-
- private volatile List<MeasurementSchedule> enabledSchedules = null;
+
private volatile Resource resource = null;
public static final class Factory implements PortletViewFactory {
@@ -104,37 +82,54 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
}
}
- /** Fetches recent metric information and updates the DynamicForm instance with i)sparkline information,
- * ii) link to recent metric graph for more details and iii) last metric value formatted to show significant
- * digits.
- */
@Override
- protected void getRecentMetrics() {
-
- //display container
- final VLayout column = new VLayout();
- column.setHeight(10);//pack
- column.setWidth100();
-
- final CountDownLatch latch = CountDownLatch.create(2, new Command() {
-
- @Override
- public void execute() {
- showEnabledMetrics(enabledSchedules == null ? null : getEnabledDefinitions(enabledSchedules), column, resource);
- }
-
- private Set<MeasurementDefinition> getEnabledDefinitions(List<MeasurementSchedule> enabledSchedules) {
- Set<MeasurementDefinition> enabledDefinitions = new HashSet<MeasurementDefinition>(enabledSchedules.size());
- for (MeasurementSchedule schedule : enabledSchedules) {
- enabledDefinitions.add(schedule.getDefinition());
+ protected void showPopupWithChart(String title, MeasurementDefinition md) {
+ ChartViewWindow window = new ChartViewWindow(title, "", refreshablePortlet);
+ D3GraphListView graphView = D3GraphListView.createSingleGraph(resource, md.getId(), true);
+ window.addItem(graphView);
+ window.show();
+ }
+
+ @Override
+ protected DynamicForm getEmptyDataForm() {
+ return AbstractActivityView.createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_NONE);
+ }
+
+ @Override
+ protected String getSeeMoreLink() {
+ return LinkManager.getResourceMonitoringGraphsLink(resourceId);
+ }
+
+ @Override
+ protected MeasurementScheduleCriteria addFilterKey(MeasurementScheduleCriteria criteria) {
+ criteria.addFilterResourceId(resourceId);
+ return criteria;
+ }
+
+ @Override
+ protected void fetchEnabledMetrics(List<MeasurementSchedule> schedules, int[] definitionArrayIds,
+ final String[] displayOrder, final Map<String, MeasurementDefinition> measurementDefMap, final VLayout layout) {
+ GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId, definitionArrayIds,
+ CustomDateRangeState.getInstance().getStartTime(), CustomDateRangeState.getInstance().getEndTime(), 60,
+ new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent metrics charting data for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ setRefreshing(false);
+ }
+
+ @Override
+ public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
+ renderData(results, displayOrder, measurementDefMap, layout);
}
- return enabledDefinitions;
}
- });
-
- //fetch only enabled schedules
- fetchEnabledSchedules(latch);
+ );
+ }
+
+ @Override
+ protected void fetchResourceType(final CountDownLatch latch, final VLayout layout) {
//locate resource reference
ResourceCriteria criteria = new ResourceCriteria();
criteria.addFilterId(this.resourceId);
@@ -170,192 +165,5 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
}
}
});
-
- //cleanup
- for (Canvas child : recentMeasurementsContent.getChildren()) {
- child.destroy();
- }
- recentMeasurementsContent.addChild(column);
- recentMeasurementsContent.markForRedraw();
- }
-
- private void fetchEnabledSchedules(final CountDownLatch latch) {
- MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
- criteria.addFilterResourceId(resourceId);
- criteria.addFilterEnabled(true);
- criteria.fetchDefinition(true);
- criteria.setPageControl(PageControl.getUnlimitedInstance());
- GWTServiceLookup.getMeasurementDataService().findMeasurementSchedulesByCriteria(criteria, new AsyncCallback<PageList<MeasurementSchedule>>() {
-
- @Override
- public void onSuccess(PageList<MeasurementSchedule> result) {
- enabledSchedules = result;
- latch.countDown();
- }
-
- @Override
- public void onFailure(Throwable caught) {
- latch.countDown();
- }
- });
- }
-
-
- private void showEnabledMetrics(final Set<MeasurementDefinition> definitions, final VLayout layout, final Resource resource) {
- if (resource == null || definitions == null) {
- Log.warn("Unable to render recent metrics properly.");
- return;
- }
-
- //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
- }
- //bundle definition ids for async call.
- int[] definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
- //sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
-
- //organize definitionArrayIds for ordered request on server.
- int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
- }
-
- GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId, definitionArrayIds,
- CustomDateRangeState.getInstance().getStartTime(), CustomDateRangeState.getInstance().getEndTime(), 60,
- new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent metrics charting data for resource [" + resourceId + "]:"
- + caught.getMessage());
- setRefreshing(false);
- }
-
- @Override
- public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
- if (!results.isEmpty()) {
- boolean someChartedData = false;
- //iterate over the retrieved charting data
- for (int index = 0; index < displayOrder.length; index++) {
- //retrieve the correct measurement definition
- final MeasurementDefinition md = measurementDefMap.get(displayOrder[index]);
-
- //load the data results for the given metric definition
- List<MeasurementDataNumericHighLowComposite> data = results.get(index);
-
- //locate last and minimum values.
- double lastValue = -1;
- double minValue = Double.MAX_VALUE;//
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue())) && (!String.valueOf(d.getValue()).contains("NaN"))) {
- if (d.getValue() < minValue) {
- minValue = d.getValue();
- }
- lastValue = d.getValue();
- }
- }
-
- //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
- String commaDelimitedList = "";
-
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue())) && (!String.valueOf(d.getValue()).contains("NaN"))) {
- commaDelimitedList += d.getValue() + ",";
- }
- }
- DynamicForm row = new DynamicForm();
- row.setNumCols(3);
- row.setColWidths(65, "*", 100);
- row.setWidth100();
- row.setAutoHeight();
- row.setOverflow(Overflow.VISIBLE);
- HTMLFlow sparklineGraph = new HTMLFlow();
- String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0' "
- + "values='" + commaDelimitedList + "'>...</span>";
- sparklineGraph.setContents(contents);
- sparklineGraph.setContentsType(ContentsType.PAGE);
- //disable scrollbars on span
- sparklineGraph.setScrollbarSize(0);
-
- CanvasItem sparklineContainer = new CanvasItem();
- sparklineContainer.setShowTitle(false);
- sparklineContainer.setHeight(16);
- sparklineContainer.setWidth(60);
- sparklineContainer.setCanvas(sparklineGraph);
-
- //Link/title element
- final String title = md.getDisplayName();
- LinkItem link = AbstractActivityView.newLinkItem(title, null);
- link.setTooltip(title);
- link.setTitleVAlign(VerticalAlignment.TOP);
- link.setAlign(Alignment.LEFT);
- link.setClipValue(true);
- link.setWrap(true);
- link.setHeight(26);
- link.setWidth("100%");
- if (!BrowserUtility.isBrowserPreIE9()) {
- link.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- window = new ChartViewWindow(title, "", refreshablePortlet);
-
- graphView = D3GraphListView.createSingleGraph(resource, md.getId(), true);
-
- window.addItem(graphView);
- window.show();
- }
- });
- } else {
- link.disable();
- }
-
- //Value
- String convertedValue;
- convertedValue = AbstractActivityView.convertLastValueForDisplay(lastValue, md);
- StaticTextItem value = AbstractActivityView.newTextItem(convertedValue);
- value.setVAlign(VerticalAlignment.TOP);
- value.setAlign(Alignment.RIGHT);
-
- row.setItems(sparklineContainer, link, value);
- row.setWidth100();
-
- //if graph content returned
- if ((!md.getName().trim().contains("Trait.")) && (lastValue != -1)) {
- layout.addMember(row);
- someChartedData = true;
- }
- }
- if (!someChartedData) {// when there are results but no chartable entries.
- DynamicForm row = AbstractActivityView.createEmptyDisplayRow(
-
- AbstractActivityView.RECENT_MEASUREMENTS_NONE);
- layout.addMember(row);
- } else {
- //insert see more link
- DynamicForm row = new DynamicForm();
- String link = LinkManager.getResourceMonitoringGraphsLink(resourceId);
- AbstractActivityView.addSeeMoreLink(row, link, layout);
- }
- //call out to 3rd party javascript lib
- new Timer() {
- @Override
- public void run() {
- BrowserUtility.graphSparkLines();
- }
- }.schedule(200);
- } else {
- DynamicForm row = AbstractActivityView
- .createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_NONE);
- layout.addMember(row);
- }
- setRefreshing(false);
- }
- }
-
- );
}
}
commit 03f930f8d89535f76e68778dd538d3a5d4101886
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Jan 10 13:56:27 2014 -0500
[BZ 1038067] - Resource Summary/Activity shows summary of disabled metrics
adding a check that finds out whether the resource has those metrics
scheduled. This is done in parallel using the countdown latch pattern.
Cherry-Pick master 985cf07bc5835ab816d661008f1f752a355f3d4e
Signed-off-by: Jay Shaughnessy <jshaughn(a)redhat.com>
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
index ddd70a3..df4e659 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java
@@ -21,6 +21,7 @@ package org.rhq.coregui.client.dashboard.portlets.resource;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -41,13 +42,15 @@ import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;
import org.rhq.core.domain.common.EntityContext;
+import org.rhq.core.domain.criteria.MeasurementScheduleCriteria;
import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementSchedule;
import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.coregui.client.LinkManager;
import org.rhq.coregui.client.dashboard.Portlet;
@@ -60,6 +63,8 @@ import org.rhq.coregui.client.inventory.resource.detail.monitoring.D3GraphListVi
import org.rhq.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.coregui.client.util.BrowserUtility;
import org.rhq.coregui.client.util.Log;
+import org.rhq.coregui.client.util.async.Command;
+import org.rhq.coregui.client.util.async.CountDownLatch;
/**
* This portlet allows the end user to customize the metric display
@@ -72,7 +77,7 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
public static final String KEY = "ResourceMetrics";
// A default displayed, persisted name for the portlet
public static final String NAME = MSG.view_portlet_defaultName_resource_metrics();
-
+
private int resourceId = -1;
private ChartViewWindow window;
@@ -82,6 +87,9 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
super(EntityContext.forResource(-1));
this.resourceId = resourceId;
}
+
+ private volatile List<MeasurementSchedule> enabledSchedules = null;
+ private volatile Resource resource = null;
public static final class Factory implements PortletViewFactory {
public static final PortletViewFactory INSTANCE = new Factory();
@@ -101,12 +109,31 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
* digits.
*/
@Override
- protected void getRecentMetrics() {
- final DashboardPortlet storedPortlet = this.portletWindow.getStoredPortlet();
+ protected void getRecentMetrics() {
+
//display container
final VLayout column = new VLayout();
column.setHeight(10);//pack
column.setWidth100();
+
+ final CountDownLatch latch = CountDownLatch.create(2, new Command() {
+
+ @Override
+ public void execute() {
+ showEnabledMetrics(enabledSchedules == null ? null : getEnabledDefinitions(enabledSchedules), column, resource);
+ }
+
+ private Set<MeasurementDefinition> getEnabledDefinitions(List<MeasurementSchedule> enabledSchedules) {
+ Set<MeasurementDefinition> enabledDefinitions = new HashSet<MeasurementDefinition>(enabledSchedules.size());
+ for (MeasurementSchedule schedule : enabledSchedules) {
+ enabledDefinitions.add(schedule.getDefinition());
+ }
+ return enabledDefinitions;
+ }
+ });
+
+ //fetch only enabled schedules
+ fetchEnabledSchedules(latch);
//locate resource reference
ResourceCriteria criteria = new ResourceCriteria();
@@ -120,13 +147,14 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
Log.debug("Error retrieving resource resource composite for resource [" + resourceId + "]:"
+ caught.getMessage());
setRefreshing(false);
+ latch.countDown();
}
@Override
public void onSuccess(PageList<ResourceComposite> results) {
if (!results.isEmpty()) {
final ResourceComposite resourceComposite = results.get(0);
- final Resource resource = resourceComposite.getResource();
+ resource = resourceComposite.getResource();
// Load the fully fetched ResourceType.
ResourceType resourceType = resource.getResourceType();
ResourceTypeRepository.Cache.getInstance().getResourceTypes(resourceType.getId(),
@@ -134,176 +162,11 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
new ResourceTypeRepository.TypeLoadedCallback() {
public void onTypesLoaded(ResourceType type) {
resource.setResourceType(type);
- //metric definitions
- Set<MeasurementDefinition> definitions = type.getMetricDefinitions();
-
- //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
- }
- //bundle definition ids for asynch call.
- int[] definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
- //sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
-
- //organize definitionArrayIds for ordered request on server.
- int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay)
- .getId();
- }
-
- GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId,
- definitionArrayIds, CustomDateRangeState.getInstance().getStartTime(),
- CustomDateRangeState.getInstance().getEndTime(), 60,
- new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
- @Override
- public void onFailure(Throwable caught) {
- Log.debug("Error retrieving recent metrics charting data for resource ["
- + resourceId + "]:" + caught.getMessage());
- setRefreshing(false);
- }
-
- @Override
- public void onSuccess(
- List<List<MeasurementDataNumericHighLowComposite>> results) {
- if (!results.isEmpty()) {
- boolean someChartedData = false;
- //iterate over the retrieved charting data
- for (int index = 0; index < displayOrder.length; index++) {
- //retrieve the correct measurement definition
- final MeasurementDefinition md = measurementDefMap
- .get(displayOrder[index]);
-
- //load the data results for the given metric definition
- List<MeasurementDataNumericHighLowComposite> data = results
- .get(index);
-
- //locate last and minimum values.
- double lastValue = -1;
- double minValue = Double.MAX_VALUE;//
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (!String.valueOf(d.getValue()).contains("NaN"))) {
- if (d.getValue() < minValue) {
- minValue = d.getValue();
- }
- lastValue = d.getValue();
- }
- }
-
- //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
- String commaDelimitedList = "";
-
- for (MeasurementDataNumericHighLowComposite d : data) {
- if ((!Double.isNaN(d.getValue()))
- && (!String.valueOf(d.getValue()).contains("NaN"))) {
- commaDelimitedList += d.getValue() + ",";
- }
- }
- DynamicForm row = new DynamicForm();
- row.setNumCols(3);
- row.setColWidths(65, "*", 100);
- row.setWidth100();
- row.setAutoHeight();
- row.setOverflow(Overflow.VISIBLE);
- HTMLFlow sparklineGraph = new HTMLFlow();
- String contents = "<span id='sparkline_" + index
- + "' class='dynamicsparkline' width='0' " + "values='"
- + commaDelimitedList + "'>...</span>";
- sparklineGraph.setContents(contents);
- sparklineGraph.setContentsType(ContentsType.PAGE);
- //disable scrollbars on span
- sparklineGraph.setScrollbarSize(0);
-
- CanvasItem sparklineContainer = new CanvasItem();
- sparklineContainer.setShowTitle(false);
- sparklineContainer.setHeight(16);
- sparklineContainer.setWidth(60);
- sparklineContainer.setCanvas(sparklineGraph);
-
- //Link/title element
- final String title = md.getDisplayName();
- LinkItem link = AbstractActivityView.newLinkItem(title, null);
- link.setTooltip(title);
- link.setTitleVAlign(VerticalAlignment.TOP);
- link.setAlign(Alignment.LEFT);
- link.setClipValue(true);
- link.setWrap(true);
- link.setHeight(26);
- link.setWidth("100%");
- if (!BrowserUtility.isBrowserPreIE9()) {
- link.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- window = new ChartViewWindow(title,"", refreshablePortlet);
-
- graphView = D3GraphListView.createSingleGraph(
- resourceComposite.getResource(), md.getId(),
- true);
-
- window.addItem(graphView);
- window.show();
- }
- });
- } else {
- link.disable();
- }
-
- //Value
- String convertedValue;
- convertedValue = AbstractActivityView
- .convertLastValueForDisplay(lastValue, md);
- StaticTextItem value = AbstractActivityView
- .newTextItem(convertedValue);
- value.setVAlign(VerticalAlignment.TOP);
- value.setAlign(Alignment.RIGHT);
-
- row.setItems(sparklineContainer, link, value);
- row.setWidth100();
-
- //if graph content returned
- if ((!md.getName().trim().contains("Trait."))
- && (lastValue != -1)) {
- column.addMember(row);
- someChartedData = true;
- }
- }
- if (!someChartedData) {// when there are results but no chartable entries.
- DynamicForm row = AbstractActivityView.createEmptyDisplayRow(
-
- AbstractActivityView.RECENT_MEASUREMENTS_NONE);
- column.addMember(row);
- } else {
- //insert see more link
- DynamicForm row = new DynamicForm();
- String link = LinkManager
- .getResourceMonitoringGraphsLink(resourceId);
- AbstractActivityView.addSeeMoreLink(row, link, column);
- }
- //call out to 3rd party javascript lib
- new Timer() {
- @Override
- public void run() {
- BrowserUtility.graphSparkLines();
- }
- }.schedule(200);
- } else {
- DynamicForm row = AbstractActivityView
- .createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_NONE);
- column.addMember(row);
- }
- setRefreshing(false);
- }
- }
-
- );
-
+ latch.countDown();
}
});
+ } else {
+ latch.countDown();
}
}
});
@@ -315,4 +178,184 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet {
recentMeasurementsContent.addChild(column);
recentMeasurementsContent.markForRedraw();
}
+
+ private void fetchEnabledSchedules(final CountDownLatch latch) {
+ MeasurementScheduleCriteria criteria = new MeasurementScheduleCriteria();
+ criteria.addFilterResourceId(resourceId);
+ criteria.addFilterEnabled(true);
+ criteria.fetchDefinition(true);
+ criteria.setPageControl(PageControl.getUnlimitedInstance());
+ GWTServiceLookup.getMeasurementDataService().findMeasurementSchedulesByCriteria(criteria, new AsyncCallback<PageList<MeasurementSchedule>>() {
+
+ @Override
+ public void onSuccess(PageList<MeasurementSchedule> result) {
+ enabledSchedules = result;
+ latch.countDown();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ latch.countDown();
+ }
+ });
+ }
+
+
+ private void showEnabledMetrics(final Set<MeasurementDefinition> definitions, final VLayout layout, final Resource resource) {
+ if (resource == null || definitions == null) {
+ Log.warn("Unable to render recent metrics properly.");
+ return;
+ }
+
+ //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
+ final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
+ for (MeasurementDefinition definition : definitions) {
+ measurementDefMap.put(definition.getDisplayName(), definition);
+ }
+ //bundle definition ids for async call.
+ int[] definitionArrayIds = new int[definitions.size()];
+ final String[] displayOrder = new String[definitions.size()];
+ measurementDefMap.keySet().toArray(displayOrder);
+ //sort the charting data ex. Free Memory, Free Swap Space,..System Load
+ Arrays.sort(displayOrder);
+
+ //organize definitionArrayIds for ordered request on server.
+ int index = 0;
+ for (String definitionToDisplay : displayOrder) {
+ definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
+ }
+
+ GWTServiceLookup.getMeasurementDataService().findDataForResource(resourceId, definitionArrayIds,
+ CustomDateRangeState.getInstance().getStartTime(), CustomDateRangeState.getInstance().getEndTime(), 60,
+ new AsyncCallback<List<List<MeasurementDataNumericHighLowComposite>>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ Log.debug("Error retrieving recent metrics charting data for resource [" + resourceId + "]:"
+ + caught.getMessage());
+ setRefreshing(false);
+ }
+
+ @Override
+ public void onSuccess(List<List<MeasurementDataNumericHighLowComposite>> results) {
+ if (!results.isEmpty()) {
+ boolean someChartedData = false;
+ //iterate over the retrieved charting data
+ for (int index = 0; index < displayOrder.length; index++) {
+ //retrieve the correct measurement definition
+ final MeasurementDefinition md = measurementDefMap.get(displayOrder[index]);
+
+ //load the data results for the given metric definition
+ List<MeasurementDataNumericHighLowComposite> data = results.get(index);
+
+ //locate last and minimum values.
+ double lastValue = -1;
+ double minValue = Double.MAX_VALUE;//
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue())) && (!String.valueOf(d.getValue()).contains("NaN"))) {
+ if (d.getValue() < minValue) {
+ minValue = d.getValue();
+ }
+ lastValue = d.getValue();
+ }
+ }
+
+ //collapse the data into comma delimited list for consumption by third party javascript library(jquery.sparkline)
+ String commaDelimitedList = "";
+
+ for (MeasurementDataNumericHighLowComposite d : data) {
+ if ((!Double.isNaN(d.getValue())) && (!String.valueOf(d.getValue()).contains("NaN"))) {
+ commaDelimitedList += d.getValue() + ",";
+ }
+ }
+ DynamicForm row = new DynamicForm();
+ row.setNumCols(3);
+ row.setColWidths(65, "*", 100);
+ row.setWidth100();
+ row.setAutoHeight();
+ row.setOverflow(Overflow.VISIBLE);
+ HTMLFlow sparklineGraph = new HTMLFlow();
+ String contents = "<span id='sparkline_" + index + "' class='dynamicsparkline' width='0' "
+ + "values='" + commaDelimitedList + "'>...</span>";
+ sparklineGraph.setContents(contents);
+ sparklineGraph.setContentsType(ContentsType.PAGE);
+ //disable scrollbars on span
+ sparklineGraph.setScrollbarSize(0);
+
+ CanvasItem sparklineContainer = new CanvasItem();
+ sparklineContainer.setShowTitle(false);
+ sparklineContainer.setHeight(16);
+ sparklineContainer.setWidth(60);
+ sparklineContainer.setCanvas(sparklineGraph);
+
+ //Link/title element
+ final String title = md.getDisplayName();
+ LinkItem link = AbstractActivityView.newLinkItem(title, null);
+ link.setTooltip(title);
+ link.setTitleVAlign(VerticalAlignment.TOP);
+ link.setAlign(Alignment.LEFT);
+ link.setClipValue(true);
+ link.setWrap(true);
+ link.setHeight(26);
+ link.setWidth("100%");
+ if (!BrowserUtility.isBrowserPreIE9()) {
+ link.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ window = new ChartViewWindow(title, "", refreshablePortlet);
+
+ graphView = D3GraphListView.createSingleGraph(resource, md.getId(), true);
+
+ window.addItem(graphView);
+ window.show();
+ }
+ });
+ } else {
+ link.disable();
+ }
+
+ //Value
+ String convertedValue;
+ convertedValue = AbstractActivityView.convertLastValueForDisplay(lastValue, md);
+ StaticTextItem value = AbstractActivityView.newTextItem(convertedValue);
+ value.setVAlign(VerticalAlignment.TOP);
+ value.setAlign(Alignment.RIGHT);
+
+ row.setItems(sparklineContainer, link, value);
+ row.setWidth100();
+
+ //if graph content returned
+ if ((!md.getName().trim().contains("Trait.")) && (lastValue != -1)) {
+ layout.addMember(row);
+ someChartedData = true;
+ }
+ }
+ if (!someChartedData) {// when there are results but no chartable entries.
+ DynamicForm row = AbstractActivityView.createEmptyDisplayRow(
+
+ AbstractActivityView.RECENT_MEASUREMENTS_NONE);
+ layout.addMember(row);
+ } else {
+ //insert see more link
+ DynamicForm row = new DynamicForm();
+ String link = LinkManager.getResourceMonitoringGraphsLink(resourceId);
+ AbstractActivityView.addSeeMoreLink(row, link, layout);
+ }
+ //call out to 3rd party javascript lib
+ new Timer() {
+ @Override
+ public void run() {
+ BrowserUtility.graphSparkLines();
+ }
+ }.schedule(200);
+ } else {
+ DynamicForm row = AbstractActivityView
+ .createEmptyDisplayRow(AbstractActivityView.RECENT_MEASUREMENTS_NONE);
+ layout.addMember(row);
+ }
+ setRefreshing(false);
+ }
+ }
+
+ );
+ }
}
commit 4e96f844a18814912a1728ad737394681d7e2de2
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Jan 10 13:53:52 2014 -0500
[BZ 846819] - Broken dashboard portlets or portlets with invalid configuration SHOULD NOT prevent the entire dashboard from working
surrounding the risky interaction with particular portlets into try-catch
block to make the logic little bit more robust. Now, exception thrown
from a portlet doesn't affect other portlets, so the portlets are more
autonomous so to speak.
Cherry-Pick Master 1e2f74e4ad545ad92ad39fdca6f691fd85608d2c
Signed-off-by: Jay Shaughnessy <jshaughn(a)redhat.com>
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/DashboardView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/DashboardView.java
index 679f26b..463b856 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/DashboardView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/dashboard/DashboardView.java
@@ -338,7 +338,11 @@ public class DashboardView extends EnhancedVLayout {
public void onItemClick(ItemClickEvent itemClickEvent) {
String key = itemClickEvent.getItem().getAttribute("portletKey");
String name = itemClickEvent.getItem().getTitle();
- addPortlet(key, name);
+ try {
+ addPortlet(key, name);
+ } catch (Exception ex) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error3(), ex);
+ }
}
});
@@ -543,14 +547,18 @@ public class DashboardView extends EnhancedVLayout {
private void loadPortletWindows() {
for (int i = 0; i < storedDashboard.getColumns(); i++) {
for (DashboardPortlet storedPortlet : storedDashboard.getPortlets(i)) {
-
- PortletWindow portletWindow = new PortletWindow(this, storedPortlet, context);
- portletWindow.setTitle(storedPortlet.getName());
- portletWindow.setHeight(storedPortlet.getHeight());
- portletWindow.setVisible(true);
-
- portletWindows.add(portletWindow);
- portalLayout.addPortletWindow(portletWindow, i);
+ try {
+ PortletWindow portletWindow = new PortletWindow(this, storedPortlet, context);
+ portletWindow.setTitle(storedPortlet.getName());
+ portletWindow.setHeight(storedPortlet.getHeight());
+ portletWindow.setVisible(true);
+
+ portletWindows.add(portletWindow);
+ portalLayout.addPortletWindow(portletWindow, i);
+ } catch (Exception ex) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error2(), ex);
+ continue;
+ }
}
}
}
@@ -926,7 +934,11 @@ public class DashboardView extends EnhancedVLayout {
for (PortletWindow pw : portletWindows) {
// I think this should work with markForRedraw but for some reason it does not
- ((Canvas) pw.getView()).redraw();
+ try {
+ ((Canvas) pw.getView()).redraw();
+ } catch (Exception ex) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_dashboardsManager_error4(), ex);
+ }
}
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
index dfdaf65..c9ac5c7 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
@@ -1503,6 +1503,9 @@ view_dashboardManager_saved = Saved dashboard {0} to server
view_dashboardManager_success = Saved dashboard
view_dashboard_favorites_error1 = Failed to load favorite Resources.
view_dashboardsManager_error1 = Failed to add new dashboard
+view_dashboardsManager_error2 = Failed to load dashboard portlet.
+view_dashboardsManager_error3 = Failed to add portlet to dashboard.
+view_dashboardsManager_error4 = Failed to draw dashboard portlet.
view_dashboardsManager_message_title_details = <h1>Welcome to {0}</h1>\n<p>This dashboard can be edited by clicking the (Edit Mode) button above.</p>\n<p>What would you like to do?</p>\n<p> <a href=\"{1}\">Import newly discovered resources.</a></p>\n<p> <a href=\"{2}\">Search for resources.</a></p>\n<p> <a href=\"{3}\">See help and documentation.</a></p>
view_dashboards_confirm1 = Are you sure you want to delete
view_dashboards_portlets_refresh_fail1 = Failed to update auto-refresh interval
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
index 7c80bbb..d971c88 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
@@ -1521,6 +1521,9 @@ view_dashboardManager_saved = Dashboard {0} byl uložen na server
view_dashboardManager_success = Dashboard uložen
view_dashboard_favorites_error1 = Nepodařilo se načíst oblíbené zdroje.
view_dashboardsManager_error1 = Nepodařilo se přidat nový dashboard
+view_dashboardsManager_error2 = Nepodařilo se načíst portlet.
+view_dashboardsManager_error3 = Nepodařilo se přidat portlet na dashboard.
+view_dashboardsManager_error4 = Nepodařilo se vykreslit portlet.
##view_dashboardsManager_message_title_details = <h1>Welcome to {0}</h1>\n<p>This dashboard can be edited by clicking the (Edit Mode) button above.</p>\n<p>What would you like to do?</p>\n<p> <a href=\"{1}\">Import newly discovered resources.</a></p>\n<p> <a href=\"{2}\">Search for resources.</a></p>\n<p> <a href=\"{3}\">See help and documentation.</a></p>
view_dashboards_confirm1 = Jste si jisti, že to chcete smazat
##view_dashboards_portlets_refresh_fail1 = Nepodařilo se změnit interval auto aktualizace pro portlety
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
index 2670220..d6d22bf 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
@@ -1865,6 +1865,9 @@ view_dashboardManager_saved=Das Dashboard {0} wurde auf dem Server gesichert
view_dashboardManager_success=Dashboard gespeichert
view_dashboard_favorites_error1=Konnte die Ressoucen-Lesezeichen nicht laden
view_dashboardsManager_error1=Konnte das neue Dashboard nicht hinzufügen
+##view_dashboardsManager_error2 = Failed to load dashboard portlet.
+##view_dashboardsManager_error3 = Failed to add portlet to dashboard.
+##view_dashboardsManager_error4 = Failed to draw dashboard portlet.
view_dashboardsManager_message_title_details=<h1>Willkommen bei {0}</h1>\n<p>Dieses Dashboard kan durch Betätigen des Bearbeitungsmodus-Knopfes verändert werden.</p>\n<p>Was möchten Sie tun?</p>\n<p> <a href\="{1}">Neu gefundene Ressourcen importieren.</a></p>\n<p> <a href\="{2}">Ressourcen suchen.</a></p>\n<p> <a href\="{3}">Hilfe und Dokumentation ansehen.</a></p>
view_dashboards_confirm1=Sind Sie sicher, dass Sie löschen möchten
view_dashboards_portlets_refresh_fail1=Aktualisierung von Auto-refresh Intervall fehlgeschlagen
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
index aa366a0..c1917f0 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
@@ -1769,6 +1769,9 @@ view_dashboardManager_saved=ダッシュボード {0} をサーバーへ保存
view_dashboardManager_success=ダッシュボードを保存しました
view_dashboard_favorites_error1=好みのリソースをロードするのに失敗しました
view_dashboardsManager_error1=新しいダッシュボードを追加するのに失敗しました
+##view_dashboardsManager_error2 = Failed to load dashboard portlet.
+##view_dashboardsManager_error3 = Failed to add portlet to dashboard.
+##view_dashboardsManager_error4 = Failed to draw dashboard portlet.
view_dashboardsManager_message_title_details=<h1>{0} をご使用いただきありがとうございます。</h1>\n<p>このダッシュボードは、上記の (編集モード) ボタンをクリックすると編集できます。</p>\n<p>以下の操作の 1 つを選択してください。</p>\n<p> <a href\="{1}">新たに見つかったリソースをインポートする</a></p>\n<p> <a href\="{2}">リソースを検索する</a></p>\n<p> <a href\="{3}">ヘルプおよびドキュメントを確認する</a></p>
# #view_dashboardsManager_message_title_details = <h1>Welcome to {0}</h1>\n<p>This dashboard can be edited by clicking the (Edit Mode) button above.</p>\n<p>What would you like to do?</p>\n<p> <a href=\"{1}\">Import newly discovered resources.</a></p>\n<p> <a href=\"{2}\">Search for resources.</a></p>\n<p> <a href=\"{3}\">See help and documentation.</a></p>
view_dashboards_confirm1=削除してもよろしいですか
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
index 96d4562..57e6094 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
@@ -1335,6 +1335,9 @@ view_dashboardManager_saved = 서버에 대시 보드 {0}을 저장했습니다
view_dashboardManager_success = 대시 보드를 저장했습니다
view_dashboard_favorites_error1 = 즐겨찾기 리소스를 로드하는데 실패했습니다.
view_dashboardsManager_error1 = 새로운 대시 보드 추가에 실패했습니다
+##view_dashboardsManager_error2 = Failed to load dashboard portlet.
+##view_dashboardsManager_error3 = Failed to add portlet to dashboard.
+##view_dashboardsManager_error4 = Failed to draw dashboard portlet.
##view_dashboardsManager_message_title_details = <h1>Welcome to {0}</h1>\n<p>This dashboard can be edited by clicking the (Edit Mode) button above.</p>\n<p>What would you like to do?</p>\n<p> <a href=\"{1}\">Import newly discovered resources.</a></p>\n<p> <a href=\"{2}\">Search for resources.</a></p>\n<p> <a href=\"{3}\">See help and documentation.</a></p>
view_dashboards_confirm1 = 삭제하시겠습니까
view_dashboards_portlets_refresh_fail2 = 자동 새로고침 포틀릿에 대한 리로드 비활성화에 실패했습니다
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
index 6ab2d30..ab1223a 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
@@ -1512,6 +1512,9 @@ view_dashboardManager_saved = Dashboard {0} salvo no servidor
view_dashboardManager_success = Dashboard salvo
view_dashboard_favorites_error1 = Falha ao carregar recursos favoritos.
view_dashboardsManager_error1 = Falha ao adicionar novo dashboad
+##view_dashboardsManager_error2 = Failed to load dashboard portlet.
+##view_dashboardsManager_error3 = Failed to add portlet to dashboard.
+##view_dashboardsManager_error4 = Failed to draw dashboard portlet.
view_dashboardsManager_inventory_title = Sum\u00E1rio do Invent\u00E1rio
view_dashboardsManager_mashup_title = Novidades do RHQ
view_dashboardsManager_message_title = Bem vindo ao RHQ
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
index c215f3c..a0ada93 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
@@ -1388,6 +1388,9 @@
#view_dashboardManager_success = Saved dashboard
#view_dashboard_favorites_error1 = Failed to load favorite Resources.
#view_dashboardsManager_error1 = Failed to add new dashboard
+##view_dashboardsManager_error2 = Failed to load dashboard portlet.
+##view_dashboardsManager_error3 = Failed to add portlet to dashboard.
+##view_dashboardsManager_error4 = Failed to draw dashboard portlet.
#view_dashboardsManager_message_title_details = <h1>Welcome to {0}</h1>\n<p>The RHQ project is an abstraction and plug-in based systems management suite that provides extensible and integrated systems management for multiple products and platforms across a set of core features. The project is designed with layered modules that provide a flexible architecture for deployment. It delivers a core user interface that delivers audited and historical management across an entire enterprise. A Server/Agent architecture provides remote management and plugins implement all specific support for managed products.</p>\n <p>This default dashboard can be edited by clicking the (edit mode) button above.</p>
#view_dashboards_confirm1 = Are you sure you want to delete
#view_dashboards_portlets_refresh_fail1 = Failed to update interval for portlets that auto-refresh
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
index 8407bad..78fa0aa 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
@@ -1494,6 +1494,9 @@ view_dashboardManager_saved = \u4fdd\u5b58\u7edf\u8ba1\u8868\u76d8{0}
view_dashboardManager_success = \u6210\u529f\u4fdd\u5b58\u7edf\u8ba1\u8868\u76d8
view_dashboard_favorites_error1 = \u52a0\u8f7d\u5e38\u7528\u8d44\u6e90\u5931\u8d25.
view_dashboardsManager_error1 = \u6dfb\u52a0\u65b0\u7edf\u8ba1\u8868\u76d8\u5931\u8d25
+##view_dashboardsManager_error2 = Failed to load dashboard portlet.
+##view_dashboardsManager_error3 = Failed to add portlet to dashboard.
+##view_dashboardsManager_error4 = Failed to draw dashboard portlet.
##view_dashboardsManager_message_title_details = <h1>Welcome to {0}</h1>\n<p>This dashboard can be edited by clicking the (Edit Mode) button above.</p>\n<p>What would you like to do?</p>\n<p> <a href=\"{1}\">Import newly discovered resources.</a></p>\n<p> <a href=\"{2}\">Search for resources.</a></p>\n<p> <a href=\"{3}\">See help and documentation.</a></p>
view_dashboards_confirm1 = \u60a8\u786e\u5b9a\u8981\u5220\u9664\uff1f
##view_dashboards_portlets_refresh_fail1 = \u4fee\u6539portlets\u81ea\u52a8\u5237\u65b0\u7684\u95f4\u9694\u65f6\u95f4\u5931\u8d25
10 years, 5 months
[rhq] etc/samples etc/test-apps modules/plugins
by Thomas Segismont
etc/samples/mbeans-on-as7-plugin/pom.xml | 98 ++
etc/samples/mbeans-on-as7-plugin/src/main/resources/META-INF/rhq-plugin.xml | 45 +
etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloService.java | 62 +
etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloServiceMBean.java | 10
modules/plugins/jboss-as-7-jmx/pom.xml | 33
modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansComponent.java | 97 ++
modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansDiscoveryComponent.java | 420 ++++++++++
modules/plugins/jboss-as-7/src/test/resources/itest/javaee6-test-app.war |binary
modules/plugins/pom.xml | 1
9 files changed, 766 insertions(+)
New commits:
commit 0af8802b5e73d767f002ca1f1dcf277bdcb57f8b
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Fri Jan 10 13:12:03 2014 +0100
Bug 1051413 - RFE: give plugin authors a tool to monitor MBeans of an application deployed on AS7 or EAP6
Added ApplicationMBeansComponent and ApplicationMBeansComponent. A separate project is needed because of classloading issues (the discovery class loader needs access to both the AS7 and JMX plugin classes).
The application MBeans container resource will be a service resource with a StandaloneAS or Managed AS parent.
Added a sample service MBean to javaee6-test-app.
Added mbeans-on-as7-plugin sample to demonstrate usage of the new facility
diff --git a/etc/samples/mbeans-on-as7-plugin/pom.xml b/etc/samples/mbeans-on-as7-plugin/pom.xml
new file mode 100644
index 0000000..fcfdd3a
--- /dev/null
+++ b/etc/samples/mbeans-on-as7-plugin/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>mbeans-on-as7-plugin</groupId>
+ <artifactId>mbeans-on-as7-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>rhq-agent-plugin</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <rhq.version>4.10.0-SNAPSHOT</rhq.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-jboss-as-7-plugin</artifactId>
+ <version>${rhq.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-jboss-as-7-jmx-util</artifactId>
+ <version>${rhq.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <phase>initialize</phase>
+ <goals>
+ <goal>maven-version</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.rhq.maven.plugins</groupId>
+ <artifactId>rhq-agent-plugin-plugin</artifactId>
+ <version>0.5</version>
+ <extensions>true</extensions>
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Maven-Version>${maven.version}</Maven-Version>
+ <Java-Version>${java.version}</Java-Version>
+ <Java-Vendor>${java.vendor}</Java-Vendor>
+ <Os-Name>${os.name}</Os-Name>
+ <Os-Arch>${os.arch}</Os-Arch>
+ <Os-Version>${os.version}</Os-Version>
+ <Build-Number>${buildNumber}</Build-Number>
+ <Build-Time>${buildTime}</Build-Time>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>validate</id>
+ <goals>
+ <goal>validate</goal>
+ </goals>
+ <configuration>
+ <rhqVersion>${rhq.version}</rhqVersion>
+ </configuration>
+ </execution>
+ <execution>
+ <id>upload</id>
+ <goals>
+ <goal>upload</goal>
+ </goals>
+ <configuration>
+ <host>127.0.0.1</host>
+ <port>7080</port>
+ <username>rhqadmin</username>
+ <password>rhqadmin</password>
+ <startScan>true</startScan>
+ <failOnError>false</failOnError>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/etc/samples/mbeans-on-as7-plugin/src/main/resources/META-INF/rhq-plugin.xml b/etc/samples/mbeans-on-as7-plugin/src/main/resources/META-INF/rhq-plugin.xml
new file mode 100644
index 0000000..200c32e
--- /dev/null
+++ b/etc/samples/mbeans-on-as7-plugin/src/main/resources/META-INF/rhq-plugin.xml
@@ -0,0 +1,45 @@
+<plugin
+ name="MyappMBeansPlugin"
+ displayName="Myapp MBeans Plugin"
+ package="com.myapp.services.plugin"
+ xmlns="urn:xmlns:rhq-plugin"
+ xmlns:c="urn:xmlns:rhq-configuration">
+
+ <depends plugin="JBossAS7" useClasses="true"/>
+
+ <service name="Myapp Services"
+ discovery="org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansDiscoveryComponent"
+ class="org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansComponent"
+ description="Container for Myapp Services"
+ singleton="true">
+
+ <runs-inside>
+ <parent-resource-type name="JBossAS7 Standalone Server" plugin="JBossAS7"/>
+ <parent-resource-type name="Managed Server" plugin="JBossAS7"/>
+ </runs-inside>
+
+ <plugin-configuration>
+ <c:simple-property name="beansQueryString" readOnly="true" default="myapp:service=*"/>
+ <c:simple-property name="newResourceKey" readOnly="true" default="myappServices"/>
+ <c:simple-property name="newResourceName" readOnly="true" default="Myapp Services"/>
+ <c:simple-property name="newResourceDescription" readOnly="true" default="Container for Myapp Services"/>
+ </plugin-configuration>
+
+ <service name="HelloService" discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
+ class="org.rhq.plugins.jmx.MBeanResourceComponent" singleton="true">
+ <plugin-configuration>
+ <c:simple-property name="objectName" default="myapp:service=HelloService" readOnly="true"/>
+ </plugin-configuration>
+ <operation name="helloTo">
+ <parameters>
+ <c:simple-property name="p1" displayName="somebody" type="string" required="true"/>
+ </parameters>
+ <results>
+ <c:simple-property name="operationResult" type="string"/>
+ </results>
+ </operation>
+ </service>
+
+ </service>
+
+</plugin>
diff --git a/etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloService.java b/etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloService.java
new file mode 100644
index 0000000..a5eaaf8
--- /dev/null
+++ b/etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloService.java
@@ -0,0 +1,62 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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 as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU 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.test.apps.javaee6;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+import javax.management.ObjectName;
+
+import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
+
+/**
+ * @author Thomas Segismont
+ */
+@Singleton
+@Startup
+public class HelloService implements HelloServiceMBean {
+ private static final String BEAN_NAME = "myapp:service=" + HelloService.class.getSimpleName();
+
+ @PostConstruct
+ public void init() {
+ try {
+ getPlatformMBeanServer().registerMBean(this, new ObjectName(BEAN_NAME));
+ System.out.println("Registered = " + BEAN_NAME);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @PreDestroy
+ public void destroy() {
+ try {
+ getPlatformMBeanServer().unregisterMBean(new ObjectName(BEAN_NAME));
+ System.out.println("Unregistered = " + BEAN_NAME);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public String helloTo(String somebody) {
+ return String.format("Hello %s!", somebody);
+ }
+}
diff --git a/etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloServiceMBean.java b/etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloServiceMBean.java
new file mode 100644
index 0000000..b4a56f7
--- /dev/null
+++ b/etc/test-apps/javaee6-test-app/src/main/java/org/rhq/test/apps/javaee6/HelloServiceMBean.java
@@ -0,0 +1,10 @@
+package org.rhq.test.apps.javaee6;
+
+/**
+ * @author Thomas Segismont
+ */
+public interface HelloServiceMBean {
+
+ String helloTo(String somebody);
+
+}
diff --git a/modules/plugins/jboss-as-7-jmx/pom.xml b/modules/plugins/jboss-as-7-jmx/pom.xml
new file mode 100644
index 0000000..8b451e0
--- /dev/null
+++ b/modules/plugins/jboss-as-7-jmx/pom.xml
@@ -0,0 +1,33 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-plugins-parent</artifactId>
+ <version>4.10.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-jboss-as-7-jmx-util</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ JBossAS 7.x Plugin JMX Util</name>
+ <description>Utility classes to help monitoring MBeans of an application deployed on AS7 or EAP6</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-jboss-as-7-plugin</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-jmx-plugin</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansComponent.java b/modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansComponent.java
new file mode 100644
index 0000000..b6bc8de
--- /dev/null
+++ b/modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansComponent.java
@@ -0,0 +1,97 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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 as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU 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.modules.plugins.jbossas7.jmx;
+
+import static org.rhq.core.domain.measurement.AvailabilityType.DOWN;
+import static org.rhq.core.domain.measurement.AvailabilityType.UP;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mc4j.ems.connection.EmsConnection;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.modules.plugins.jbossas7.BaseComponent;
+import org.rhq.plugins.jmx.JMXComponent;
+
+/**
+ * A component class representing a container for appplication MBeans resources.
+ *
+ * @author Thomas Segismont
+ * @see ApplicationMBeansDiscoveryComponent
+ */
+public class ApplicationMBeansComponent implements JMXComponent<BaseComponent<?>> {
+ private static final Log LOG = LogFactory.getLog(ApplicationMBeansComponent.class);
+
+ private Configuration pluginConfiguration;
+ private EmsConnection emsConnection;
+ private String beansQueryString;
+
+ @Override
+ public void start(ResourceContext resourceContext) throws InvalidPluginConfigurationException, Exception {
+ pluginConfiguration = resourceContext.getPluginConfiguration();
+ beansQueryString = pluginConfiguration
+ .getSimpleValue(ApplicationMBeansDiscoveryComponent.PluginConfigProps.BEANS_QUERY_STRING);
+ emsConnection = ApplicationMBeansDiscoveryComponent.loadEmsConnection(pluginConfiguration);
+ }
+
+ @Override
+ public void stop() {
+ pluginConfiguration = null;
+ if (emsConnection != null) {
+ emsConnection.close();
+ }
+ }
+
+ @Override
+ public EmsConnection getEmsConnection() {
+ synchronized (this) {
+ if (emsConnection == null || !emsConnection.getConnectionProvider().isConnected()) {
+ emsConnection = ApplicationMBeansDiscoveryComponent.loadEmsConnection(pluginConfiguration);
+ }
+ }
+ return emsConnection;
+ }
+
+ @Override
+ public AvailabilityType getAvailability() {
+ EmsConnection connection = getEmsConnection();
+ if (connection == null) {
+ return DOWN;
+ }
+ if (!hasApplicationMBeans()) {
+ LOG.warn("Found no MBeans with query '" + beansQueryString + "'");
+ return DOWN;
+ }
+ return UP;
+ }
+
+ /**
+ * Checks if application MBeans are available. The default implementation uses the EMS query string stored in the
+ * resource plugin config.
+ *
+ * @return true if MBeans are available
+ */
+ protected boolean hasApplicationMBeans() {
+ return !emsConnection.queryBeans(beansQueryString).isEmpty();
+ }
+}
diff --git a/modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansDiscoveryComponent.java b/modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansDiscoveryComponent.java
new file mode 100644
index 0000000..aa924a8
--- /dev/null
+++ b/modules/plugins/jboss-as-7-jmx/src/main/java/org/rhq/modules/plugins/jbossas7/jmx/ApplicationMBeansDiscoveryComponent.java
@@ -0,0 +1,420 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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 as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU 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.modules.plugins.jbossas7.jmx;
+
+import static org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansDiscoveryComponent.PluginConfigProps.BEANS_QUERY_STRING;
+import static org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansDiscoveryComponent.PluginConfigProps.NEW_RESOURCE_DESCRIPTION;
+import static org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansDiscoveryComponent.PluginConfigProps.NEW_RESOURCE_NAME;
+import static org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansDiscoveryComponent.PluginConfigProps.NEW_RESOURCE_VERSION;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mc4j.ems.connection.ConnectionFactory;
+import org.mc4j.ems.connection.EmsConnection;
+import org.mc4j.ems.connection.settings.ConnectionSettings;
+import org.mc4j.ems.connection.support.ConnectionProvider;
+import org.mc4j.ems.connection.support.metadata.JSR160ConnectionTypeDescriptor;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
+import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
+import org.rhq.modules.plugins.jbossas7.BaseComponent;
+import org.rhq.modules.plugins.jbossas7.BaseServerComponent;
+import org.rhq.modules.plugins.jbossas7.ManagedASComponent;
+import org.rhq.modules.plugins.jbossas7.StandaloneASComponent;
+import org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration;
+
+/**
+ * Discovery class for the container {@link ApplicationMBeansComponent} component class.
+ *
+ * <h3>Custom plugin setup</h3>
+ *
+ * <p>This class is <strong>not</strong> declared in the AS7 plugin descriptor. It is a tool that that plugin developers
+ * may use while writing their <strong>own</strong> plugin to monitor their application MBeans.</p>
+ *
+ * <p>The custom plugin <strong>must</strong>:</p>
+ * <ul>
+ * <li>depend on the AS7 plugin and re-use its classes (<em>useClasses</em> attribute set to true in the plugin
+ * descriptor);</li>
+ * <li>embed the JMX plugin as a library.</li>
+ * </ul>
+ *
+ * <p>The resource type using this class (or a subclass of this class) as a discovery component must indicate which type
+ * of server it runs inside. It may be either a <em>JBossAS7 Standalone Server</em> or a <em>Managed Server</em>.</p>
+ *
+ * <p>Plugins authors are <em>required</em> to provide a resource key and name and <em>may</em>provide a resource
+ * description and version by declaring plugin configuration properties of the following names:</p>
+ *
+ * <ul>
+ * <li>{@link PluginConfigProps#NEW_RESOURCE_KEY}</li>
+ * <li>{@link PluginConfigProps#NEW_RESOURCE_NAME}</li>
+ * <li>{@link PluginConfigProps#NEW_RESOURCE_DESCRIPTION}</li>
+ * <li>{@link PluginConfigProps#NEW_RESOURCE_VERSION}</li>
+ * </ul>
+ *
+ * <p>Alternatively, they can subclass create a subclass of this discovery component and override one/some/all of the
+ * following methods:</p>
+ *
+ * <ul>
+ * <li>{@link #getNewResourceKey(org.rhq.core.domain.configuration.Configuration)}</li>
+ * <li>{@link #getNewResourceName(org.rhq.core.domain.configuration.Configuration)}</li>
+ * <li>{@link #getNewResourceDescription(org.rhq.core.domain.configuration.Configuration)} </li>
+ * <li>{@link #getNewResourceVersion(org.rhq.core.domain.configuration.Configuration)}</li>
+ * </ul>
+ *
+ * <h3>Auto-discovery</h3>
+ *
+ * <p>By default, application MBeans will be searched with an EMS query defined in the plugin descriptor by the
+ * {@link PluginConfigProps#BEANS_QUERY_STRING} plugin-config property.
+ * <br>
+ * It is also possible to define the query string in a subclass overriding the
+ * {@link #getBeansQueryString(org.rhq.core.domain.configuration.Configuration)} method.
+ * </p>
+ *
+ * <p>Plugin developers can implement their custom MBeans lookup method in a subclass overriding the
+ * {@link #hasApplicationMBeans(org.rhq.core.domain.configuration.Configuration, org.mc4j.ems.connection.EmsConnection)}
+ * method.</p>
+ *
+ * <h3>JMX host and port discovery</h3>
+ *
+ * <p>The JMX server host will be detected by looking at the top level server resource plugin configuration
+ * ({@link org.rhq.modules.plugins.jbossas7.StandaloneASComponent} and {@link org.rhq.modules.plugins.jbossas7.HostControllerComponent}). The JMX port detection mechanism depends on the
+ * parent resource.</p>
+ *
+ * <h4>On standalone servers</h4>
+ *
+ * <p>In standalone mode, the discovery component will look at the management port defined in the parent
+ * {@link org.rhq.modules.plugins.jbossas7.StandaloneASComponent} plugin configuration and add the value {@link #STANDALONE_REMOTING_PORT_OFFSET}.</p>
+ *
+ * <h4>On managed servers</h4>
+ *
+ * <p>In domain mode, the discovery component will use '4447' <em>plus</em> the port offset of the managed server.</p>
+ *
+ * <h3>Authentication</h3>
+ *
+ * <p>JMX connectivity on AS7 and EAP6 requires authentication and standalone and managed servers behaviors differ.</p>
+ *
+ * <h4>On standalone servers</h4>
+ *
+ * <p>In standalone mode, the server will use the ManagementRealm, just as for HTTP management interface authentication.
+ * Consequently, this class will pick up the credentials of the management user defined in the plugin configuration of
+ * the parent server resource ({@link org.rhq.modules.plugins.jbossas7.StandaloneASComponent}).</p>
+ *
+ * <p>In other words, plugin authors have nothing to do.</p>
+ *
+ * <h4>On managed servers</h4>
+ *
+ * <p>In domain mode, the server will use the ApplicationRealm. Consequently, there is no way for the discovery
+ * component to discover credentials automatically and it will use "rhqadmin:rhqadmin" by default.</p>
+ *
+ * <p>When working with managed servers, plugin developers should subclass the discovery component and override the
+ * {@link #getCredentialsForManagedAS()} method. For example, an implementation could lookup the credentials in a
+ * text file.</p>
+ *
+ * <h3>Plugin descriptor example</h3>
+ *
+ * <pre>
+ * <plugin
+ * name="MyappMBeansPlugin"
+ * displayName="Myapp MBeans Plugin"
+ * package="com.myapp.services.plugin"
+ * xmlns="urn:xmlns:rhq-plugin"
+ * xmlns:c="urn:xmlns:rhq-configuration">
+ *
+ * <depends plugin="JBossAS7" useClasses="true"/>
+ *
+ * <service name="Myapp Services"
+ * discovery="org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansDiscoveryComponent"
+ * class="org.rhq.modules.plugins.jbossas7.jmx.ApplicationMBeansComponent"
+ * description="Container for Myapp Services"
+ * singleton="true">
+ *
+ * <runs-inside>
+ * <!-- The type of the server the application is running on -->
+ * <parent-resource-type name="JBossAS7 Standalone Server" plugin="JBossAS7"/>
+ * <parent-resource-type name="Managed Server" plugin="JBossAS7"/>
+ * </runs-inside>
+ *
+ * <plugin-configuration>
+ * <c:simple-property name="beansQueryString" readOnly="true" default="myapp:service=*"/>
+ * <c:simple-property name="newResourceKey" readOnly="true" default="myappServices"/>
+ * <c:simple-property name="newResourceName" readOnly="true" default="Myapp Services"/>
+ * <c:simple-property name="newResourceDescription" readOnly="true" default="Container for Myapp Services"/>
+ * </plugin-configuration>
+ *
+ * <!--
+ * ApplicationMBeansComponent can be the parent of any JMXComponent (JMX plugin). For example, it's possible
+ * to monitor a MBean with no line of Java code thanks to the MBeanResourceComponent facility. Plugin authors
+ * only have to configure metrics (mapped to MBeans attributes) and operations (MBeans operations).
+ * -->
+ * <service name="HelloService" discovery="org.rhq.plugins.jmx.MBeanResourceDiscoveryComponent"
+ * class="org.rhq.plugins.jmx.MBeanResourceComponent" singleton="true">
+ * <plugin-configuration>
+ * <c:simple-property name="objectName" default="myapp:service=HelloService" readOnly="true"/>
+ * </plugin-configuration>
+ * <operation name="helloTo">
+ * <parameters>
+ * <c:simple-property name="p1" displayName="somebody" type="string" required="true"/>
+ * </parameters>
+ * <results>
+ * <c:simple-property name="operationResult" type="string"/>
+ * </results>
+ * </operation>
+ * </service>
+ *
+ * </service>
+ *
+ * </plugin>
+ * </pre>
+ *
+ * @author Thomas Segismont
+ * @see ApplicationMBeansComponent
+ */
+public class ApplicationMBeansDiscoveryComponent implements ResourceDiscoveryComponent<BaseComponent<?>> {
+ private static final Log LOG = LogFactory.getLog(ApplicationMBeansDiscoveryComponent.class);
+
+ public static final class PluginConfigProps {
+ public static final String BEANS_QUERY_STRING = "beansQueryString";
+ public static final String NEW_RESOURCE_KEY = "newResourceKey";
+ public static final String NEW_RESOURCE_NAME = "newResourceName";
+ public static final String NEW_RESOURCE_DESCRIPTION = "newResourceDescription";
+ public static final String NEW_RESOURCE_VERSION = "newResourceVersion";
+
+ private PluginConfigProps() {
+ // Constants class
+ }
+ }
+
+ private static final String HOSTNAME = "hostname";
+ private static final String PORT = "port";
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
+ private static final String CLIENT_JAR_LOCATION = "clientJarLocation";
+
+ private static final int STANDALONE_REMOTING_PORT_OFFSET = 9;
+ private static final int DOMAIN_REMOTING_PORT_DEFAULT = 4447;
+ private static final String MANAGED_SERVER_PORT_OFFSET_PROPERTY_NAME = "socket-binding-port-offset";
+
+ @Override
+ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext<BaseComponent<?>> context)
+ throws Exception {
+
+ BaseComponent<?> parentComponent = context.getParentResourceComponent();
+ BaseServerComponent baseServerComponent = parentComponent.getServerComponent();
+ ServerPluginConfiguration serverPluginConfiguration = baseServerComponent.getServerPluginConfiguration();
+
+ Configuration pluginConfig = context.getDefaultPluginConfiguration();
+
+ pluginConfig.setSimpleValue(HOSTNAME, serverPluginConfiguration.getHostname());
+
+ int port;
+ String username, password;
+ if (parentComponent instanceof ManagedASComponent) {
+ ManagedASComponent managedASComponent = (ManagedASComponent) parentComponent;
+ Configuration managedASConfig = managedASComponent.loadResourceConfiguration();
+ PropertySimple offsetProp = managedASConfig.getSimple(MANAGED_SERVER_PORT_OFFSET_PROPERTY_NAME);
+ if (offsetProp == null) {
+ LOG.warn("Could not find Managed Server socket binding offset, skipping discovery");
+ return Collections.emptySet();
+ }
+ port = offsetProp.getIntegerValue() + DOMAIN_REMOTING_PORT_DEFAULT;
+ String[] credentials = getCredentialsForManagedAS();
+ username = credentials[0];
+ password = credentials[1];
+ } else if (parentComponent instanceof StandaloneASComponent) {
+ port = serverPluginConfiguration.getPort() + STANDALONE_REMOTING_PORT_OFFSET;
+ username = serverPluginConfiguration.getUser();
+ password = serverPluginConfiguration.getPassword();
+ } else {
+ LOG.warn(parentComponent + " is not a supported parent component");
+ return Collections.emptySet();
+ }
+ pluginConfig.setSimpleValue(PORT, String.valueOf(port));
+ pluginConfig.setSimpleValue(USERNAME, username);
+ pluginConfig.setSimpleValue(PASSWORD, password);
+
+ File clientJarFile = new File(serverPluginConfiguration.getHomeDir(), "bin" + File.separator + "client"
+ + File.separator + "jboss-client.jar");
+ if (!clientJarFile.isFile()) {
+ LOG.warn(clientJarFile + " does not exist.");
+ return Collections.emptySet();
+ }
+ pluginConfig.setSimpleValue(CLIENT_JAR_LOCATION, clientJarFile.getAbsolutePath());
+
+ EmsConnection emsConnection = null;
+ try {
+ emsConnection = loadEmsConnection(pluginConfig);
+ if (emsConnection == null) {
+ // An error occured while creating the connection
+ return Collections.emptySet();
+ }
+ if (!hasApplicationMBeans(pluginConfig, emsConnection)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("No application MBeans found");
+ }
+ return Collections.emptySet();
+ }
+
+ return Collections.singleton(new DiscoveredResourceDetails(context.getResourceType(),
+ getNewResourceKey(pluginConfig), getNewResourceName(pluginConfig), getNewResourceVersion(pluginConfig),
+ getNewResourceDescription(pluginConfig), pluginConfig, null));
+
+ } finally {
+ if (emsConnection != null) {
+ emsConnection.close();
+ }
+ }
+ }
+
+ /**
+ * Indicates if a managed server or a standalone server has application MBeans. This implementation searches MBeans
+ * with an EMS query string.
+ *
+ * @param pluginConfig - the plugin configuration object for the {@link ApplicationMBeansComponent} that may be
+ * created
+ * @param emsConnection - an active emsConnection which can be used to communicate with the server
+ * @return true if application MBeans were detected, false otherwise
+ */
+ protected boolean hasApplicationMBeans(Configuration pluginConfig, EmsConnection emsConnection) {
+ String beansQueryString = getBeansQueryString(pluginConfig);
+ if (emsConnection.queryBeans(beansQueryString).isEmpty()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found no MBeans with query '" + beansQueryString + "'");
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Default implementation of the credentials lookup for JMX authentication against managed servers (domain mode).
+ *
+ * @return an array of two elements, the first being the username and the second the password
+ */
+ protected String[] getCredentialsForManagedAS() {
+ return new String[] { "rhqadmin", "rhqadmin" };
+ }
+
+ /**
+ * The EMS query string chosen when using the default implementation of
+ * {@link #hasApplicationMBeans(org.rhq.core.domain.configuration.Configuration, org.mc4j.ems.connection.EmsConnection)}.
+ *
+ * @param pluginConfig - the plugin configuration object for the {@link ApplicationMBeansComponent} that will be
+ * created
+ * @return an EMS query string
+ */
+ protected String getBeansQueryString(Configuration pluginConfig) {
+ return pluginConfig.getSimpleValue(BEANS_QUERY_STRING);
+ }
+
+ /**
+ * @param pluginConfig - the plugin configuration object for the {@link ApplicationMBeansComponent} that will be
+ * created
+ * @return the new resource key
+ */
+ protected String getNewResourceKey(Configuration pluginConfig) {
+ return pluginConfig.getSimpleValue(PluginConfigProps.NEW_RESOURCE_KEY);
+ }
+
+ /**
+ * @param pluginConfig - the plugin configuration object for the {@link ApplicationMBeansComponent} that will be
+ * created
+ * @return the new resource name
+ */
+ protected String getNewResourceName(Configuration pluginConfig) {
+ return pluginConfig.getSimpleValue(NEW_RESOURCE_NAME);
+ }
+
+ /**
+ * @param pluginConfig - the plugin configuration object for the {@link ApplicationMBeansComponent} that will be
+ * created
+ * @return the new resource description
+ */
+ protected String getNewResourceDescription(Configuration pluginConfig) {
+ return pluginConfig.getSimpleValue(NEW_RESOURCE_DESCRIPTION);
+ }
+
+ /**
+ * @param pluginConfig - the plugin configuration object for the {@link ApplicationMBeansComponent} that will be
+ * created
+ * @return the new resource version
+ */
+ protected String getNewResourceVersion(Configuration pluginConfig) {
+ return pluginConfig.getSimpleValue(NEW_RESOURCE_VERSION);
+ }
+
+ /**
+ * Creates a new {@link EmsConnection} object.
+ *
+ * @param pluginConfig - a plugin configuration object of the {@link ApplicationMBeansComponent}
+ * @return a new {@link EmsConnection} object or null if connecting failed
+ */
+ public static EmsConnection loadEmsConnection(Configuration pluginConfig) {
+ EmsConnection emsConnection = null;
+ try {
+ File clientJarFile = new File(pluginConfig.getSimpleValue(CLIENT_JAR_LOCATION));
+
+ ConnectionSettings connectionSettings = new ConnectionSettings();
+ connectionSettings.initializeConnectionType(new A7ConnectionTypeDescriptor(clientJarFile));
+ connectionSettings.setLibraryURI(clientJarFile.getParent());
+ connectionSettings.setServerUrl( //
+ "service:jmx:remoting-jmx://" //
+ + pluginConfig.getSimpleValue(HOSTNAME) //
+ + ":" //
+ + pluginConfig.getSimpleValue(PORT));
+ connectionSettings.setPrincipal(pluginConfig.getSimpleValue(USERNAME));
+ connectionSettings.setCredentials(pluginConfig.getSimpleValue(PASSWORD));
+
+ ConnectionFactory connectionFactory = new ConnectionFactory();
+ connectionFactory.discoverServerClasses(connectionSettings);
+ ConnectionProvider connectionProvider = connectionFactory.getConnectionProvider(connectionSettings);
+
+ return connectionProvider.connect();
+
+ } catch (Exception e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not create EmsConnection", e);
+ }
+ if (emsConnection != null) {
+ emsConnection.close();
+ }
+ return null;
+ }
+ }
+
+ private static class A7ConnectionTypeDescriptor extends JSR160ConnectionTypeDescriptor {
+ private final File clientJarFile;
+
+ public A7ConnectionTypeDescriptor(File clientJarFile) {
+ this.clientJarFile = clientJarFile;
+ }
+
+ @Override
+ public String[] getConnectionClasspathEntries() {
+ return new String[] { clientJarFile.getName() };
+ }
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/test/resources/itest/javaee6-test-app.war b/modules/plugins/jboss-as-7/src/test/resources/itest/javaee6-test-app.war
index f88eab4..fbbb6c2 100644
Binary files a/modules/plugins/jboss-as-7/src/test/resources/itest/javaee6-test-app.war and b/modules/plugins/jboss-as-7/src/test/resources/itest/javaee6-test-app.war differ
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index 54197c5..e7bceaf 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -135,6 +135,7 @@
<module>jboss-as</module>
<module>jboss-as-5</module>
<module>jboss-as-7</module>
+ <module>jboss-as-7-jmx</module>
<module>rhq-server</module>
<module>jboss-cache-v3</module>
<!-- was not in Jopr build at merge time <module>jbossOSGi</module> -->
10 years, 5 months
[rhq] Changes to 'BZ1046154'
by Simeon Pinder
New branch 'BZ1046154' available with the following commits:
commit 59efc5809cf895e601a5127d625047b220f4e8f5
Author: Simeon Pinder <spinder(a)fulliautomatix.conchfritter.com>
Date: Fri Jan 10 08:04:42 2014 -0500
[BZ 1046154] fix domain api javadoc issue. Domain was not explicitly included
in the javadoc reactor but only coincidentally so with previous releases.
10 years, 5 months
[rhq] Branch 'release/jon3.2.x' - modules/core
by Simeon Pinder
modules/core/pom.xml | 1 +
1 file changed, 1 insertion(+)
New commits:
commit 116344b8f96a887a097a1a7ce8577652ecc9cd15
Author: Simeon Pinder <spinder(a)fulliautomatix.conchfritter.com>
Date: Fri Jan 10 08:04:42 2014 -0500
[BZ 1046154] fix domain api javadoc issue. Domain was not explicitly included
in the javadoc reactor but only coincidentally so with previous releases.
diff --git a/modules/core/pom.xml b/modules/core/pom.xml
index 60ab57b..ccb9aed 100644
--- a/modules/core/pom.xml
+++ b/modules/core/pom.xml
@@ -111,6 +111,7 @@
<modules>
<module>native-system</module>
<module>plugin-api</module>
+ <module>domain</module>
</modules>
<build>
10 years, 5 months
[rhq] modules/core
by Simeon Pinder
modules/core/pom.xml | 1 +
1 file changed, 1 insertion(+)
New commits:
commit 7f418bee064004b303305434c0ab206094b4e3f7
Author: Simeon Pinder <spinder(a)fulliautomatix.conchfritter.com>
Date: Fri Jan 10 08:04:42 2014 -0500
[BZ 1046154] fix domain api javadoc issue. Domain was not explicitly included
in the javadoc reactor but only coincidentally so with previous releases.
diff --git a/modules/core/pom.xml b/modules/core/pom.xml
index d68e830..7017b8e 100644
--- a/modules/core/pom.xml
+++ b/modules/core/pom.xml
@@ -111,6 +111,7 @@
<modules>
<module>native-system</module>
<module>plugin-api</module>
+ <module>domain</module>
</modules>
<build>
10 years, 5 months