modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java | 5 modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 31 modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertCondition.java | 2 modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java | 3 modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java | 2 modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/InventoryContext.java | 65 modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java | 14 modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java | 6 modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java | 12 modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java | 6 modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java | 12 modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java | 43 modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryContextImpl.java | 57 modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 49 modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java | 2 modules/enterprise/agent/src/etc/rhq-agent-wrapper.sh | 40 modules/enterprise/binding/pom.xml | 7 modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java | 39 modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java | 58 modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptedTestBase.java | 220 + modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java | 269 +- modules/enterprise/gui/coregui/pom.xml | 13 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java | 33 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java | 5 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/BundleSelector.java | 14 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java | 11 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesDataSource.java | 28 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java | 35 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java | 45 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/DynamicCallbackFormImplIE8.java | 50 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java | 1 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java | 21 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java | 33 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java | 7 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeSearchView.java | 116 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java | 6 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/LiveGraphView.java | 17 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java | 6 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml | 20 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 10 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties | 6 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 10 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties | 6 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties | 10 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties | 6 modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties | 10 modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html | 3 modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.7.2.min.js | 4 modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-1.6.js | 1271 ---------- modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-2.0.min.js | 5 modules/enterprise/remoting/cli/pom.xml | 27 modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/ClientMain.java | 28 modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml | 9 modules/enterprise/scripting/javascript/pom.xml | 2 modules/enterprise/scripting/pom.xml | 5 modules/enterprise/scripting/python/pom.xml | 2 modules/enterprise/server/ear/pom.xml | 20 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java | 18 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerLocal.java | 19 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java | 5 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/GroupAlertDefinitionManagerBean.java | 4 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java | 20 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 13 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java | 2 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/LargeGroupCriteriaTest.java | 55 modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java | 139 - modules/enterprise/server/plugins/pom.xml | 1 modules/helpers/pluginAnnotations/pom.xml | 8 modules/helpers/pluginGen/pom.xml | 6 modules/helpers/pluginGen/src/main/resources/pom.ftl | 15 modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java | 3 modules/plugins/database/src/test/java/org/rhq/plugins/database/ComponentTest.java | 7 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextComponent.java | 46 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/CreateChildResourceFacetDelegate.java | 13 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstallationInfo.java | 47 modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProductType.java | 7 modules/plugins/jboss-as-7/pom.xml | 1 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 56 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java | 3 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java | 49 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConnectorDiscoveryGroupValidatorComponent.java | 83 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DatasourceComponent.java | 43 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainDeploymentComponent.java | 8 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HornetQComponent.java | 27 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java | 7 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java | 32 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java | 2 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SocketBindingGroupComponent.java | 11 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java | 118 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java | 7 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SubsystemDiscovery.java | 61 modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TransactionsComponent.java | 62 modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 334 +- modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java | 107 modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java | 6 modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java | 3 modules/plugins/jboss-as-7/src/test/resources/test-plugin.xml | 33 modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java | 38 modules/plugins/jboss-cache-v3/src/main/java/org/rhq/plugins/jbosscache3/JBossCacheDetailDiscoveryComponent.java | 8 modules/plugins/jboss-cache-v3/src/main/resources/META-INF/rhq-plugin.xml | 2 modules/plugins/mysql/src/test/java/org/rhq/plugins/mysql/ComponentTest.java | 5 modules/plugins/oracle/src/test/java/org/rhq/plugins/oracle/ComponentTest.java | 12 modules/plugins/perftest/src/main/resources/META-INF/rhq-plugin.xml | 8 modules/plugins/perftest/src/main/resources/configurable-7.xml | 40 modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java | 5 pom.xml | 19 106 files changed, 2410 insertions(+), 2045 deletions(-)
New commits: commit 8e5f17203b143ac986c5d7db683fdb204fe28dbb Merge: bdb98df 42c00f9 Author: John Sanda jsanda@redhat.com Date: Thu Sep 6 07:51:39 2012 -0400
Merge branch 'master' into jsanda/metrics-rhq
Conflicts: modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 13c240d,1443b80..5b80b4a --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@@ -4007,22 -4007,34 +4007,33 @@@ <schema-javaTask className="ContentSourceConfigurationObfuscationUpgradeTask" /> </schemaSpec>
+ <!-- RHQ 4.4, JON 3.1.0 RELEASE uses DB Schema 2.121 --> + <schemaSpec version="2.122"> - <schema-addColumn table="RHQ_CONFIG_PROP_DEF" column="MIN_ENTRIES" columnType="INTEGER"/> - <schema-addColumn table="RHQ_CONFIG_PROP_DEF" column="MAX_ENTRIES" columnType="INTEGER"/> + <schema-directSQL> + <statement desc="Updating DOWN Alert Conditions to new format"> + UPDATE RHQ_ALERT_CONDITION + SET NAME = 'AVAIL_GOES_DOWN', OPTION_STATUS = NULL + WHERE TYPE = 'AVAILABILITY' + AND NAME IS NULL + AND OPTION_STATUS = 'DOWN' + </statement> + <statement desc="Updating UP Alert Conditions to new format"> + UPDATE RHQ_ALERT_CONDITION + SET NAME = 'AVAIL_GOES_UP', OPTION_STATUS = NULL + WHERE TYPE = 'AVAILABILITY' + AND NAME IS NULL + AND OPTION_STATUS = 'UP' + </statement> + </schema-directSQL> </schemaSpec> - -<!-- JON 3.1.1 RELEASE uses DB Schema 2.122 --> + + <schemaSpec version="2.123"> - <schema-directSQL> - <statement desc="Adding metrics server plugin active plugin system configuration property"> - INSERT INTO rhq_system_config (id, property_key, property_value, default_property_value) - VALUES (59, 'ACTIVE_METRICS_PLUGIN', 'metrics-rhq', 'metrics-rhq') - </statement> - </schema-directSQL> + <schema-addColumn table="RHQ_CONFIG_PROP_DEF" column="MIN_ENTRIES" columnType="INTEGER"/> + <schema-addColumn table="RHQ_CONFIG_PROP_DEF" column="MAX_ENTRIES" columnType="INTEGER"/> </schemaSpec>
- - </dbupgrade> </target> </project> diff --cc modules/enterprise/server/plugins/pom.xml index f9a86f5,11f3b5c..6a5e729 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@@ -78,9 -78,7 +78,8 @@@ <module>filetemplate-bundle</module> <module>ant-bundle</module> <module>validate-all-serverplugins</module> - <module>groovy-script</module> <module>packagetype-cli</module> + <module>metrics-rhq</module> </modules>
</project>
commit 42c00f9ade61af787ec4dd325b1045c6841f22bb Author: Heiko W. Rupp hwr@redhat.com Date: Mon Aug 27 15:25:57 2012 -0400
Update pom-template.
diff --git a/modules/helpers/pluginGen/src/main/resources/pom.ftl b/modules/helpers/pluginGen/src/main/resources/pom.ftl index 378bd76..2434ddd 100644 --- a/modules/helpers/pluginGen/src/main/resources/pom.ftl +++ b/modules/helpers/pluginGen/src/main/resources/pom.ftl @@ -2,7 +2,7 @@ <#-- /* * RHQ Management Platform - * Copyright (C) 2005-2008 Red Hat, Inc. + * Copyright (C) 2005-20012 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -31,7 +31,7 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-plugins-parent</artifactId> - <version><#if props.rhqVersion??>${props.rhqVersion}<#else >1.3.0-SNAPSHOT</#if></version><!-- TODO adjust RHQ version --> + <version><#if props.rhqVersion??>${props.rhqVersion}<#else >4.5.0-SNAPSHOT</#if></version><!-- TODO adjust RHQ version --> </parent>
<groupId>org.rhq</groupId> @@ -43,9 +43,6 @@ <description>${props.description}</description> </#if>
- <properties> - <rhq.version><#if props.rhqVersion??>${props.rhqVersion}<#else >1.3.0-SNAPSHOT</#if></rhq.version> <!-- TODO adjust, see above too --> - </properties>
<build> <plugins> @@ -212,26 +209,26 @@ <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-core-domain</artifactId> - <version>${r"${rhq.version}"}</version> + <version>${r"${project.version}"}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-core-plugin-api</artifactId> - <version>${r"${rhq.version}"}</version> + <version>${r"${project.version}"}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-core-native-system</artifactId> - <version>${r"${rhq.version}"}</version> + <version>${r"${project.version}"}</version> <scope>provided</scope> </dependency> <#if props.dependsOnJmxPlugin> <dependency> <groupId>org.rhq</groupId> <artifactId>rhq-jmx-plugin</artifactId> - <version>${r"${rhq.version}"}</version> + <version>${r"${project.version}"}</version> <scope>provided</scope> </dependency> </#if>
commit 11fb6e5360c29a76726d7759b680220459386497 Author: Heiko W. Rupp hwr@redhat.com Date: Thu Aug 23 12:07:35 2012 -0400
Update plugin generator poms.
diff --git a/modules/helpers/pluginAnnotations/pom.xml b/modules/helpers/pluginAnnotations/pom.xml index b6720cb..74800f8 100644 --- a/modules/helpers/pluginAnnotations/pom.xml +++ b/modules/helpers/pluginAnnotations/pom.xml @@ -7,20 +7,20 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>3.0.0</version> + <version>4.5.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
<groupId>org.rhq.helpers</groupId> <artifactId>rhq-pluginAnnotations</artifactId> <packaging>jar</packaging> - <version>3.0.2-SNAPSHOT</version> + <version>4.5.0-SNAPSHOT</version>
<name>RHQ plugin annotations</name> <description>Annotations to help generate plugin descriptors</description>
<build> - + <plugins>
<plugin> @@ -31,7 +31,7 @@ </configuration> </plugin>
- <plugin> + <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> diff --git a/modules/helpers/pluginGen/pom.xml b/modules/helpers/pluginGen/pom.xml index 299550d..62bf822 100644 --- a/modules/helpers/pluginGen/pom.xml +++ b/modules/helpers/pluginGen/pom.xml @@ -7,14 +7,14 @@ <parent> <groupId>org.rhq</groupId> <artifactId>rhq-parent</artifactId> - <version>3.0.0</version> + <version>4.5.0-SNAPSHOT</version> <relativePath>../../../pom.xml</relativePath> </parent>
<groupId>org.rhq.helpers</groupId> <artifactId>rhq-pluginGen</artifactId> <packaging>jar</packaging> - <version>3.0.2-SNAPSHOT</version> + <version>4.5.0-SNAPSHOT</version>
<name>RHQ plugin generator</name> <description>Helper to generate plugin skeletons</description> @@ -90,7 +90,7 @@ <dependency> <groupId>org.rhq.helpers</groupId> <artifactId>rhq-pluginAnnotations</artifactId> - <version>3.0.2-SNAPSHOT</version> + <version>4.5.0-SNAPSHOT</version> </dependency> </dependencies>
commit e33404e91d4b0cfc681e7816872e93c107b5d8f5 Author: Jirka Kremser jkremser@redhat.com Date: Fri Aug 31 13:02:07 2012 +0200
[BZ 773626 - Failed to load resource composite data error when refreshing Inventory page (Unavailable Servers, Servers, etc)] handling the exception on the client side and re-fetch the data
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java index 55271c6..383602b 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java @@ -171,6 +171,12 @@ public class ResourceDatasource extends RPCDataSource<Resource, ResourceCriteria if (caught.getMessage().contains("SearchExpressionException")) { Message message = new Message("Invalid search expression.", Message.Severity.Error); CoreGUI.getMessageCenter().notify(message); + } else if (caught.getMessage().contains("PageList was passed an empty collection")) { + // Because of bug 773626 + Log.warn(caught.getMessage()); + criteria.setPageControl(new PageControl(0, getDataPageSize())); + executeFetch(request, response, criteria); + return; } else { CoreGUI.getErrorHandler().handleError(MSG.view_inventory_resources_loadFailed(), caught); }
commit 1293a88ef64918b6401bd830a0739c8f22398fc9 Author: Simeon Pinder spinder@fulliautomatix.conchfritter.com Date: Thu Aug 30 16:11:28 2012 -0400
[BZ 840512] adding logic to defend against @PostLoad logic not being called after installation as expected.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java index 07b3467..bb00ef5 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ObfuscatedPropertySimple.java @@ -122,6 +122,9 @@ public class ObfuscatedPropertySimple extends PropertySimple { */ @Override public String getStringValue() { + if (clearTextValue == null) { + initClearTextValue(); + } return clearTextValue; }
commit 26941dd6fb00043842ad5d4e6786b1f5ed391382 Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Aug 30 11:18:30 2012 -0400
[Bug 852561 - AlertCondition.name is null in database after JON 2.4 to 3.1 upgrade] fix merge issue
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 94fa46f..1443b80 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -4010,20 +4010,22 @@ <!-- RHQ 4.4, JON 3.1.0 RELEASE uses DB Schema 2.121 -->
<schemaSpec version="2.122"> - <statement desc="Updating DOWN Alert Conditions to new format"> - UPDATE RHQ_ALERT_CONDITION - SET NAME = 'AVAIL_GOES_DOWN', OPTION_STATUS = NULL - WHERE TYPE = 'AVAILABILITY' - AND NAME IS NULL - AND OPTION_STATUS = 'DOWN' - </statement> - <statement desc="Updating UP Alert Conditions to new format"> - UPDATE RHQ_ALERT_CONDITION - SET NAME = 'AVAIL_GOES_UP', OPTION_STATUS = NULL - WHERE TYPE = 'AVAILABILITY' - AND NAME IS NULL - AND OPTION_STATUS = 'UP' - </statement> + <schema-directSQL> + <statement desc="Updating DOWN Alert Conditions to new format"> + UPDATE RHQ_ALERT_CONDITION + SET NAME = 'AVAIL_GOES_DOWN', OPTION_STATUS = NULL + WHERE TYPE = 'AVAILABILITY' + AND NAME IS NULL + AND OPTION_STATUS = 'DOWN' + </statement> + <statement desc="Updating UP Alert Conditions to new format"> + UPDATE RHQ_ALERT_CONDITION + SET NAME = 'AVAIL_GOES_UP', OPTION_STATUS = NULL + WHERE TYPE = 'AVAILABILITY' + AND NAME IS NULL + AND OPTION_STATUS = 'UP' + </statement> + </schema-directSQL> </schemaSpec>
<!-- JON 3.1.1 RELEASE uses DB Schema 2.122 -->
commit 35c152e87e280d8a5cd93353892da39067883819 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Aug 29 15:39:00 2012 -0400
[Bug 852561 - AlertCondition.name is null in database after JON 2.4 to 3.1 upgrade] From an RHQ perspective this should have affected upgrades to RHQ 4.4. Add a db upgrade step to convert relevant alert condition rows to the new format.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml index d4b5505..eee04da 100644 --- a/modules/core/dbutils/pom.xml +++ b/modules/core/dbutils/pom.xml @@ -17,7 +17,7 @@ <description>Database schema setup, upgrade and other utilities</description>
<properties> - <db.schema.version>2.122</db.schema.version> + <db.schema.version>2.123</db.schema.version> <rhq.ds.type-mapping>${rhq.test.ds.type-mapping}</rhq.ds.type-mapping> <rhq.ds.server-name>${rhq.test.ds.server-name}</rhq.ds.server-name> <rhq.ds.db-name>${rhq.test.ds.db-name}</rhq.ds.db-name> diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml index 2cee9f4..94fa46f 100644 --- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml +++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml @@ -4007,7 +4007,28 @@ <schema-javaTask className="ContentSourceConfigurationObfuscationUpgradeTask" /> </schemaSpec>
- <schemaSpec version="2.122"> +<!-- RHQ 4.4, JON 3.1.0 RELEASE uses DB Schema 2.121 --> + + <schemaSpec version="2.122"> + <statement desc="Updating DOWN Alert Conditions to new format"> + UPDATE RHQ_ALERT_CONDITION + SET NAME = 'AVAIL_GOES_DOWN', OPTION_STATUS = NULL + WHERE TYPE = 'AVAILABILITY' + AND NAME IS NULL + AND OPTION_STATUS = 'DOWN' + </statement> + <statement desc="Updating UP Alert Conditions to new format"> + UPDATE RHQ_ALERT_CONDITION + SET NAME = 'AVAIL_GOES_UP', OPTION_STATUS = NULL + WHERE TYPE = 'AVAILABILITY' + AND NAME IS NULL + AND OPTION_STATUS = 'UP' + </statement> + </schemaSpec> + +<!-- JON 3.1.1 RELEASE uses DB Schema 2.122 --> + + <schemaSpec version="2.123"> <schema-addColumn table="RHQ_CONFIG_PROP_DEF" column="MIN_ENTRIES" columnType="INTEGER"/> <schema-addColumn table="RHQ_CONFIG_PROP_DEF" column="MAX_ENTRIES" columnType="INTEGER"/> </schemaSpec> diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertCondition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertCondition.java index 8a72244..0744199 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertCondition.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertCondition.java @@ -427,7 +427,7 @@ public class AlertCondition implements Serializable { /** * The name of the condition whose semantics are different based on this condition's category: * - * AVAILABILITY: n/a (null) + * AVAILABILITY: The relevant Avail AlertConditionOperator name * THRESHOLD: the name of the metric (TODO: today its the display name, very bad for i18n purposes) * BASELINE: the name of the metric (TODO: today its the display name, very bad for i18n purposes) * CHANGE: the name of the metric (TODO: today its the display name, very bad for i18n purposes)
commit 74704eda37bce26278fa089437d98bcd590b4317 Author: Jirka Kremser jkremser@redhat.com Date: Wed Aug 29 14:15:26 2012 +0200
[BZ 814305 - Dealing with singletons in inventory] Refresh button now takes into consideration the already created singletons and they are not populated in the create/import child combobox
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java index 2eea340..d539136 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/Table.java @@ -597,7 +597,7 @@ public class Table<DS extends RPCDataSource> extends LocatableHLayout implements } else { // menu action LocatableMenu menu = new LocatableMenu(tableAction.getLocatorId() + "Menu"); - final Map<String, ? extends Object> menuEntries = tableAction.getValueMap(); + final Map<String, Object> menuEntries = tableAction.getValueMap(); for (final String key : menuEntries.keySet()) { MenuItem item = new MenuItem(key); item.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler() { @@ -980,7 +980,7 @@ public class Table<DS extends RPCDataSource> extends LocatableHLayout implements * completion. Failure to do so may leave the widgets disabled. */ public void addTableAction(String locatorId, String title, String confirmation, - LinkedHashMap<String, ? extends Object> valueMap, TableAction tableAction) { + Map<String, Object> valueMap, TableAction tableAction) { // If the specified locator ID is qualified, strip off the ancestry prefix, so we can make sure its locator ID // extends the footer's locator ID as it should. int underscoreIndex = locatorId.lastIndexOf('_'); @@ -995,6 +995,37 @@ public class Table<DS extends RPCDataSource> extends LocatableHLayout implements tableActions.add(info); }
+ /** + * Updates the list of table's associated actions <code>tableActions</code>. + * It automatically updates the gui by calling <code>drawFooter()</code> provided the table has been initialized. + * + * Note: To prevent user action while a current action completes, all widgets on the footer are disabled + * when footer actions take place, typically a button click. It is up to the action to ensure the page + * (via refresh() or CoreGUI.refresh()) or footer (via refreshTableActions) are refreshed as needed at action + * completion. Failure to do so may leave the widgets disabled. + * + * @param title the title of a modified action + * @param valueMap the map containing the tuples with name of a select item and <code>actionValue</code> which is + * then passed to <code>tableAction.executeAction()</code>; use the <code>LinkedHashMap</code> if you want to + * preserve the order of map items + * @param tableAction the tableAction object (on this object the <code>executeAction()</code> is actually invoked) + */ + public void updateTableAction(String title, Map<String, Object> valueMap, + TableAction tableAction) { + if (title == null) { + return; + } + for (TableActionInfo info : tableActions) { + if (title.equals(info.getTitle())) { + if (valueMap != null) info.setValueMap(valueMap); + if (tableAction != null) info.setAction(tableAction); + // the action listeners have to be re-added + if (isInitialized()) drawFooter(); + break; + } + } + } + public void setListGridDoubleClickHandler(DoubleClickHandler handler) { doubleClickHandler = handler; } @@ -1247,12 +1278,12 @@ public class Table<DS extends RPCDataSource> extends LocatableHLayout implements private String locatorId; private String title; private String confirmMessage; - private LinkedHashMap<String, ? extends Object> valueMap; + private Map<String, Object> valueMap; private TableAction action; private Canvas actionCanvas;
protected TableActionInfo(String locatorId, String title, String confirmMessage, - LinkedHashMap<String, ? extends Object> valueMap, TableAction action) { + Map<String, Object> valueMap, TableAction action) { this.locatorId = locatorId; this.title = title; this.confirmMessage = confirmMessage; @@ -1272,9 +1303,13 @@ public class Table<DS extends RPCDataSource> extends LocatableHLayout implements return confirmMessage; }
- public LinkedHashMap<String, ? extends Object> getValueMap() { + public Map<String, Object> getValueMap() { return valueMap; } + + public void setValueMap(Map<String, Object> valueMap) { + this.valueMap = valueMap; + }
public Canvas getActionCanvas() { return actionCanvas; diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeSearchView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeSearchView.java index bb43f26..265778b 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeSearchView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeSearchView.java @@ -89,41 +89,49 @@ public class ResourceCompositeSearchView extends ResourceSearchView { super.onInit();
// To properly filter Create Child and Import menus we need existing singleton child resources. If the - // user has creat permission and the parent type has singleton child types and creatable or importable child + // user has create permission and the parent type has singleton child types and creatable or importable child // types, perform an async call to fetch the singleton children. If we make the async call don't declare this - // instance initialized until after it completesas we must have the children before the menu buttons can be drawn. + // instance initialized until after it completes as we must have the children before the menu buttons can be drawn.
final Resource parentResource = parentResourceComposite.getResource(); ResourceType parentType = parentResource.getResourceType(); - creatableChildTypes = getCreatableChildTypes(parentType); importableChildTypes = getImportableChildTypes(parentType); hasCreatableTypes = !creatableChildTypes.isEmpty(); hasImportableTypes = !importableChildTypes.isEmpty(); - singletonChildren = new ArrayList(); // initialize to non-null + refreshSingletons(parentResource, null); + + } + + private void refreshSingletons(final Resource parentResource, final AsyncCallback<PageList<Resource>> callback) { + singletonChildren = new ArrayList<Resource>(); // initialize to non-null
- Integer[] singletonChildTypes = getSingletonChildTypes(parentType); + Integer[] singletonChildTypes = getSingletonChildTypes(parentResource.getResourceType());
if (canCreate && singletonChildTypes.length > 0 && (hasCreatableTypes || hasImportableTypes)) { ResourceCriteria criteria = new ResourceCriteria(); criteria.addFilterParentResourceId(parentResource.getId()); criteria.addFilterResourceTypeIds(singletonChildTypes); - GWTServiceLookup.getResourceService().findResourcesByCriteria(criteria, - new AsyncCallback<PageList<Resource>>() { - - @Override - public void onSuccess(PageList<Resource> result) { - singletonChildren = result; - initialized = true; + GWTServiceLookup.getResourceService().findResourcesByCriteria(criteria, new AsyncCallback<PageList<Resource>>() { + + @Override + public void onSuccess(PageList<Resource> result) { + singletonChildren = result; + initialized = true; + if (callback != null) { + callback.onSuccess(result); } + }
- @Override - public void onFailure(Throwable caught) { - Log.error("Failed to load child resources for [" + parentResource + "]", caught); - initialized = true; + @Override + public void onFailure(Throwable caught) { + Log.error("Failed to load child resources for [" + parentResource + "]", caught); + initialized = true; + if (callback != null) { + callback.onFailure(caught); } - }); - + } + }); } else { initialized = true; } @@ -196,34 +204,38 @@ public class ResourceCompositeSearchView extends ResourceSearchView { } });
- addImportAndCreateButtons(); + addImportAndCreateButtons(false);
super.configureTable(); }
@SuppressWarnings("unchecked") - private void addImportAndCreateButtons() { + private void addImportAndCreateButtons(boolean override) {
final Resource parentResource = parentResourceComposite.getResource(); ResourceType parentType = parentResource.getResourceType();
// Create Child Menu and Manual Import Menu if (canCreate && (hasCreatableTypes || hasImportableTypes)) { - if (hasCreatableTypes) { Map<String, ResourceType> displayNameMap = getDisplayNames(creatableChildTypes); LinkedHashMap<String, ResourceType> createTypeValueMap = new LinkedHashMap<String, ResourceType>( displayNameMap); removeExistingSingletons(singletonChildren, createTypeValueMap); - addTableAction(extendLocatorId("CreateChild"), MSG.common_button_create_child(), null, - createTypeValueMap, new AbstractTableAction(TableActionEnablement.ALWAYS) { - public void executeAction(ListGridRecord[] selection, Object actionValue) { - ResourceFactoryCreateWizard.showCreateWizard(parentResource, (ResourceType) actionValue); - // we can refresh the table buttons immediately since the wizard is a dialog, the - // user can't access enabled buttons anyway. - ResourceCompositeSearchView.this.refreshTableInfo(); - } - }); + AbstractTableAction createAction = new AbstractTableAction(TableActionEnablement.ALWAYS) { + public void executeAction(ListGridRecord[] selection, Object actionValue) { + ResourceFactoryCreateWizard.showCreateWizard(parentResource, (ResourceType) actionValue); + // we can refresh the table buttons immediately since the wizard is a dialog, the + // user can't access enabled buttons anyway. + ResourceCompositeSearchView.this.refreshTableInfo(); + } + }; + if (override) { + updateTableAction(MSG.common_button_create_child(), createTypeValueMap, createAction); + } else { + addTableAction(extendLocatorId("CreateChild"), MSG.common_button_create_child(), null, + createTypeValueMap, createAction); + } }
if (hasImportableTypes) { @@ -231,18 +243,23 @@ public class ResourceCompositeSearchView extends ResourceSearchView { LinkedHashMap<String, ResourceType> importTypeValueMap = new LinkedHashMap<String, ResourceType>( displayNameMap); removeExistingSingletons(singletonChildren, importTypeValueMap); - addTableAction(extendLocatorId("Import"), MSG.common_button_import(), null, importTypeValueMap, - new AbstractTableAction(TableActionEnablement.ALWAYS) { - public void executeAction(ListGridRecord[] selection, Object actionValue) { - ResourceFactoryImportWizard.showImportWizard(parentResource, (ResourceType) actionValue); - // we can refresh the table buttons immediately since the wizard is a dialog, the - // user can't access enabled buttons anyway. - ResourceCompositeSearchView.this.refreshTableInfo(); - } - }); + AbstractTableAction importAction = new AbstractTableAction(TableActionEnablement.ALWAYS) { + public void executeAction(ListGridRecord[] selection, Object actionValue) { + ResourceFactoryImportWizard.showImportWizard(parentResource, (ResourceType) actionValue); + // we can refresh the table buttons immediately since the wizard is a dialog, the + // user can't access enabled buttons anyway. + ResourceCompositeSearchView.this.refreshTableInfo(); + } + }; + if (override) { + updateTableAction(MSG.common_button_import(), importTypeValueMap, importAction); + } else { + addTableAction(extendLocatorId("Import"), MSG.common_button_import(), null, importTypeValueMap, + importAction); + } }
- } else { + } else if (!override) { if (!canCreate && hasCreatableTypes) { addTableAction(extendLocatorId("CreateChild"), MSG.common_button_create_child(), new AbstractTableAction(TableActionEnablement.NEVER) { @@ -261,6 +278,7 @@ public class ResourceCompositeSearchView extends ResourceSearchView { } } } +
private void removeExistingSingletons(List<Resource> singletonChildren, Map<String, ResourceType> displayNameMap) {
@@ -359,5 +377,23 @@ public class ResourceCompositeSearchView extends ResourceSearchView { return new ResourceCompositeSearchView(locatorId, parentResourceComposite, new Criteria("parentId", String.valueOf(parentResourceComposite.getResource().getId())), MSG.view_tabs_common_child_resources()); } + + @Override + public void refresh() { + refreshSingletons(parentResourceComposite.getResource(), new AsyncCallback<PageList<Resource>>() { + + @Override + public void onSuccess(PageList<Resource> result) { + addImportAndCreateButtons(true); + ResourceCompositeSearchView.super.refresh(); + } + + @Override + public void onFailure(Throwable caught) { + ResourceCompositeSearchView.super.refresh(); + } + }); + + }
}
commit c6c1e7819fbd8f667649223e12355e66ddd33252 Author: Stefan Negrea snegrea@redhat.com Date: Wed Aug 29 03:06:38 2012 -0500
[BZ 852632] Remove allow-direct-connections-only property from configuration to prevent sending the value to the application server. If this property is not left undefined, the configuration file for the server becomes invalid if the user attempts to use discovery-group-name.
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 01618e2..46b3084 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 @@ -4714,7 +4714,6 @@ <metric property="started" dataType="trait" description="Whether the cluster connection is started."/>
<resource-configuration> - <c:simple-property name="allow-direct-connections-only" required="false" type="boolean" readOnly="true" defaultValue="false" description="Whether, if a node learns of the existence of a node that is more than 1 hop away, we do not create a bridge for direct cluster connection. Only relevant if 'static-connectors' is defined. The default value is false."/> <c:simple-property name="call-timeout" required="false" type="long" readOnly="true" defaultValue="30000" description="The timeout (in ms) for remote calls made by the cluster connection. The default value is 30000."/> <c:simple-property name="check-period" required="false" type="long" readOnly="true" defaultValue="30000" description="The period (in milliseconds) between client failure check. The default value is 30000."/> <c:simple-property name="cluster-connection-address" required="true" type="string" readOnly="true" description="Each cluster connection only applies to messages sent to an address that starts with this value."/> @@ -6843,7 +6842,6 @@ </plugin-configuration>
<resource-configuration> - <c:simple-property name="allow-direct-connections-only" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether, if a node learns of the existence of a node that is more than 1 hop away, we do not create a bridge for direct cluster connection. Only relevant if 'static-connectors' is defined. The default value is false."/> <c:simple-property name="call-timeout" required="false" type="long" readOnly="false" defaultValue="30000" description="The timeout (in ms) for remote calls made by the cluster connection. The default value is 30000."/> <c:simple-property name="check-period" required="false" type="long" readOnly="false" defaultValue="30000" description="The period (in milliseconds) between client failure check. The default value is 30000."/> <c:simple-property name="cluster-connection-address" required="true" type="string" readOnly="false" description="Each cluster connection only applies to messages sent to an address that starts with this value."/> @@ -12948,7 +12946,6 @@ <metric property="started" dataType="trait" description="Whether the cluster connection is started."/>
<resource-configuration> - <c:simple-property name="allow-direct-connections-only" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether, if a node learns of the existence of a node that is more than 1 hop away, we do not create a bridge for direct cluster connection. Only relevant if 'static-connectors' is defined. The default value is false."/> <c:simple-property name="call-timeout" required="false" type="long" readOnly="false" defaultValue="30000" description="The timeout (in ms) for remote calls made by the cluster connection. The default value is 30000."/> <c:simple-property name="check-period" required="false" type="long" readOnly="false" defaultValue="30000" description="The period (in milliseconds) between client failure check. The default value is 30000."/> <c:simple-property name="cluster-connection-address" required="true" type="string" readOnly="false" description="Each cluster connection only applies to messages sent to an address that starts with this value."/>
commit 74aa0f7f9b0f2dd1044450d924f61b3faee78c27 Author: Stefan Negrea snegrea@redhat.com Date: Wed Aug 29 02:52:42 2012 -0500
[BZ 852552] Updates to set correctly all the data-source and xa-data-source properties that do not support null values and cannot be undefined.
While these properties look undefined in the server, they cannot undefined or set to null at any point in time. The application server makes use of the default value at all times.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DatasourceComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DatasourceComponent.java index a4efae1..5011120 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DatasourceComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DatasourceComponent.java @@ -13,6 +13,9 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.domain.measurement.MeasurementDataNumeric; import org.rhq.core.domain.measurement.MeasurementDataTrait; import org.rhq.core.domain.measurement.MeasurementReport; @@ -174,6 +177,27 @@ public class DatasourceComponent extends BaseComponent<BaseComponent<?>> impleme } }
+ @Override + public void updateResourceConfiguration(ConfigurationUpdateReport report) { + Configuration config = report.getConfiguration(); + ConfigurationDefinition configDef = context.getResourceType().getResourceConfigurationDefinition(); + + //These properties cannot be undefined once set. + //Also the AS7 server does not accept null values even if the properties are still unset. + replaceWithDefaultIfNull("max-pool-size", config, configDef); + replaceWithDefaultIfNull("min-pool-size", config, configDef); + replaceWithDefaultIfNull("pool-prefill", config, configDef); + replaceWithDefaultIfNull("pool-use-strict-min", config, configDef); + replaceWithDefaultIfNull("blocking-timeout-wait-millis", config, configDef); + replaceWithDefaultIfNull("idle-timeout-minutes", config, configDef); + replaceWithDefaultIfNull("background-validation-millis", config, configDef); + replaceWithDefaultIfNull("background-validation-minutes", config, configDef); + replaceWithDefaultIfNull("background-validation", config, configDef); + + ConfigurationWriteDelegate delegate = new ConfigurationWriteDelegate(configDef, getASConnection(), address); + delegate.updateResourceConfiguration(report); + } + private void getRCAsMetric(MeasurementReport report, MeasurementScheduleRequest request) { Operation op = new ReadAttribute(getAddress(), request.getName()); Result res = getASConnection().execute(op); @@ -204,4 +228,23 @@ public class DatasourceComponent extends BaseComponent<BaseComponent<?>> impleme
return trait; } + + /** + * Replace the value configured by the user with the default value from the resource descriptor if + * the value to be sent to the server is null or empty. + * + * @param propertyName property name + * @param config configuration update + * @param configDef configuration definition + */ + private void replaceWithDefaultIfNull(String propertyName, Configuration config, ConfigurationDefinition configDef) { + PropertyDefinitionSimple propertyDefinition = configDef.getPropertyDefinitionSimple(propertyName); + + if (propertyDefinition != null) { + String propertyValue = config.getSimpleValue(propertyName); + if (propertyValue == null || propertyValue.isEmpty()) { + config.put(new PropertySimple(propertyName, propertyDefinition.getDefaultValue())); + } + } + } } 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 29ef057..01618e2 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 @@ -412,10 +412,10 @@ <c:simple-property name="use-java-context" type="boolean" readOnly="false" required="false" default="true" description="Setting this to false will bind the DataSource into global JNDI;"/> <c:simple-property name="enabled" type="boolean" readOnly="true" required="false" description="Specifies if the datasource should be enabled"/> <c:simple-property name="jta" type="boolean" readOnly="false" required="false" default="true" description="Enable JTA integration"/> - <c:simple-property name="max-pool-size" type="integer" readOnly="false" required="false" description="The max-pool-size element indicates the maximum number of connections for a pool. No more connections will be created in each sub-pool."/> - <c:simple-property name="min-pool-size" type="integer" readOnly="false" required="false" description="The min-pool-size element indicates the minimum number of connections a pool should hold. These are not created until a Subject is known from a request for a connection."/> - <c:simple-property name="pool-prefill" type="boolean" readOnly="false" required="false" default="false" description="Whether to attempt to prefill the connection pool. Changing this value require a server restart."/> - <c:simple-property name="pool-use-strict-min" type="boolean" readOnly="false" required="false" default="false" description="Define if the min-pool-size should be considered a strictly."/> + <c:simple-property name="max-pool-size" type="integer" readOnly="false" required="false" defaultValue="20" description="The max-pool-size element indicates the maximum number of connections for a pool. No more connections will be created in each sub-pool."/> + <c:simple-property name="min-pool-size" type="integer" readOnly="false" required="false" defaultValue="0" description="The min-pool-size element indicates the minimum number of connections a pool should hold. These are not created until a Subject is known from a request for a connection."/> + <c:simple-property name="pool-prefill" type="boolean" readOnly="false" required="false" defaultValue="false" description="Whether to attempt to prefill the connection pool. Changing this value require a server restart."/> + <c:simple-property name="pool-use-strict-min" type="boolean" readOnly="false" required="false" defaultValue="false" description="Define if the min-pool-size should be considered a strictly."/> <c:simple-property name="security-domain" required="false" type="string" readOnly="false" description="Indicates Subject (from security domain) are used to distinguish connections in the pool. The content of the security-domain is the name of the JAAS security manager that will handleauthentication. This name correlates to the JAAS login-config.xml descriptor application-policy/name attribute."/> <c:simple-property name="reauth-plugin-class-name" required="false" type="string" readOnly="false" description="re-authentication plugin implementation provided for specific purpose (i.e vendor)"/> <!-- @@ -433,7 +433,7 @@ </c:simple-property>
<c:simple-property name="allow-multiple-users" type="boolean" required="false" readOnly="false" description="Specifies if multiple users will access the datasource through the getConnection(user, password) method and hence if the internal pool type should account for that"/> - <c:simple-property name="prepared-statements-cacheSize" type="long" readOnly="false" required="false" description="The number of prepared statements per connection in an LRU cache"/> + <c:simple-property name="prepared-statements-cache-size" type="long" readOnly="false" required="false" description="The number of prepared statements per connection in an LRU cache"/> <c:simple-property name="share-prepared-statements" type="boolean" readOnly="false" required="false" default="false" description="Whether to share prepare statements, i.e. whether asking for same statement twice without closing uses the same underlying prepared statement"/> <c:simple-property name="track-statements" type="string" readOnly="false" required="false" description="Whether to check for unclosed statements when a connection is returned to the pool and result sets are closed when a statement is closed/return to the prepared statement cache. valid values are: false - do not track statements and results true - track statements and result sets and warn when they are not closed nowarn - track statements but do no warn about them being unclosed"> <c:property-options> @@ -444,8 +444,8 @@ </c:simple-property> <c:simple-property name="allocation-retry" type="integer" readOnly="false" required="false" description="The allocation retry element indicates the number of times that allocating a connection should be tried before throwing an exception."/> <c:simple-property name="allocation-retry-wait-millis" type="long" readOnly="false" required="false" description="Indicates the time in milliseconds to wait between retrying to allocate a connection."/> - <c:simple-property name="blocking-timeout-wait-millis" type="long" readOnly="false" required="false" description="The blocking-timeout-millis element indicates the maximum time in milliseconds to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for a permit for a connection, and will never throw an exception if creating a new connection takes an inordinately long time."/> - <c:simple-property name="idle-timeout-minutes" type="long" readOnly="false" required="false" description="The idle-timeout-minutes elements indicates 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 1/2 the smallest idle-timeout-minutes of any pool. Changing this value require a server restart."/> + <c:simple-property name="blocking-timeout-wait-millis" type="long" readOnly="false" required="false" defaultValue="30000" description="The blocking-timeout-millis element indicates the maximum time in milliseconds to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for a permit for a connection, and will never throw an exception if creating a new connection takes an inordinately long time."/> + <c:simple-property name="idle-timeout-minutes" type="long" readOnly="false" required="false" defaultValue="15" description="The idle-timeout-minutes elements indicates 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 1/2 the smallest idle-timeout-minutes of any pool. Changing this value require a server restart."/> <c:simple-property name="query-timeout" type="long" readOnly="false" required="false" description="Any configured query timeout in seconds The default is no timeout"/> <c:simple-property name="use-try-lock" type="long" readOnly="false" required="false" description="Any configured timeout for internal locks on the resource adapter objects in seconds"/> <c:simple-property name="set-tx-query-timeout" type="boolean" readOnly="false" required="false" default="false" description="Whether to set the query timeout based on the time remaining until transaction timeout, any configured query timeout will be used if there is no transaction."/> @@ -462,8 +462,8 @@ <c:simple-property name="exception-sorter-class-name" type="string" readOnly="false" required="false" description="An org.jboss.jca.adapters.jdbc.ExceptionSorter that provides a boolean isExceptionFatal(SQLException e) method to validate is an exception should be broadcast to all javax.resource.spi.ConnectionEventListener as a connectionErrorOccurred"/> <c:simple-property name="stale-connection-checker-class-name" type="string" readOnly="false" required="false" description="An org.jboss.jca.adapters.jdbc.StaleConnectionChecker that provides a boolean isStaleConnection(SQLException e) method which if it it returns true will wrap the exception in an org.jboss.jca.adapters.jdbc.StaleConnectionException"/> <c:simple-property name="valid-connection-checker-class-name" type="string" readOnly="false" required="false" description="An org.jboss.jca.adapters.jdbc.ValidConnectionChecker that provides a SQLException isValidConnection(Connection e) method to validate is a connection is valid. An exception means the connection is destroyed. This overrides the check-valid-connection-sql when present."/> - <c:simple-property name="background-validation-millis" type="long" readOnly="false" required="false" description="The background-validation-minutes element specifies the amount of time, in minutes, that background validation will run. Changing this value require a server restart."/> - <c:simple-property name="background-validation" type="boolean" readOnly="false" required="false" default="false" description="An element to specify that connections should be validated on a background thread versus being validated prior to use. Changing this value require a server restart."/> + <c:simple-property name="background-validation-millis" type="long" readOnly="false" required="false" defaultValue="600000" description="The background-validation-minutes element specifies the amount of time, in minutes, that background validation will run. Changing this value require a server restart."/> + <c:simple-property name="background-validation" type="boolean" readOnly="false" required="false" defaultValue="false" description="An element to specify that connections should be validated on a background thread versus being validated prior to use. Changing this value require a server restart."/> <c:simple-property name="use-fast-fail" type="boolean" readOnly="false" required="false" description="Whether fail a connection allocation on the first connection if it is invalid (true) or keep trying until the pool is exhausted of all potential connections (false)"/> <c:simple-property name="validate-on-match" type="boolean" readOnly="false" required="false" default="false" description="The validate-on-match element indicates whether or not connection level validation should be done when a connection factory attempts to match a managed connection for a given set. This is typically exclusive to the use of background validation"/> <c:simple-property name="spy" type="boolean" readOnly="false" required="false" defaultValue="false" description="whatever spy or not the jdbc connection"/> @@ -515,7 +515,7 @@ </c:property-options> </c:simple-property>
- <c:simple-property name="prepared-statements-cacheSize" type="long" readOnly="true" required="false" description="The number of prepared statements per connection in an LRU cache"/> + <c:simple-property name="prepared-statements-cache-size" type="long" readOnly="true" required="false" description="The number of prepared statements per connection in an LRU cache"/> <c:simple-property name="share-prepared-statements" type="boolean" readOnly="true" required="false" description="Whether to share prepare statements, i.e. whether asking for same statement twice without closing uses the same underlying prepared statement"/> <c:simple-property name="track-statements" type="string" readOnly="true" required="false" description="Whether to check for unclosed statements when a connection is returned to the pool and result sets are closed when a statement is closed/return to the prepared statement cache. valid values are: false - do not track statements and results true - track statements and result sets and warn when they are not closed nowarn - track statements but do no warn about them being unclosed"/> <c:simple-property name="allocation-retry" type="integer" readOnly="true" required="false" description="The allocation retry element indicates the number of times that allocating a connection should be tried before throwing an exception."/> @@ -570,10 +570,10 @@ <c:simple-property name="url-selector-strategy-class-name" required="false" type="string" readOnly="true" description="A class that implements org.jboss.jca.adapters.jdbc.URLSelectorStrategy"/> <c:simple-property name="use-java-context" required="false" type="boolean" readOnly="true" description="Setting this to false will bind the DataSource into global JNDI;"/> <c:simple-property name="enabled" required="false" type="boolean" readOnly="true" description="Specifies if the datasource should be enabled"/> - <c:simple-property name="max-pool-size" required="false" type="integer" readOnly="false" description="The max-pool-size element indicates the maximum number of connections for a pool. No more connections will be created in each sub-pool."/> - <c:simple-property name="min-pool-size" required="false" type="integer" readOnly="false" description="The min-pool-size element indicates the minimum number of connections a pool should hold. These are not created until a Subject is known from a request for a connection."/> - <c:simple-property name="pool-prefill" required="false" type="boolean" readOnly="false" description="Whether to attempt to prefill the connection pool. Changing this value require a server restart."/> - <c:simple-property name="pool-use-strict-min" required="false" type="boolean" readOnly="false" description="Define if the min-pool-size should be considered a strictly."/> + <c:simple-property name="max-pool-size" required="false" type="integer" readOnly="false" defaultValue="20" description="The max-pool-size element indicates the maximum number of connections for a pool. No more connections will be created in each sub-pool."/> + <c:simple-property name="min-pool-size" required="false" type="integer" readOnly="false" defaultValue="0" description="The min-pool-size element indicates the minimum number of connections a pool should hold. These are not created until a Subject is known from a request for a connection."/> + <c:simple-property name="pool-prefill" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether to attempt to prefill the connection pool. Changing this value require a server restart."/> + <c:simple-property name="pool-use-strict-min" required="false" type="boolean" readOnly="false" defaultValue="false" description="Define if the min-pool-size should be considered a strictly."/> <c:simple-property name="interleaving" required="false" type="boolean" readOnly="true" description="An element to enable interleaving for XA connection factories"/> <c:simple-property name="no-tx-separate-pool" required="false" type="boolean" readOnly="true" description="Oracle does not like XA connections getting used both inside and outside a JTA transaction. To workaround the problem you can create separate sub-pools for the different context"/> <c:simple-property name="pad-xid" required="false" type="boolean" readOnly="true" description="Should the Xid be padded"/> @@ -596,13 +596,13 @@ <c:option value="EntirePool"/> </c:property-options> </c:simple-property> - <c:simple-property name="prepared-statements-cacheSize" required="false" type="long" readOnly="true" description="The number of prepared statements per connection in an LRU cache"/> + <c:simple-property name="prepared-statements-cache-size" required="false" type="long" readOnly="true" description="The number of prepared statements per connection in an LRU cache"/> <c:simple-property name="share-prepared-statements" required="false" type="boolean" readOnly="true" description="Whether to share prepare statements, i.e. whether asking for same statement twice without closing uses the same underlying prepared statement"/> <c:simple-property name="track-statements" required="false" type="string" readOnly="true" description="Whether to check for unclosed statements when a connection is returned to the pool and result sets are closed when a statement is closed/return to the prepared statement cache. valid values are: false - do not track statements and results true - track statements and result sets and warn when they are not closed nowarn - track statements but do no warn about them being unclosed"/> <c:simple-property name="allocation-retry" required="false" type="integer" readOnly="true" description="The allocation retry element indicates the number of times that allocating a connection should be tried before throwing an exception."/> <c:simple-property name="allocation-retry-wait-millis" required="false" type="long" readOnly="true" description="he allocation retry wait millis element indicates the time in milliseconds to wait between retrying to allocate a connection."/> - <c:simple-property name="blocking-timeout-wait-millis" required="false" type="long" readOnly="false" description="The blocking-timeout-millis element indicates the maximum time in milliseconds to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for a permit for a connection, and will never throw an exception if creating a new connection takes an inordinately long time."/> - <c:simple-property name="idle-timeout-minutes" required="false" type="long" readOnly="false" description="The idle-timeout-minutes elements indicates 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 1/2 the smallest idle-timeout-minutes of any pool. Changing this value require a server restart."/> + <c:simple-property name="blocking-timeout-wait-millis" required="false" type="long" readOnly="false" defaultValue="30000" description="The blocking-timeout-millis element indicates the maximum time in milliseconds to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for a permit for a connection, and will never throw an exception if creating a new connection takes an inordinately long time."/> + <c:simple-property name="idle-timeout-minutes" required="false" type="long" readOnly="false" defaultValue="15" description="The idle-timeout-minutes elements indicates 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 1/2 the smallest idle-timeout-minutes of any pool. Changing this value require a server restart."/> <c:simple-property name="query-timeout" required="false" type="long" readOnly="true" description="Any configured query timeout in seconds The default is no timeout"/> <c:simple-property name="use-try-lock" required="false" type="long" readOnly="true" description="Any configured timeout for internal locks on the resource adapter objects in seconds"/> <c:simple-property name="set-tx-query-timeout" required="false" type="boolean" readOnly="true" description="Whether to set the query timeout based on the time remaining until transaction timeout, any configured query timeout will be used if there is no transaction."/> @@ -637,8 +637,8 @@ configuration </c:map-property> --> - <c:simple-property name="background-validation-minutes" required="false" type="long" readOnly="false" description="The background-validation-minutes element specifies the amount of time, in minutes, that background validation will run. Changing this value require a server restart."/> - <c:simple-property name="background-validation" required="false" type="boolean" readOnly="false" description="An element to specify that connections should be validated on a background thread versus being validated prior to use. Changing this value require a server restart."/> + <c:simple-property name="background-validation-minutes" required="false" type="long" readOnly="false" defaultValue="10" description="The background-validation-minutes element specifies the amount of time, in minutes, that background validation will run. Changing this value require a server restart."/> + <c:simple-property name="background-validation" required="false" type="boolean" readOnly="false" defaultValue="false" description="An element to specify that connections should be validated on a background thread versus being validated prior to use. Changing this value require a server restart."/> <c:simple-property name="use-fast-fail" required="false" type="boolean" readOnly="false" description="Whether fail a connection allocation on the first connection if it is invalid (true) or keep trying until the pool is exhausted of all potential connections (false)"/> <c:simple-property name="validate-on-match" required="false" type="boolean" readOnly="true" description="The validate-on-match element indicates whether or not connection level validation should be done when a connection factory attempts to match a managed connection for a given set. This is typically exclusive to the use of background validation"/> <c:simple-property name="xa-resource-timeout" required="false" type="integer" readOnly="true" description="Passed to XAResource.setTransactionTimeout() Default is zero which does not invoke the setter. In seconds"/> @@ -706,7 +706,7 @@ <c:option value="EntirePool"/> </c:property-options> </c:simple-property> - <c:simple-property name="prepared-statements-cacheSize" required="false" type="long" readOnly="true" description="The number of prepared statements per connection in an LRU cache"/> + <c:simple-property name="prepared-statements-cache-size" required="false" type="long" readOnly="true" description="The number of prepared statements per connection in an LRU cache"/> <c:simple-property name="share-prepared-statements" required="false" type="boolean" readOnly="true" description="Whether to share prepare statements, i.e. whether asking for same statement twice without closing uses the same underlying prepared statement"/> <c:simple-property name="track-statements" required="false" type="string" readOnly="true" description="Whether to check for unclosed statements when a connection is returned to the pool and result sets are closed when a statement is closed/return to the prepared statement cache. valid values are: false - do not track statements and results true - track statements and result sets and warn when they are not closed nowarn - track statements but do no warn about them being unclosed"/> <c:simple-property name="allocation-retry" required="false" type="integer" readOnly="true" description="The allocation retry element indicates the number of times that allocating a connection should be tried before throwing an exception."/>
commit e6e91058f3ac76c6458847bd66a8ee5c9c24493e Author: Stefan Negrea snegrea@redhat.com Date: Wed Aug 29 02:20:24 2012 -0500
[BZ 847674] Updated all the wait methods for reload, shutdown, and restart to have the same design. All the methods now take into account possible exceptions for the test operation sent to the application server.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java index 27b1133..98a46d2 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java @@ -241,25 +241,36 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend return startServer(); }
- protected boolean waitUntilDown(OperationResult tmp) throws InterruptedException { + protected boolean waitUntilDown() throws InterruptedException { boolean down=false; int count=0; + while (!down) { Operation op = new ReadAttribute(new Address(),"release-version"); - Result res = getASConnection().execute(op); - if (!res.isSuccess()) { // If op succeeds, server is not down - down=true; - } else if (count > 20) { - tmp.setErrorMessage("Was not able to shut down the server"); - return true; + + try{ + Result res = getASConnection().execute(op); + if (!res.isSuccess()) { // If op succeeds, server is not down + down = true; + } else if (count > 20) { + break; + } + } catch (Exception e) { + down = true; } + if (!down) { - Thread.sleep(1000); // Wait 1s + try { + Thread.sleep(1000); // Wait 1s + } catch (InterruptedException e) { + // ignore + } } count++; } - log.debug("waitUntilDown: Used " + count + " delay round(s) to shut down"); - return false; + + log.debug("waitUntilDown: Used " + count + " delay round(s) to shut down. Server down=" + down); + return down; }
/** diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java index 565add2..7ea12b9 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HostControllerComponent.java @@ -92,8 +92,11 @@ public class HostControllerComponent<T extends ResourceComponent<?>> extends Bas Result res = getASConnection().execute(op); operationResult = postProcessResult(name, res);
- waitUntilDown(operationResult); - + if (waitUntilDown()) { + operationResult.setSimpleResult("Success"); + } else { + operationResult.setErrorMessage("Was not able to shut down the server."); + } } else if (name.equals("installRhqUser")) { operationResult = installManagementUser(parameters, pluginConfiguration); } else { diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java index 573742e..778d127 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java @@ -163,39 +163,59 @@ public class StandaloneASComponent<T extends ResourceComponent<?>> extends BaseS
OperationResult operationResult = postProcessResult(name, res);
- if (name.equals("shutdown")) - waitUntilDown(operationResult); + if (name.equals("shutdown")) { + if (waitUntilDown()) { + operationResult.setSimpleResult("Success"); + } else { + operationResult.setErrorMessage("Was not able to shut down the server."); + } + }
- if (name.equals("reload")) - waitUntilReloaded(operationResult); + if (name.equals("reload")) { + if (waitUntilReloaded()) { + operationResult.setSimpleResult("Success"); + } else { + operationResult.setErrorMessage("Was not able to reload the server."); + } + }
context.getAvailabilityContext().requestAvailabilityCheck();
return operationResult; }
- private void waitUntilReloaded(OperationResult operationResult) { + private boolean waitUntilReloaded() { boolean reloaded = false; int count = 0; + while (!reloaded) { - try { - Thread.sleep(2000); // Wait 2s - } catch (InterruptedException e) { - // Ignore + Operation op = new ReadAttribute(new Address(), "release-version"); + try{ + Result res = getASConnection().execute(op); + if (res.isSuccess() && !res.isReloadRequired()) { + reloaded = true; + } else if (count > 20) { + break; + } + } catch (Exception e) { + //do absolutely nothing + //if an exception is thrown that means the server is still reloading, so consider this + //a single failed attempt, equivalent to res.isSuccess == false }
- Operation op = new ReadAttribute(new Address(), "release-version"); - Result res = getASConnection().execute(op); - if (res.isSuccess() && !res.isReloadRequired()) { - reloaded = true; - } else if (count > 20) { - operationResult.setErrorMessage("Was not able to reload the server"); - return; + if (!reloaded) { + try { + Thread.sleep(1000); // Wait 1s + } catch (InterruptedException e) { + // ignore + } } count++; } - log.debug("waitUntilReloaded: Used " + count + " delay round(s) to reload"); - return; + + log.debug("waitUntilReloaded: Used " + count + " delay round(s) to reload. Reload=" + reloaded); + + return reloaded; }
@Override
commit 96602db100b087e36016b1aa6a2e39780b583898 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 23:33:45 2012 -0500
[BZ 852552] Adding special validation for the transaction subsystem.
The special case for this subsystem:
If [process-id-uuid] == true then do not send updates for [process-id-socket-binding], this property will be undefined by the AS7 on the next reload/restart
If [process-id-uuid] == false then allow AS7 to perform property validation * If [process-id-uuid] == false then send [process-id-socket-binding] value and allow AS7 to perform property validation
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TransactionsComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TransactionsComponent.java new file mode 100644 index 0000000..102118b --- /dev/null +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TransactionsComponent.java @@ -0,0 +1,62 @@ +/* + * RHQ Management Platform + * Copyright 2012, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.rhq.modules.plugins.jbossas7; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.rhq.core.pluginapi.inventory.ResourceComponent; + +/** + * Support for transactions subsystem configuration updates. + * + * The special case for this subsystem: + * + * If [process-id-uuid] == true then do not send updates for [process-id-socket-binding], this property + * will be undefined by the AS7 on the next server reload/restart + * + * If [process-id-uuid] == false then send [process-id-socket-binding] value and + * allow AS7 to perform property validation + * + * + * @author Stefan Negrea + */ +public class TransactionsComponent extends BaseComponent<ResourceComponent<?>> { + + @Override + public void updateResourceConfiguration(ConfigurationUpdateReport report) { + Configuration config = report.getConfiguration(); + ConfigurationDefinition configDef = context.getResourceType().getResourceConfigurationDefinition(); + + boolean processIdUuid = Boolean.valueOf(config.getSimpleValue("process-id-uuid")); + if (processIdUuid == true) { + //Do not even send the updates for [process-id-socket-binding] because the AS7 will + //undefine it during the next reload/restart. + //Also, sending null for [process-id-socket-binding] with [process-id-uuid] == true causes + //a validation error on the server. + configDef.getPropertyDefinitions().remove("process-id-socket-binding"); + config.remove("process-id-socket-binding"); + } + + ConfigurationWriteDelegate delegate = new ConfigurationWriteDelegate(configDef, getASConnection(), address); + delegate.updateResourceConfiguration(report); + } +} 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 0f150a4..29ef057 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 @@ -8338,7 +8338,7 @@
<service name="Transactions Subsystem (Standalone)" discovery="SubsystemDiscovery" - class="BaseComponent" + class="TransactionsComponent" singleton="true" description="The transactions subsystem.">
@@ -8460,7 +8460,7 @@
<service name="Transactions Subsystem (Profile)" discovery="SubsystemDiscovery" - class="BaseComponent" + class="TransactionsComponent" singleton="true" description="The transactions subsystem.">
@@ -8516,7 +8516,7 @@
<service name="Transactions Subsystem (Managed)" discovery="SubsystemDiscovery" - class="BaseComponent" + class="TransactionsComponent" singleton="true" description="The transactions subsystem.">
commit b8d890aaf85b9d3f74eb60d1bad32af02d030759 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 23:01:08 2012 -0500
[BZ 852552] Add two resource types to the list of ignored resources for this integration test. Both of these resources have special requirements with regards to configuration updates.
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java index aad8739..824162a 100644 --- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java +++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java @@ -86,6 +86,9 @@ public class ResourcesStandaloneServerTest extends AbstractJBossAS7PluginTest { //will revisit after BZ 826542 is resolved // ignoredResources.add("Authentication (Classic)");
+ ignoredResources.add("Memory Pool"); + ignoredResources.add("Periodic Rotating File Handler"); + Resource platform = this.pluginContainer.getInventoryManager().getPlatform(); Resource server = getResourceByTypeAndKey(platform, StandaloneServerComponentTest.RESOURCE_TYPE, StandaloneServerComponentTest.RESOURCE_KEY);
commit a31197fcd63548c6e49606525b9938c123e5ffb2 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 22:59:02 2012 -0500
[BZ 852552] Update socket binding group to not send at all port-offset for non-standalone servers.
Just setting port-offset to null was not enough since now all the unset properties are sent to the AS7 server. The property and property definition are now removed from updates sent host controllers.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SocketBindingGroupComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SocketBindingGroupComponent.java index 00d28ca..573db2e 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SocketBindingGroupComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SocketBindingGroupComponent.java @@ -2,6 +2,7 @@ package org.rhq.modules.plugins.jbossas7;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertySimple; +import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
@@ -29,12 +30,14 @@ public class SocketBindingGroupComponent extends BaseComponent implements Config public void updateResourceConfiguration(ConfigurationUpdateReport report) {
Configuration config = report.getConfiguration(); + ConfigurationDefinition configDef = context.getResourceType().getResourceConfigurationDefinition(); + if (!(context.getParentResourceComponent() instanceof StandaloneASComponent)) { // TODO what about managed servers - config.put(new PropertySimple("port-offset",null)); + configDef.getPropertyDefinitions().remove("port-offset"); + config.remove("port-offset"); }
- super.updateResourceConfiguration(report); - - + ConfigurationWriteDelegate delegate = new ConfigurationWriteDelegate(configDef, getASConnection(), address); + delegate.updateResourceConfiguration(report); } }
commit 91aaaf71e585022ca85f62e371a7d63ae554ff6d Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 22:55:05 2012 -0500
[BZ 852552] Create a separate distributed cache definition because this resource contains addtional properties not available for invalidation and replicate caches.
The diferrence between these caches was obvious only after the updates to always send unset properties. All these extra properties (which are null) were sent to the server causing failures for caches that do not have them in their definition.
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 81ddfe9..0f150a4 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 @@ -2002,7 +2002,7 @@ class="TemplatedComponent">
<plugin-configuration> - <c:simple-property name="path" readOnly="true" default="distributed-cache|invalidation-cache|replicated-cache"/> + <c:simple-property name="path" readOnly="true" default="invalidation-cache|replicated-cache"/> </plugin-configuration>
<resource-configuration> @@ -2031,30 +2031,64 @@ <c:simple-property name="queue-flush-interval" required="false" type="long" readOnly="true" default="10" description="In ASYNC mode, this attribute controls how often the asynchronous thread used to flush the replication queue runs. This should be a positive integer which represents thread wakeup time in milliseconds."/> <c:simple-property name="remote-timeout" required="false" type="long" readOnly="true" default="17500" description="In SYNC mode, the timeout (in ms) used to wait for an acknowledgment when making a remote call, after which the call is aborted and an exception is thrown."/> <c:simple-property name="async-marshalling" required="false" type="boolean" readOnly="true" defaultValue="false" description="If enabled, this will cause marshalling of entries to be performed asynchronously. The default value is false."/> - <c:simple-property name="l1-lifespan" required="false" type="long" readOnly="true" defaultValue="600000" description="Maximum lifespan of an entry placed in the L1 cache. This element configures the L1 cache behavior in 'distributed' caches instances. In any other cache modes, this element is ignored. The default value is 600000."/> <c:simple-property name="module" required="false" type="string" readOnly="true" description="The module whose class loader should be used when building this cache's configuration."/> - <c:simple-property name="owners" required="false" type="integer" readOnly="true" defaultValue="2" description="Number of cluster-wide replicas for each cache entry. The default value is 2."/> - <c:simple-property name="virtual-nodes" required="false" type="integer" readOnly="true" defaultValue="1" description="Controls the number of virtual nodes per 'real' node. If numVirtualNodes is 1, then virtual nodes are disabled. The topology aware consistent hash must be used if you wish to take advantage of virtual nodes. A default of 1 is used. The default value is 1."/>
- <c:simple-property name="__type" displayName="Type of cache" required="true" readOnly="true" default="local-cache" description="Type of cache"> + <c:simple-property name="__type" displayName="Type of cache" required="true" readOnly="true" default="invalidation-cache" description="Type of cache"> <c:property-options> <c:option value="invalidation-cache"/> - <c:option value="distributed-cache"/> <c:option value="replicated-cache"/> </c:property-options> </c:simple-property> <c:template name="Invalidation Cache" description="Invalidation Cache"> <c:simple-property name="__type" readOnly="true" default="invalidation-cache"/> </c:template> - <c:template name="Distributed Cache" description="Distributed Cache"> - <c:simple-property name="__type" readOnly="true" default="distributed-cache"/> - </c:template> <c:template name="Replicated Cache" description="Replicated Cache"> <c:simple-property name="__type" readOnly="true" default="replicated-cache"/> </c:template> </resource-configuration> </service>
+ <service name="Distributed Cache (Managed Server)" + discovery="SubsystemDiscovery" + class="BaseComponent"> + + <plugin-configuration> + <c:simple-property name="path" readOnly="true" default="distributed-cache"/> + </plugin-configuration> + + <resource-configuration> + <c:simple-property name="start" required="false" type="string" readOnly="true" default="LAZY" description="The cache start mode, which can be EAGER (immediate start) or LAZY (on-demand start)."> + <c:property-options> + <c:option value="LAZY"/> + <c:option value="EAGER"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="batching" required="false" type="boolean" readOnly="true" default="false" description="If enabled, the invocation batching API will be made available for this cache."/> + <c:simple-property name="indexing" required="false" type="string" readOnly="true" default="NONE" description="If enabled, entries will be indexed when they are added to the cache. Indexes will be updated as entries change or are removed."> + <c:property-options> + <c:option value="NONE"/> + <c:option value="LOCAL"/> + <c:option value="ALL"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="jndi-name" required="false" type="string" readOnly="true" description="The jndi-name to which to bind this cache instance."/> + <c:simple-property name="mode" required="false" type="string" readOnly="true" default="SYNC" description="Sets the clustered cache mode, ASYNC for asynchronous operation, or SYNC for synchronous operation."> + <c:property-options> + <c:option value="SYNC"/> + <c:option value="ASYNC"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="queue-size" required="false" type="integer" readOnly="true" default="0" description="In ASYNC mode, this attribute can be used to trigger flushing of the queue when it reaches a specific threshold."/> + <c:simple-property name="queue-flush-interval" required="false" type="long" readOnly="true" default="10" description="In ASYNC mode, this attribute controls how often the asynchronous thread used to flush the replication queue runs. This should be a positive integer which represents thread wakeup time in milliseconds."/> + <c:simple-property name="remote-timeout" required="false" type="long" readOnly="true" default="17500" description="In SYNC mode, the timeout (in ms) used to wait for an acknowledgment when making a remote call, after which the call is aborted and an exception is thrown."/> + <c:simple-property name="async-marshalling" required="false" type="boolean" readOnly="true" defaultValue="false" description="If enabled, this will cause marshalling of entries to be performed asynchronously. The default value is false."/> + <c:simple-property name="l1-lifespan" required="false" type="long" readOnly="true" defaultValue="600000" description="Maximum lifespan of an entry placed in the L1 cache. This element configures the L1 cache behavior in 'distributed' caches instances. In any other cache modes, this element is ignored. The default value is 600000."/> + <c:simple-property name="module" required="false" type="string" readOnly="true" description="The module whose class loader should be used when building this cache's configuration."/> + <c:simple-property name="owners" required="false" type="integer" readOnly="true" defaultValue="2" description="Number of cluster-wide replicas for each cache entry. The default value is 2."/> + <c:simple-property name="virtual-nodes" required="false" type="integer" readOnly="true" defaultValue="1" description="Controls the number of virtual nodes per 'real' node. If numVirtualNodes is 1, then virtual nodes are disabled. The topology aware consistent hash must be used if you wish to take advantage of virtual nodes. A default of 1 is used. The default value is 1."/> + </resource-configuration> + </service> + <service name="Local Cache (Managed Server)" discovery="SubsystemDiscovery" class="BaseComponent" @@ -11331,7 +11365,7 @@ creationDataType="configuration">
<plugin-configuration> - <c:simple-property name="path" readOnly="true" default="distributed-cache|invalidation-cache|replicated-cache"/> + <c:simple-property name="path" readOnly="true" default="invalidation-cache|replicated-cache"/> </plugin-configuration>
<resource-configuration> @@ -11360,30 +11394,66 @@ <c:simple-property name="queue-flush-interval" required="false" type="long" readOnly="false" default="10" description="In ASYNC mode, this attribute controls how often the asynchronous thread used to flush the replication queue runs. This should be a positive integer which represents thread wakeup time in milliseconds."/> <c:simple-property name="remote-timeout" required="false" type="long" readOnly="false" default="17500" description="In SYNC mode, the timeout (in ms) used to wait for an acknowledgment when making a remote call, after which the call is aborted and an exception is thrown."/> <c:simple-property name="async-marshalling" required="false" type="boolean" readOnly="false" defaultValue="false" description="If enabled, this will cause marshalling of entries to be performed asynchronously. The default value is false."/> - <c:simple-property name="l1-lifespan" required="false" type="long" readOnly="false" defaultValue="600000" description="Maximum lifespan of an entry placed in the L1 cache. This element configures the L1 cache behavior in 'distributed' caches instances. In any other cache modes, this element is ignored. The default value is 600000."/> <c:simple-property name="module" required="false" type="string" readOnly="false" description="The module whose class loader should be used when building this cache's configuration."/> - <c:simple-property name="owners" required="false" type="integer" readOnly="false" defaultValue="2" description="Number of cluster-wide replicas for each cache entry. The default value is 2."/> - <c:simple-property name="virtual-nodes" required="false" type="integer" readOnly="false" defaultValue="1" description="Controls the number of virtual nodes per 'real' node. If numVirtualNodes is 1, then virtual nodes are disabled. The topology aware consistent hash must be used if you wish to take advantage of virtual nodes. A default of 1 is used. The default value is 1."/>
- <c:simple-property name="__type" displayName="Type of cache" required="true" readOnly="true" default="local-cache" description="Type of cache"> + <c:simple-property name="__type" displayName="Type of cache" required="true" readOnly="true" default="invalidation-cache" description="Type of cache"> <c:property-options> <c:option value="invalidation-cache"/> - <c:option value="distributed-cache"/> <c:option value="replicated-cache"/> </c:property-options> </c:simple-property> <c:template name="Invalidation Cache" description="Invalidation Cache"> <c:simple-property name="__type" readOnly="true" default="invalidation-cache"/> </c:template> - <c:template name="Distributed Cache" description="Distributed Cache"> - <c:simple-property name="__type" readOnly="true" default="distributed-cache"/> - </c:template> <c:template name="Replicated Cache" description="Replicated Cache"> <c:simple-property name="__type" readOnly="true" default="replicated-cache"/> </c:template> </resource-configuration> </service>
+ <service name="Distributed Cache" + discovery="SubsystemDiscovery" + class="BaseComponent" + createDeletePolicy="both" + creationDataType="configuration"> + + <plugin-configuration> + <c:simple-property name="path" readOnly="true" default="distributed-cache"/> + </plugin-configuration> + + <resource-configuration> + <c:simple-property name="start" required="false" type="string" readOnly="false" default="LAZY" description="The cache start mode, which can be EAGER (immediate start) or LAZY (on-demand start)."> + <c:property-options> + <c:option value="LAZY"/> + <c:option value="EAGER"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="batching" required="false" type="boolean" readOnly="false" default="false" description="If enabled, the invocation batching API will be made available for this cache."/> + <c:simple-property name="indexing" required="false" type="string" readOnly="false" default="NONE" description="If enabled, entries will be indexed when they are added to the cache. Indexes will be updated as entries change or are removed."> + <c:property-options> + <c:option value="NONE"/> + <c:option value="LOCAL"/> + <c:option value="ALL"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="jndi-name" required="false" type="string" readOnly="false" description="The jndi-name to which to bind this cache instance."/> + <c:simple-property name="mode" required="true" type="string" readOnly="false" default="SYNC" defaultValue="SYNC" description="Sets the clustered cache mode, ASYNC for asynchronous operation, or SYNC for synchronous operation."> + <c:property-options> + <c:option value="SYNC"/> + <c:option value="ASYNC"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="queue-size" required="false" type="integer" readOnly="false" default="0" description="In ASYNC mode, this attribute can be used to trigger flushing of the queue when it reaches a specific threshold."/> + <c:simple-property name="queue-flush-interval" required="false" type="long" readOnly="false" default="10" description="In ASYNC mode, this attribute controls how often the asynchronous thread used to flush the replication queue runs. This should be a positive integer which represents thread wakeup time in milliseconds."/> + <c:simple-property name="remote-timeout" required="false" type="long" readOnly="false" default="17500" description="In SYNC mode, the timeout (in ms) used to wait for an acknowledgment when making a remote call, after which the call is aborted and an exception is thrown."/> + <c:simple-property name="async-marshalling" required="false" type="boolean" readOnly="false" defaultValue="false" description="If enabled, this will cause marshalling of entries to be performed asynchronously. The default value is false."/> + <c:simple-property name="l1-lifespan" required="false" type="long" readOnly="false" defaultValue="600000" description="Maximum lifespan of an entry placed in the L1 cache. This element configures the L1 cache behavior in 'distributed' caches instances. In any other cache modes, this element is ignored. The default value is 600000."/> + <c:simple-property name="module" required="false" type="string" readOnly="false" description="The module whose class loader should be used when building this cache's configuration."/> + <c:simple-property name="owners" required="false" type="integer" readOnly="false" defaultValue="2" description="Number of cluster-wide replicas for each cache entry. The default value is 2."/> + <c:simple-property name="virtual-nodes" required="false" type="integer" readOnly="false" defaultValue="1" description="Controls the number of virtual nodes per 'real' node. If numVirtualNodes is 1, then virtual nodes are disabled. The topology aware consistent hash must be used if you wish to take advantage of virtual nodes. A default of 1 is used. The default value is 1."/> + </resource-configuration> + </service> + <service name="Local Cache" discovery="SubsystemDiscovery" class="BaseComponent"
commit 9320bfa050c332a5f89334fcf5606395e5ef9098 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 22:46:02 2012 -0500
[BZ 852552] Update mod-cluster property name to load-balancing-group. The "domain" alias no longer works for load-balancing-group causing configuration updates to fail with unknown domain property.
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 bef06ec..81ddfe9 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 @@ -168,7 +168,7 @@ <c:simple-property name="connector" required="true" type="string" readOnly="false" defaultValue="ajp" description="Name of the web connector used to communicate with the load balancer."> <c:option-source target="resource" expression="type=Connector plugin=&pluginName;"/> </c:simple-property> - <c:simple-property name="domain" required="false" type="string" readOnly="false" description="loadBalancingGroup name."/> + <c:simple-property name="load-balancing-group" required="false" type="string" readOnly="false" description="loadBalancingGroup name."/> </c:group>
<c:group name="context" displayName="Web Context Options">
commit 9f82d413e980967ea3fae7ffe2579c44cc29cbb7 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 22:44:05 2012 -0500
[BZ 852552] Removing properties from the Transport subresource because the resource definition no longer contains them.
Because unset properties are now always sent to the AS7 server, all these removed Transport properties were sent to the AS7 causing an unknown property failure.
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 6f13412..bef06ec 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 @@ -2099,9 +2099,6 @@ <c:simple-property name="cluster" required="false" type="string" readOnly="true" description="The name of the group communication cluster"/> <c:simple-property name="executor" required="false" type="string" readOnly="true" description="The executor to use for the transport"/> <c:simple-property name="lock-timeout" required="false" type="long" readOnly="true" defaultValue="240000" description="The timeout for locks for the transport. The default value is 240000."/> - <c:simple-property name="machine" required="false" type="string" readOnly="true" description="A machine identifier for the transport"/> - <c:simple-property name="rack" required="false" type="string" readOnly="true" description="A rack identifier for the transport"/> - <c:simple-property name="site" required="false" type="string" readOnly="true" description="A site identifier for the transport"/> <c:simple-property name="stack" required="false" type="string" readOnly="true" description="The jgroups stack to use for the transport"/> </resource-configuration> </service> @@ -11431,9 +11428,6 @@ <c:simple-property name="cluster" required="false" type="string" readOnly="false" description="The name of the group communication cluster"/> <c:simple-property name="executor" required="false" type="string" readOnly="false" description="The executor to use for the transport"/> <c:simple-property name="lock-timeout" required="false" type="long" readOnly="false" defaultValue="240000" description="The timeout for locks for the transport. The default value is 240000."/> - <c:simple-property name="machine" required="false" type="string" readOnly="false" description="A machine identifier for the transport"/> - <c:simple-property name="rack" required="false" type="string" readOnly="false" description="A rack identifier for the transport"/> - <c:simple-property name="site" required="false" type="string" readOnly="false" description="A site identifier for the transport"/> <c:simple-property name="stack" required="false" type="string" readOnly="false" description="The jgroups stack to use for the transport"/> </resource-configuration> </service>
commit c1655d4d576311b9034a31b505e75981b1d6e720 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 22:39:35 2012 -0500
[BZ 852552] Send unset properties to AS7 as null.
Existing code was not sending updates for unset properties at all to AS7 making it impossible to unset (or set to empty) a property after it was set to something not null.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java index aad2105..f73ccf5 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java @@ -431,16 +431,25 @@ public class ConfigurationWriteDelegate implements ConfigurationFacet { private void createWriteAttributePropertySimple(CompositeOperation cop, PropertySimple property, PropertyDefinitionSimple propertyDefinition, Address address) {
- // If the property value is null and the property is optional, skip too - if (property.getStringValue() == null && !propertyDefinition.isRequired()) - return; - if (property.getName().endsWith(":ignore")) // Caller takes care return;
if (propertyDefinition.isReadOnly() && !createChildRequested) return;
+ //If the property value is null and the property is optional, + //then send default value or null to the server + if (property.getStringValue() == null && !propertyDefinition.isRequired()) { + String name = property.getName(); + if (name.indexOf(':') != -1) { + name = name.substring(0, name.indexOf(":")); + } + + Operation writeAttribute = new WriteAttribute(address, name, null); + cop.addStep(writeAttribute); + return; + } + SimpleEntry<String, Object> entry = this.preparePropertySimple(property, propertyDefinition); Operation writeAttribute = new WriteAttribute(address, entry.getKey(), entry.getValue()); cop.addStep(writeAttribute); diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java index 21e3d5f..48b6783 100644 --- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java +++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java @@ -59,7 +59,6 @@ public class ConfigurationUpdatingTest extends AbstractConfigurationHandlingTest public void test1() throws Exception {
ConfigurationDefinition definition = loadDescriptor("simple1"); - FakeConnection connection = new FakeConnection();
ConfigurationWriteDelegate delegate = new ConfigurationWriteDelegate(definition, connection, null); @@ -70,12 +69,22 @@ public class ConfigurationUpdatingTest extends AbstractConfigurationHandlingTest
CompositeOperation cop = delegate.updateGenerateOperationFromProperties(conf, new Address());
- assert cop.numberOfSteps() == 1; - Operation step1 = cop.step(0); - assert step1.getOperation().equals("write-attribute"); - Map<String, Object> props = step1.getAdditionalProperties(); - assert props.size() == 2; + Assert.assertEquals(cop.numberOfSteps(), 2);
+ for (int i = 0; i < cop.numberOfSteps(); i++) { + Operation step = cop.step(0); + Assert.assertEquals(step.getOperation(), "write-attribute"); + Map<String, Object> stepProps = step.getAdditionalProperties(); + Assert.assertEquals(stepProps.size(), 2); + + if (stepProps.get("name").equals("needed")) { + Assert.assertEquals(stepProps.get("value"), "test"); + } else if (stepProps.get("name").equals("optional")) { + Assert.assertEquals(stepProps.get("value"), null); + } else { + Assert.fail("Unexepected property found!"); + } + } }
public void test2() throws Exception {
commit e1d2190442ddcfe023696fa59b040f78929a27c6 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 20:14:08 2012 -0500
[BZ 846400] Add validation for components that rely connectors and discovery group name. A compoment should have either the connector or discovery group configured, but not both.
This validation is handled by the AS7 server itself for new resource creation but the validation is missing for configuration updates. Without this validation code in place, the AS7 server accepts the commands, persists the configuration, but fails to reload or restart rendering the server unusable until the configuration file is manually edited. With this fix, the AS7 plugin will not send the configuration updates to the AS7 server unless they meet the descriptor requirements.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConnectorDiscoveryGroupValidatorComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConnectorDiscoveryGroupValidatorComponent.java new file mode 100644 index 0000000..fab342f --- /dev/null +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConnectorDiscoveryGroupValidatorComponent.java @@ -0,0 +1,83 @@ +/* + * RHQ Management Platform + * Copyright 2012, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.rhq.modules.plugins.jbossas7; + +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; +import org.rhq.core.domain.configuration.PropertyList; +import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; +import org.rhq.core.pluginapi.inventory.ResourceComponent; + +/** + * @author Stefan Negrea + * + */ +public class ConnectorDiscoveryGroupValidatorComponent extends BaseComponent<ResourceComponent<?>> { + + @Override + public void updateResourceConfiguration(ConfigurationUpdateReport report) { + Configuration resourceConfiguration = report.getConfiguration(); + ResourceType resourceType = this.context.getResourceType(); + + // we need to check that a connector XOR a discovery-group-name is given + int configuredItemsFound = 0; + String errorMessage = ""; + + if (resourceType.getName().equals("Connection Factory") + || resourceType.getName().equals("Pooled Connection Factory")) { + + PropertyMap connector = resourceConfiguration.getMap("connector:collapsed"); + if (connector != null) { + String name = connector.getSimpleValue("name:0", ""); + if (!name.isEmpty()) { + configuredItemsFound++; + } + } + + errorMessage = "You need to provide either a connector name OR a discovery-group-name. "; + } else if (resourceType.getName().equals("Bridge") || resourceType.getName().equals("Cluster Connection")) { + + PropertyList staticConnectors = resourceConfiguration.getList("static-connectors:nullable"); + if (staticConnectors != null) { + if (!staticConnectors.getList().isEmpty()) { + configuredItemsFound++; + } + } + + errorMessage = "You need to provide either static connectors name OR a discovery-group-name. "; + } + + String discoveryGroup = resourceConfiguration.getSimpleValue("discovery-group-name", ""); + if (!discoveryGroup.isEmpty()) { + configuredItemsFound++; + } + + if (configuredItemsFound != 1) { + errorMessage += (configuredItemsFound == 0) ? "You provided none." : "You provided both."; + report.setErrorMessage(errorMessage); + report.setStatus(ConfigurationUpdateStatus.FAILURE); + } else { + super.updateResourceConfiguration(report); + } + } +} diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HornetQComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HornetQComponent.java index dad90bc..cd791fa 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HornetQComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/HornetQComponent.java @@ -21,9 +21,7 @@ package org.rhq.modules.plugins.jbossas7;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertyList; -import org.rhq.core.domain.configuration.PropertyMap; import org.rhq.core.domain.resource.CreateResourceStatus; -import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.inventory.CreateResourceReport;
/** @@ -43,31 +41,6 @@ public class HornetQComponent extends TemplatedSubResourcesComponent { return report; }
- ResourceType resourceType = report.getResourceType(); - if (resourceType.getName().equals("Connection-Factory")) { - // we need to check that a connector XOR a discovery-group-name is given - int found = 0; - PropertyMap connector = resourceConfiguration.getMap("connector:collapsed"); - - if (connector != null) { - - String name = connector.getSimpleValue("name:0", ""); - if (!name.isEmpty()) - found++; - } - String discoveryGroup = resourceConfiguration.getSimpleValue("discovery-group-name", ""); - if (!discoveryGroup.isEmpty()) - found++; - - if (found == 0 || found == 2) { - String errorMessage = "You need to provide either a connector name OR a discovery-group-name. You provided "; - errorMessage += (found == 0) ? "none" : "both"; - report.setErrorMessage(errorMessage); - report.setStatus(CreateResourceStatus.FAILURE); - return report; - } - } - report = super.createResource(report); return report; } diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java index 8b6eb12..1ede55e 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/JmsComponent.java @@ -21,16 +21,13 @@ package org.rhq.modules.plugins.jbossas7; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import org.rhq.core.domain.configuration.PropertyList; -import org.rhq.core.domain.configuration.PropertyMap; -import org.rhq.core.domain.resource.CreateResourceStatus; -import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
/** * Component class for the JMS subsystem * @author Heiko W. Rupp */ -public class JmsComponent extends BaseComponent { +public class JmsComponent extends ConnectorDiscoveryGroupValidatorComponent {
@Override public void updateResourceConfiguration(ConfigurationUpdateReport report) { @@ -43,31 +40,8 @@ public class JmsComponent extends BaseComponent { return; }
- ResourceType resourceType = context.getResourceType(); - if (resourceType.getName().equals("Connection-Factory")) { - // we need to check that a connector XOR a discovery-group-name is given - int found = 0; - PropertyMap connector = resourceConfiguration.getMap("connector:collapsed"); - - if (connector != null) { - - String name = connector.getSimpleValue("name:0", ""); - if (!name.isEmpty()) - found++; - } - String discoveryGroup = resourceConfiguration.getSimpleValue("discovery-group-name", ""); - if (!discoveryGroup.isEmpty()) - found++; - - if (found == 0 || found == 2) { - String errorMessage = "You need to provide either a connector name OR a discovery-group-name. You provided "; - errorMessage += (found == 0) ? "none" : "both"; - report.setErrorMessage(errorMessage); - report.setStatus(ConfigurationUpdateStatus.FAILURE); - return; - } - } - + //defer the rest of the validation for connector and discovery group name to + //the base class super.updateResourceConfiguration(report); } } 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 8143d04..6f13412 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 @@ -4654,7 +4654,7 @@
<service name="Cluster Connection (Managed Server)" discovery="SubsystemDiscovery" - class="BaseComponent" + class="ConnectorDiscoveryGroupValidatorComponent" createDeletePolicy="neither">
<plugin-configuration> @@ -4784,7 +4784,7 @@
<service name="Bridge (Managed Server)" discovery="SubsystemDiscovery" - class="BaseComponent" + class="ConnectorDiscoveryGroupValidatorComponent" createDeletePolicy="neither">
<plugin-configuration> @@ -6804,7 +6804,7 @@
<service name="Cluster Connection (Profile)" discovery="SubsystemDiscovery" - class="BaseComponent" + class="ConnectorDiscoveryGroupValidatorComponent" createDeletePolicy="both">
<plugin-configuration> @@ -6893,7 +6893,7 @@
<service name="Bridge (Profile)" discovery="SubsystemDiscovery" - class="BaseComponent" + class="ConnectorDiscoveryGroupValidatorComponent" createDeletePolicy="both">
<plugin-configuration> @@ -12855,7 +12855,7 @@
<service name="Cluster Connection" discovery="SubsystemDiscovery" - class="BaseComponent" + class="ConnectorDiscoveryGroupValidatorComponent" createDeletePolicy="both">
<plugin-configuration> @@ -12985,7 +12985,7 @@
<service name="Bridge" discovery="SubsystemDiscovery" - class="BaseComponent" + class="ConnectorDiscoveryGroupValidatorComponent" createDeletePolicy="both">
<plugin-configuration>
commit e96ce182758719f86364bdc7a2e73c287dddbe4c Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 28 15:22:40 2012 -0500
[BZ 852534] Collapsed maps with null keys should be set to null. Attempting to send maps with null values to the application server results in validation errors.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java index 8286f17..aad2105 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java @@ -628,10 +628,14 @@ public class ConfigurationWriteDelegate implements ConfigurationFacet { throw new IllegalArgumentException("Member names in a :collapsed map must end in :0 and :1"); }
- Map<String, Object> resultMap = new HashMap<String, Object>(); - resultMap.put(key, value); + if (key != null) { + Map<String, Object> resultMap = new HashMap<String, Object>(); + resultMap.put(key, value);
- return resultMap; + return resultMap; + } else { + return null; + } }
commit 9fda60f21e354f3b33a1ecf85b81cae19e0af1af Author: Jirka Kremser jkremser@redhat.com Date: Tue Aug 28 14:34:23 2012 +0200
[BZ 850818 - Globally uncaught exception on clicking OK button while adding CLI Script alert notification to the alert definition] Added the check whether the repository has been picked
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java index f63eb55..b212043 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/CliNotificationSenderForm.java @@ -403,6 +403,11 @@ public class CliNotificationSenderForm extends AbstractNotificationSenderForm { }
private void validatePackage(final AsyncCallback<Void> callback) { + if (config.selectedRepo == null) { + repoSelector.setIcons(failureIcon); + callback.onFailure(null); + return; + } getConfiguration().put(new PropertySimple(PROP_REPO_ID, config.selectedRepo.getId()));
if (packageSelector.getSelectedIndex() == 0) {
commit f3f26d0a85bf71fad532424b6267a331bd048136 Author: Mike Thompson mithomps@redhat.com Date: Mon Aug 27 14:42:26 2012 -0700
[BZ 848501] - IE8 rendering of resource measurement time overlaid on the actual metric name
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java index c27e626..8a0898d 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/resource/ResourceMetricsPortlet.java @@ -290,6 +290,7 @@ public class ResourceMetricsPortlet extends GroupMetricsPortlet { StaticTextItem value = AbstractActivityView .newTextItem(convertedValue); value.setVAlign(VerticalAlignment.TOP); + value.setAlign(Alignment.RIGHT);
row.setItems(graphContainer, link, value); row.setWidth100();
commit b8a6a496d40915abb22fdd87753aec0c131ed95d Author: Stefan Negrea snegrea@redhat.com Date: Fri Aug 24 10:21:20 2012 -0500
[BZ 849964] Increase the operation timeout to 30 seconds to avoid cases where the host is under heavy load thus making all managed server operations take longer than the default 10 seconds.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java index d26f54e..e7fcd5b 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ManagedASComponent.java @@ -271,7 +271,7 @@ public class ManagedASComponent extends BaseComponent<HostControllerComponent<?> } }
- Result res = getASConnection().execute(op); + Result res = getASConnection().execute(op, 30);
OperationResult opRes; if (res.isSuccess()) {
commit 97867e2b4b241fa5ea33d0f439b1026914def5be Author: Jirka Kremser jkremser@redhat.com Date: Thu Aug 23 16:55:00 2012 +0200
[BZ 851239 - Globally uncaught exception on clicking the link Bundles->Repositories->JBoss Patches] Defensive programming - check for null/empty list -> exception is not thrown
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java index 6eaa263..1f2f660 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java @@ -42,7 +42,11 @@ import org.rhq.core.domain.bundle.Bundle; import org.rhq.core.domain.criteria.BundleCriteria; import org.rhq.core.domain.tagging.Tag; import org.rhq.core.domain.util.PageList; -import org.rhq.enterprise.gui.coregui.client.*; +import org.rhq.enterprise.gui.coregui.client.BookmarkableView; +import org.rhq.enterprise.gui.coregui.client.CoreGUI; +import org.rhq.enterprise.gui.coregui.client.IconEnum; +import org.rhq.enterprise.gui.coregui.client.ViewId; +import org.rhq.enterprise.gui.coregui.client.ViewPath; import org.rhq.enterprise.gui.coregui.client.bundle.BundleTopView; import org.rhq.enterprise.gui.coregui.client.bundle.deploy.BundleDeployWizard; import org.rhq.enterprise.gui.coregui.client.bundle.deployment.BundleDeploymentView; @@ -286,6 +290,11 @@ public class BundleView extends LocatableVLayout implements BookmarkableView { }
public void onSuccess(PageList<Bundle> result) { + if (result == null || result.isEmpty()) { + CoreGUI.getMessageCenter().notify( + new Message(MSG.view_bundle_list_error4(), Message.Severity.Error)); + return; + } Bundle bundle = result.get(0); viewBundle(bundle, viewPath.getCurrent()); } diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties index cfa1f6d..9681ea1 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties @@ -413,10 +413,10 @@ filter_from_date = From filter_to_date = To group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = {0} out of {1} group members have a ''{2}'' resource -search_invalid_search_expression = Invalid search expression. -search_failed_to_save_search = Failed to Save Search: {0} search_failed_to_retrieve_saved_search = Failed to retrieve saved search search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion +search_failed_to_save_search = Failed to Save Search: {0} +search_invalid_search_expression = Invalid search expression. search_name_your_search = name you search search_successfully_saved_search = Successfully Saved Search: {0} util_ancestry_parentAncestry = Parent Ancestry for: @@ -1127,6 +1127,7 @@ view_bundle_list_destinationsCount = Destinations Count view_bundle_list_error1 = Failed to load bundle to deploy [{0}] view_bundle_list_error2 = Failed to get a single bundle to deploy [{0}] view_bundle_list_error3 = Failed to load bundle +view_bundle_list_error4 = No bundles found in this repository view_bundle_list_loadFailure = Failed to load the bundle to be deployed [{0}] view_bundle_list_loadWithLatestFailure = Failed to load bundle with the latest version data view_bundle_list_singleLoadFailure = Failed to get a single bundle to be deployed [{0}] @@ -1182,7 +1183,7 @@ view_configEdit_error_3 = Cannot add property named [{0}]. The property name is view_configEdit_files = Files view_configEdit_hideAll = Hide All view_configEdit_jumpToSection = Jump to Section -view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} +view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} view_configEdit_minBoundsExceeded = Cannot delete this entry as the minimum has been set to: {0} view_configEdit_msg_1 = Added property [{0}] to the set. view_configEdit_msg_2 = Removed properties from the set. diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties index 5be0d57..b2a842d 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties @@ -1146,6 +1146,7 @@ view_bundle_list_destinationsCount = Počet cílů view_bundle_list_error1 = Nepodařilo se načíst balík k nasazení [{0}] view_bundle_list_error2 = Nepodařilo se získat 1 balík k nasazení [{0}] view_bundle_list_error3 = Nepodařilo se získat balík +view_bundle_list_error3 = V tomto repozitáři nejsou žádné balíky view_bundle_list_loadFailure = Nepodařilo se získat balík k nasazení [{0}] view_bundle_list_loadWithLatestFailure = Nepodařilo se získat balík s poslední verzí view_bundle_list_singleLoadFailure = Nepodařilo se získat 1 balík k nasazení [{0}] diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties index d39f16a..4fe89d0 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties @@ -397,10 +397,10 @@ filter_from_date = Von filter_to_date = Bis ##group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = {0} der {1} Gruppenmitglieder haben eine ''{2}'' Ressource -##search_invalid_search_expression = Invalid search expression. -##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion +##search_failed_to_save_search = Failed to Save Search: {0} +##search_invalid_search_expression = Invalid search expression. ##search_name_your_search = name you search ##search_successfully_saved_search = Successfully Saved Search: {0} util_disambiguationReportDecorator_pluginSuffix = ({0} Plugin) @@ -1013,6 +1013,7 @@ view_bundle_list_destinationsCount = Anzahl Ziele ##view_bundle_list_error1 = Failed to load bundle to deploy [{0}] ##view_bundle_list_error2 = Failed to get a single bundle to deploy [{0}] view_bundle_list_error3 = Konnte das Bundle nicht laden +##view_bundle_list_error4 = No bundles found in this repository ##view_bundle_list_loadFailure = Failed to load the bundle to be deployed [{0}] ##view_bundle_list_loadWithLatestFailure = Failed to load bundle with the latest version data ##view_bundle_list_singleLoadFailure = Failed to get a single bundle to be deployed [{0}] @@ -1066,7 +1067,7 @@ view_configEdit_confirm_2 = Sind Sie sicher dass sie diese Zeile löschen wollen view_configEdit_files = Dateien view_configEdit_hideAll = Alle verbergen view_configEdit_jumpToSection = Zum Abschnitt springen -##view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} +##view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} ##view_configEdit_minBoundsExceeded = Cannot delete this entry as the minimum has been set to: {0} view_configEdit_msg_1 = Eigentschaft [{0}] zur Menge hinzugefügt ##view_configEdit_msg_2 = Removed properties from the set. diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties index 6c2044a..e2e25e8 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties @@ -1123,6 +1123,7 @@ view_bundle_list_destinationsCount = 宛先数 view_bundle_list_error1 = [{0}] をデプロイするためのバンドルのロードに失敗しました view_bundle_list_error2 = [{0}] をデプロイするための単一バンドルの取得に失敗しました view_bundle_list_error3 = バンドルのロードに失敗しました +##view_bundle_list_error4 = No bundles found in this repository view_bundle_list_loadFailure = デプロイされるバンドル [{0}] のロードに失敗しました view_bundle_list_loadWithLatestFailure = 最新バージョンデータを持つバンドルのロードに失敗しました view_bundle_list_singleLoadFailure = デプロイされる単一バンドル [{0}] の取得に失敗しました diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties index 9f00c55..e3f044f 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties @@ -416,10 +416,10 @@ favorites_resources = Recursos Favoritos ##filter_to_date = To ##group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = {0} out of {1} group members have a ''{2}'' resource -##search_invalid_search_expression = Invalid search expression. -##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion +##search_failed_to_save_search = Failed to Save Search: {0} +##search_invalid_search_expression = Invalid search expression. ##search_name_your_search = name you search ##search_successfully_saved_search = Successfully Saved Search: {0} util_ancestry_parentAncestry = Ancestral para: @@ -1133,6 +1133,7 @@ view_bundle_list_destinationsCount = Soma das Destina\u00E7\u00F5es view_bundle_list_error1 = Falha ao carregar bundle [{0}] para implantar view_bundle_list_error2 = Falha ao obter um \u00FAnico bundle [{0}] para deploy view_bundle_list_error3 = Falha ao carregar o bundle +##view_bundle_list_error4 = No bundles found in this repository view_bundle_list_loadFailure = Falha ao carregar o bundle [{0}] para ser implantado view_bundle_list_loadWithLatestFailure = Falha ao carregar o bundle com os dados da \u00FAltima vers\u00E3o view_bundle_list_singleLoadFailure = Falha ao obter um \u00FAnico bundle [{0}] para ser implantado @@ -1188,7 +1189,7 @@ view_configEdit_error_3 = N\u00E3o f\u00F3 poss\u00EDvel adicionar a propriedade view_configEdit_files = Arquivos view_configEdit_hideAll = Ocultar todos view_configEdit_jumpToSection = Ir direto para a Sele\u00E7\u00E3o -##view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} +##view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} ##view_configEdit_minBoundsExceeded = Cannot delete this entry as the minimum has been set to: {0} view_configEdit_msg_1 = Propriedade [{0}] adicionada ao conjunto. view_configEdit_msg_2 = Propriedades removidas do conjunto. diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties index 25671e1..e27ce16 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties @@ -2464,6 +2464,7 @@ view_admin_downloads_cli_version = Версия CLI ##view_admin_downloads_connectors_none = No connectors are available for download ##view_alert_details_field_resource_ancestry = Resource Ancestry ##view_alert_details_field_watched_resource = Watched Resource +##view_bundle_list_error4 = No bundles found in this repository ##view_bundle_revertWizard_getInfoStep_revertDeployDescFull = [REVERT From] {0} [REVERT To] {1} ##view_configEdit_property = Property ##view_configEdit_unset = Unset? diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties index 827e01b..2de43cc 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties @@ -405,10 +405,10 @@ favorites_resources = \u8d44\u6e90\u6536\u85cf\u5939 ##filter_to_date = To ##group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = \u9664\u53bb {1},{0}\u7684\u7ec4\u6210\u5458\u62e5\u6709 \u4e00\u4e2a''{2}''\u8d44\u6e90 -##search_invalid_search_expression = Invalid search expression. -##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion +##search_failed_to_save_search = Failed to Save Search: {0} +##search_invalid_search_expression = Invalid search expression. ##search_name_your_search = name you search ##search_successfully_saved_search = Successfully Saved Search: {0} util_ancestry_parentAncestry = Parent Ancestry for: @@ -1117,6 +1117,7 @@ view_bundle_list_destinationsCount = \u76ee\u7684\u5730\u6570 view_bundle_list_error1 = Failed to load bundle to deploy [{0}] view_bundle_list_error2 = Failed to get a single bundle to deploy [{0}] view_bundle_list_error3 = \u52a0\u8f7dbundle\u5931\u8d25 +##view_bundle_list_error4 = No bundles found in this repository view_bundle_list_loadFailure = Failed to load the bundle to be deployed [{0}] view_bundle_list_loadWithLatestFailure = Failed to load bundle with the latest version data view_bundle_list_singleLoadFailure = Failed to get a single bundle to be deployed [{0}] @@ -1172,7 +1173,7 @@ view_configEdit_error_3 = \u65e0\u6cd5\u6dfb\u52a0\u540d\u4e3a[{0}]\u7684\u5c5e\ view_configEdit_files = \u6587\u4ef6 view_configEdit_hideAll = \u9690\u85cf\u6240\u6709 view_configEdit_jumpToSection = \u8df3\u81f3\u6a21\u5757 -##view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} +##view_configEdit_maxBoundsExceeded = Cannot add another entry because the maximum size bounds has been met: {0} ##view_configEdit_minBoundsExceeded = Cannot delete this entry as the minimum has been set to: {0} view_configEdit_msg_1 = \u589e\u52a0\u5c5e\u6027 [{0}]\u5230\u96c6\u5408. view_configEdit_msg_2 = \u79fb\u9664\u96c6\u5408\u5185\u6240\u6709\u7684\u5c5e\u6027.
commit 8fb35be5c92397b282a582c754c6b71b8b277a60 Author: Lukas Krejci lkrejci@redhat.com Date: Thu Aug 23 12:08:11 2012 +0200
Duplicating all the tests that use scripting language to have both javascript and python versions.
diff --git a/modules/enterprise/binding/pom.xml b/modules/enterprise/binding/pom.xml index 7d37053..37959d2 100644 --- a/modules/enterprise/binding/pom.xml +++ b/modules/enterprise/binding/pom.xml @@ -45,6 +45,13 @@ </dependency>
<dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-scripting-python</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> <groupId>${project.groupId}</groupId> <artifactId>rhq-core-domain</artifactId> <version>${project.version}</version> diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java index c3d5450..cf93afb 100644 --- a/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java +++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptEngineTest.java @@ -40,19 +40,24 @@ import org.rhq.bindings.util.PackageFinder; * * @author Lukas Krejci */ -@Test -public class ScriptEngineTest { +public class ScriptEngineTest extends ScriptedTestBase {
private static StandardBindings EMPTY_BINDINGS = new StandardBindings(new PrintWriter(System.out), new FakeRhqFacade());
@Test - public void testFactory() throws ScriptException, IOException { + public void testFactory_javascript() throws ScriptException, IOException { ScriptEngine engine = getScriptEngine(); assertNotNull(engine); }
@Test - public void testSandbox() throws ScriptException, IOException { + public void testFactory_python() throws ScriptException, IOException { + ScriptEngine engine = getScriptEngine(); + assertNotNull(engine); + } + + @Test + public void testSandbox_javascript() throws ScriptException, IOException { ScriptEngine sandbox = getSecuredScriptEngine();
try { @@ -76,7 +81,44 @@ public class ScriptEngineTest { }
@Test - public void testStandardBindings() throws ScriptException, IOException { + public void testSandbox_python() throws Exception { + ScriptEngine sandbox = getSecuredScriptEngine(); + + try { + sandbox.eval("import java.lang as foo\nfoo.System.exit(1)"); + } catch (Exception e) { + assertSecurityExceptionPresent(e); + } + + try { + //try hard to get to the System.exit() + sandbox.eval( + "import java.lang as l\n" + + "import java.lang.reflect as r\n" + + "import java.beans as b\n" + + "cls = l.Class.forName('java.lang.System')\n" + + "params = r.Array.newInstance(l.Class.forName('java.lang.Object'), 1)\n" + + "params[0] = l.Integer.valueOf('1')\n" + + "st = b.Statement(cls, 'exit', params)\n" + + "st.execute()"); + + } catch (Exception e) { + assertSecurityExceptionPresent(e); + } + } + + @Test + public void testStandardBindings_javascript() throws ScriptException, IOException { + ScriptEngine scriptEngine = getScriptEngine(); + + for(String var : EMPTY_BINDINGS.keySet()) { + boolean hasVar = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(var); + assertTrue(hasVar, "The variable '" + var + "' is not present in the script context but should be."); + } + } + + @Test + public void testStandardBindings_python() throws Exception { ScriptEngine scriptEngine = getScriptEngine();
for(String var : EMPTY_BINDINGS.keySet()) { @@ -86,13 +128,11 @@ public class ScriptEngineTest { }
private ScriptEngine getScriptEngine() throws ScriptException, IOException { - return ScriptEngineFactory.getScriptEngine("javascript", new PackageFinder(Collections.<File> emptyList()), - EMPTY_BINDINGS); + return getScriptEngine(new PackageFinder(Collections.<File> emptyList()), EMPTY_BINDINGS); }
private ScriptEngine getSecuredScriptEngine() throws ScriptException, IOException { - return ScriptEngineFactory.getSecuredScriptEngine("javascript", - new PackageFinder(Collections.<File> emptyList()), EMPTY_BINDINGS, new StandardScriptPermissions()); + return getSecuredScriptEngine(new PackageFinder(Collections.<File> emptyList()), EMPTY_BINDINGS, new StandardScriptPermissions()); }
private void assertSecurityExceptionPresent(Throwable t) { diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptedTestBase.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptedTestBase.java new file mode 100644 index 0000000..9bf09b5 --- /dev/null +++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/ScriptedTestBase.java @@ -0,0 +1,220 @@ +/* + * RHQ Management Platform + * Copyright (C) 2005-2012 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.rhq.bindings; + +import static org.testng.Assert.fail; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.security.PermissionCollection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.script.ScriptEngine; +import javax.script.ScriptException; + +import org.testng.IHookCallBack; +import org.testng.IHookable; +import org.testng.ITestContext; +import org.testng.ITestNGMethod; +import org.testng.ITestResult; +import org.testng.annotations.AfterClass; + +import org.rhq.bindings.util.PackageFinder; + +/** + * This is a base class for tests that need to test the some functionality using + * the scripting languages. + * <p> + * It enforces the naming convention for the tests: + * <code> + * @Test + * public void myTestMethod_language() ... + * </code> + * The language is to be replaced with the name of the scripting language that the test method + * uses (e.g. javacript, python). This class then makes sure that each test exists for all + * the scripting languages that are present on the classpath. + * <p> + * This class also provides the {@link #getScriptEngine(PackageFinder, StandardBindings)} and + * {@link #getSecuredScriptEngine(PackageFinder, StandardBindings, PermissionCollection)} methods + * that, if invoked from within a test method call-chain, will return the script engine for the + * correct language under test (determined by the test method name suffix). + * + * @author Lukas Krejci + */ +public abstract class ScriptedTestBase implements IHookable { + + private String currentLanguage; + + @AfterClass + public void checkTestImplsForEachLanguage(ITestContext ctx) { + Set<Method> methods = getAllTestMethods(getClass(), ctx); + + Set<String> supportedLanguages = ScriptEngineFactory.getSupportedLanguages(); + + Map<String, Set<String>> methodBaseNamesByLanguage = new HashMap<String, Set<String>>(); + + for (String lang : supportedLanguages) { + methodBaseNamesByLanguage.put(lang, new HashSet<String>()); + } + + Set<Method> invalidTestMethods = new HashSet<Method>(); + + for (Method m : methods) { + //check that the method name ends with one of the supported language names + boolean valid = false; + for (String lang : supportedLanguages) { + String suffix = "_" + lang; + + if (!m.getName().endsWith(suffix)) { + continue; + } + + //now put the method "basename" into our mapping array + String baseName = m.getName().substring(0, m.getName().lastIndexOf("_")); + methodBaseNamesByLanguage.get(lang).add(baseName); + + valid = true; + break; + } + + if (!valid) { + invalidTestMethods.add(m); + } + } + + Set<String> missingTests = new HashSet<String>(); + + //now check that all languages have all test methods + for (Map.Entry<String, Set<String>> a : methodBaseNamesByLanguage.entrySet()) { + for (Map.Entry<String, Set<String>> b : methodBaseNamesByLanguage.entrySet()) { + String alang = a.getKey(); + String blang = b.getKey(); + Set<String> amethods = a.getValue(); + Set<String> bmethods = b.getValue(); + + if (alang.equals(blang)) { + continue; + } + + addMissing(amethods, bmethods, alang, missingTests); + addMissing(bmethods, amethods, blang, missingTests); + } + } + + if (!invalidTestMethods.isEmpty() || !missingTests.isEmpty()) { + StringBuilder msg = new StringBuilder("Scripted test " + getClass() + " is invalid:\n"); + + if (!invalidTestMethods.isEmpty()) { + msg.append("Invalid method names:\n"); + for (Method m : invalidTestMethods) { + msg.append(m.getName()).append("\n"); + } + } + + if (!missingTests.isEmpty()) { + msg.append("\nMissing tests for languages:\n"); + for (String m : missingTests) { + msg.append(m).append("\n"); + } + } + + fail(msg.toString()); + } + } + + @Override + public final void run(IHookCallBack callBack, ITestResult testResult) { + String methodName = testResult.getMethod().getMethodName(); + int underScoreIdx = methodName.lastIndexOf('_'); + if (underScoreIdx >= 0 && underScoreIdx < methodName.length() - 1) { + currentLanguage = methodName.substring(underScoreIdx + 1); + } else { + currentLanguage = null; + } + + callBack.runTestMethod(testResult); + + currentLanguage = null; + } + + /** + * Returns a new script engine implementation for the current test method. + * <p> + * The script engine implementation is determined based on the test method's name + * suffix. + * <p> + * E.g. if the test method ends with "_javascript", this method will return the javascript + * script engine. + * <p> + * This method is calling {@link ScriptEngineFactory#getScriptEngine(String, PackageFinder, StandardBindings)} + * but determines the "language" parameter for you. + * + * @param packageFinder the package finder to use for the script engine initialization + * @param bindings the bindings to use in the script engine + * @return the script engine + * @throws ScriptException + * @throws IOException + */ + protected ScriptEngine getScriptEngine(PackageFinder packageFinder, StandardBindings bindings) + throws ScriptException, IOException { + + return ScriptEngineFactory.getScriptEngine(currentLanguage, packageFinder, bindings); + } + + /** + * Similar to {@link #getScriptEngine(PackageFinder, StandardBindings)} but returns the + * secured version of the script engine. + * + * @param packageFinder the package finder to use for the script engine initialization + * @param bindings the bindings to use in the script engine + * @param perms the permissions to run the scripts with + * @return the script engine + * @throws ScriptException + * @throws IOException + */ + protected ScriptEngine getSecuredScriptEngine(PackageFinder packageFinder, StandardBindings bindings, + PermissionCollection perms) throws ScriptException, IOException { + + return ScriptEngineFactory.getSecuredScriptEngine(currentLanguage, packageFinder, bindings, perms); + } + + private static Set<Method> getAllTestMethods(Class<?> cls, ITestContext ctx) { + HashSet<Method> ret = new HashSet<Method>(); + for (ITestNGMethod m : ctx.getAllTestMethods()) { + if (m.getTestClass().getRealClass().equals(cls)) { + ret.add(m.getConstructorOrMethod().getMethod()); + } + } + + return ret; + } + + private static void addMissing(Set<String> methods, Set<String> referenceMethods, String lang, Set<String> missing) { + for (String m : referenceMethods) { + if (!methods.contains(m)) { + String fullName = m + "_" + lang; + missing.add(fullName); + } + } + } +} diff --git a/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java index 1d7f657..97753e3 100644 --- a/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java +++ b/modules/enterprise/binding/src/test/java/org/rhq/bindings/util/ScriptAssertTest.java @@ -26,118 +26,247 @@ package org.rhq.bindings.util; import static org.testng.Assert.fail;
import java.io.File; +import java.io.IOException; import java.io.PrintWriter; import java.util.Collections;
import javax.script.ScriptEngine; import javax.script.ScriptException;
-import org.testng.annotations.BeforeTest; import org.testng.annotations.Test;
import org.rhq.bindings.FakeRhqFacade; -import org.rhq.bindings.ScriptEngineFactory; +import org.rhq.bindings.ScriptedTestBase; import org.rhq.bindings.StandardBindings;
-public class ScriptAssertTest { +public class ScriptAssertTest extends ScriptedTestBase {
- private ScriptEngine engine; + private ScriptEngine getScriptEngine() { + try { + return getScriptEngine(new PackageFinder(Collections.<File> emptyList()), new StandardBindings( + new PrintWriter(System.out), new FakeRhqFacade())); + } catch (ScriptException e) { + fail("Could not get the script engine.", e); + return null; + } catch (IOException e) { + fail("Could not get the script engine.", e); + return null; + } + }
- @BeforeTest - public void verifyScriptEngineIsAvailable() throws Exception { - StandardBindings bindings = new StandardBindings(new PrintWriter(System.out), new FakeRhqFacade()); - engine = ScriptEngineFactory.getScriptEngine("javascript", new PackageFinder(Collections.<File> emptyList()), - bindings); + @Test + public void testAssertExists_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "var a = 1; assertExists('a');", "assertExists should succeed for a defined variable."); + testThrowsAssertion(engine, "assertExists('foo')", "assertExists should fail for an undefined variable."); + testWorks(engine, "function func() { return 42 }; assertExists('func');", + "assertExists should succeed for a defined function."); }
@Test - public void testAssertExists() { - testWorks("var a = 1; assertExists('a');", "assertExists should succeed for a defined variable."); - testThrowsAssertion("assertExists('foo')", "assertExists should fail for an undefined variable."); - testWorks("function func() { return 42 }; assertExists('func');", + public void testAssertExists_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "a = 1\n" + "assertExists('a')", "assertExists should succeed for a defined variable."); + testThrowsAssertion(engine, "assertExists('foo')", "assertExists should fail for an undefined variable."); + testWorks(engine, "def func():\n" + " return 42\n" + "assertExists('func')", "assertExists should succeed for a defined function."); }
@Test - public void testAssertTrue() { - testWorks("var a = true; assertTrue(a);", "assertTrue of a true variable should succeed"); - testWorks("assertTrue(1 == 1)", "assertTrue on a true boolean expression should succeed"); - testThrowsAssertion("var a = false; assertTrue(a)", "assertTrue should fail on a false variable"); - testThrowsAssertion("assertTrue(1 == 2)", "assertTrue should fail on a false boolean expression"); + public void testAssertTrue_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "var a = true; assertTrue(a);", "assertTrue of a true variable should succeed"); + testWorks(engine, "assertTrue(1 == 1)", "assertTrue on a true boolean expression should succeed"); + testThrowsAssertion(engine, "var a = false; assertTrue(a)", "assertTrue should fail on a false variable"); + testThrowsAssertion(engine, "assertTrue(1 == 2)", "assertTrue should fail on a false boolean expression"); + } + + @Test + public void testAssertTrue_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "a = True\n" + "assertTrue(a)", "assertTrue of a true variable should succeed"); + testWorks(engine, "assertTrue(1 == 1)", "assertTrue on a true boolean expression should succeed"); + testThrowsAssertion(engine, "a = False\n" + "assertTrue(a)", "assertTrue should fail on a false variable"); + testThrowsAssertion(engine, "assertTrue(1 == 2)", "assertTrue should fail on a false boolean expression"); + } + + @Test + public void testAssertFalse_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "var a = false; assertFalse(a)", "assertFalse of a false variable should succeed"); + testWorks(engine, "assertFalse(1 == 2)", "assertFalse on a false boolean expression should succeed"); + testThrowsAssertion(engine, "var a = true; assertFalse(a)", "assertFalse should fail on a true variable"); + testThrowsAssertion(engine, "assertFalse(1 == 1)", "assertFalse should fail on a true boolean expression"); } - + @Test - public void testAssertFalse() { - testWorks("var a = false; assertFalse(a);", "assertFalse of a false variable should succeed"); - testWorks("assertFalse(1 == 2)", "assertFalse on a false boolean expression should succeed"); - testThrowsAssertion("var a = true; assertFalse(a)", "assertFalse should fail on a true variable"); - testThrowsAssertion("assertFalse(1 == 1)", "assertFalse should fail on a true boolean expression"); + public void testAssertFalse_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "a = False\n" + "assertFalse(a)", "assertFalse of a false variable should succeed"); + testWorks(engine, "assertFalse(1 == 2)", "assertFalse on a false boolean expression should succeed"); + testThrowsAssertion(engine, "a = True\n" + "assertFalse(a)", "assertFalse should fail on a true variable"); + testThrowsAssertion(engine, "assertFalse(1 == 1)", "assertFalse should fail on a true boolean expression"); } - + @Test - public void testAssertNull() { - testWorks("assertNull(foo)", "assertNull should succeed on an undefined variable"); - testWorks("var foo = null; assertNull(foo);", "assertNull should succeed on a null variable"); - testWorks("assertNull(null)", "assertNull should succeed on a null literal"); - testThrowsAssertion("assertNull(1)", "assertNull should fail on a number"); - testThrowsAssertion("var foo = '1'; assertNull(foo)", "assertNull should fail on a non-null variable"); + public void testAssertNull_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "var foo = null; assertNull(foo);", "assertNull should succeed on a null variable"); + testWorks(engine, "assertNull(null)", "assertNull should succeed on a null literal"); + testThrowsAssertion(engine, "assertNull(1)", "assertNull should fail on a number"); + testThrowsAssertion(engine, "var foo = '1'; assertNull(foo)", "assertNull should fail on a non-null variable"); } - + @Test - public void testAssertNotNull() { - testWorks("assertNotNull(1)", "assertNotNull should succeed on a number"); - testWorks("var foo = '1'; assertNotNull(foo)", "assertNotNull should succeed on a non-null variable"); - testThrowsAssertion("assertNotNull(foo)", "assertNotNull should fail on an undefined variable"); - testThrowsAssertion("var foo = null; assertNotNull(foo);", "assertNotNull should fail on a null variable"); - testThrowsAssertion("assertNotNull(null)", "assertNotNull should fail on a null literal"); + public void testAssertNull_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "foo = None\n" + "assertNull(foo)", "assertNull should succeed on a null variable"); + testWorks(engine, "assertNull(None)", "assertNull should succeed on a null literal"); + testThrowsAssertion(engine, "assertNull(1)", "assertNull should fail on a number"); + testThrowsAssertion(engine, "foo = '1'\n" + "assertNull(foo)", "assertNull should fail on a non-null variable"); } - + @Test - public void testAssertEquals_Numbers() { - testWorks("assertEquals(1, 1)", "1 == 1"); - testWorks("assertEquals(1.0, 1)", "1.0 == 1"); - testWorks("assertEquals(1.0, 1.0)", "1.0 == 1.0"); - testThrowsAssertion("assertEquals(1, 2)", "1 == 2"); + public void testAssertNotNull_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertNotNull(1)", "assertNotNull should succeed on a number"); + testWorks(engine, "var foo = '1'; assertNotNull(foo)", "assertNotNull should succeed on a non-null variable"); + testThrowsAssertion(engine, "assertNotNull(foo)", "assertNotNull should fail on an undefined variable"); + testThrowsAssertion(engine, "var foo = null; assertNotNull(foo);", + "assertNotNull should fail on a null variable"); + testThrowsAssertion(engine, "assertNotNull(null)", "assertNotNull should fail on a null literal"); } - + @Test - public void testAssertEquals_Arrays() { - testWorks("assertEquals(['a', 'b'], ['a', 'b'])", "native array comparison"); - testThrowsAssertion("assertEquals(['a', 'b'], ['c', 'd'])", "native array comparison with difference"); + public void testAssertNotNull_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertNotNull(1)", "assertNotNull should succeed on a number"); + testWorks(engine, "foo = '1'\n" + "assertNotNull(foo)", "assertNotNull should succeed on a non-null variable"); + testThrowsAssertion(engine, "assertNotNull(foo)", "assertNotNull should fail on an undefined variable"); + testThrowsAssertion(engine, "foo = None\n" + "assertNotNull(foo);", + "assertNotNull should fail on a null variable"); + testThrowsAssertion(engine, "assertNotNull(None)", "assertNotNull should fail on a null literal"); }
@Test - public void testAssertEquals_Collections() { - testWorks("a = new java.util.ArrayList; " + "b = new java.util.ArrayList; " + "a.add('a'); " + "b.add('a'); " - + "assertEquals(a, b)", "ArrayList comparison"); - testThrowsAssertion("a = new java.util.ArrayList; " + "b = new java.util.ArrayList; " + "a.add('a'); " + public void testAssertEquals_Numbers_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertEquals(1, 1)", "1 == 1"); + testWorks(engine, "assertEquals(1.0, 1)", "1.0 == 1"); + testWorks(engine, "assertEquals(1.0, 1.0)", "1.0 == 1.0"); + testThrowsAssertion(engine, "assertEquals(1, 2)", "1 == 2"); + } + + @Test + public void testAssertEquals_Numbers_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertEquals(1, 1)", "1 == 1"); + //Python distinguishes between ints and floats, so this + //won't work (even though "1.0 == 1" returns true in pure python) + //testWorks(engine, "assertEquals(1.0, 1)", "1.0 == 1"); + testWorks(engine, "assertEquals(1.0, 1.0)", "1.0 == 1.0"); + testThrowsAssertion(engine, "assertEquals(1, 2)", "1 == 2"); + } + + @Test + public void testAssertEquals_Arrays_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertEquals(['a', 'b'], ['a', 'b'])", "native array comparison"); + testThrowsAssertion(engine, "assertEquals(['a', 'b'], ['c', 'd'])", "native array comparison with difference"); + } + + @Test + public void testAssertEquals_Arrays_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertEquals(['a', 'b'], ['a', 'b'])", "native array comparison"); + testThrowsAssertion(engine, "assertEquals(['a', 'b'], ['c', 'd'])", "native array comparison with difference"); + } + + @Test + public void testAssertEquals_Collections_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "a = new java.util.ArrayList; " + "b = new java.util.ArrayList; " + "a.add('a'); " + + "b.add('a'); " + "assertEquals(a, b)", "ArrayList comparison"); + testThrowsAssertion(engine, "a = new java.util.ArrayList; " + "b = new java.util.ArrayList; " + "a.add('a'); " + "b.add('b'); " + "assertEquals(a, b)", "ArrayList comparison with difference"); }
@Test - public void testAssertEqualsNoOrder() { - testWorks("assertEqualsNoOrder(['a', 'b'], ['b', 'a'])", "native array comparison"); + public void testAssertEquals_Collections_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "import java.util as u\n" + "a = u.ArrayList()\n" + "b = u.ArrayList()\n" + "a.add('a')\n" + + "b.add('a')\n" + "assertEquals(a, b)", "ArrayList comparison"); + testThrowsAssertion(engine, "import java.util as u\n" + "a = u.ArrayList()\n" + "b = u.ArrayList()\n" + "a.add('a')\n" + + "b.add('b')\n" + "assertEquals(a, b)", "ArrayList comparison with difference"); }
@Test - public void testAssertSame() { - testWorks("var a = '1'; assertSame(a, a)", "assertSame should succeed comparing one variable"); - testWorks("var a = '1'; b = a; assertSame(a, b)", "asserSame should succeed comparing 2 references of the same object"); - testWorks("assertSame(null, null);", "assertSame should succeed on null values"); - testThrowsAssertion("var a = '1'; b = '2'; assertSame(a, b)", "assertSame should fail comparing 2 different variables"); - testThrowsAssertion("var a = 1; assertSame(a, null)", "assertSame should fail comparing non-null variable with a null value"); + public void testAssertEqualsNoOrder_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertEqualsNoOrder(['a', 'b'], ['b', 'a'])", "native array comparison"); } - + + @Test + public void testAssertEqualsNoOrder_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "assertEqualsNoOrder(['a', 'b'], ['b', 'a'])", "native array comparison"); + } + @Test - public void testAssertNotSame() { - testThrowsAssertion("var a = '1'; assertNotSame(a, a)", "assertNotSame should fail comparing one variable"); - testThrowsAssertion("var a = '1'; b = a; assertNotSame(a, b)", "asserNotSame should fail comparing 2 references of the same object"); - testThrowsAssertion("assertNotSame(null, null);", "assertNotSame should fail on null values"); - testWorks("var a = '1'; b = '2'; assertNotSame(a, b)", "assertNotSame should succeed comparing 2 different variables"); - testWorks("var a = 1; assertNotSame(a, null)", "assertNotSame should succeed comparing non-null variable with a null value"); + public void testAssertSame_javascript() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "var a = '1'; assertSame(a, a)", "assertSame should succeed comparing one variable"); + testWorks(engine, "var a = '1'; b = a; assertSame(a, b)", + "asserSame should succeed comparing 2 references of the same object"); + testWorks(engine, "assertSame(null, null);", "assertSame should succeed on null values"); + testThrowsAssertion(engine, "var a = '1'; b = '2'; assertSame(a, b)", + "assertSame should fail comparing 2 different variables"); + testThrowsAssertion(engine, "var a = 1; assertSame(a, null)", + "assertSame should fail comparing non-null variable with a null value"); } - - private void testWorks(String script, String message) { + + @Test + public void testAssertSame_python() { + ScriptEngine engine = getScriptEngine(); + testWorks(engine, "a = '1'\n" + "assertSame(a, a)", "assertSame should succeed comparing one variable"); + testWorks(engine, "a = '1'\n" + "b = a\n" + "assertSame(a, b)", + "asserSame should succeed comparing 2 references of the same object"); + testWorks(engine, "assertSame(None, None)", "assertSame should succeed on null values"); + testThrowsAssertion(engine, "a = '1'\n" + "b = '2'\n" + "assertSame(a, b)", + "assertSame should fail comparing 2 different variables"); + testThrowsAssertion(engine, "a = 1\n" + "assertSame(a, None)", + "assertSame should fail comparing non-null variable with a null value"); + } + + @Test + public void testAssertNotSame_javascript() { + ScriptEngine engine = getScriptEngine(); + testThrowsAssertion(engine, "var a = '1'; assertNotSame(a, a)", + "assertNotSame should fail comparing one variable"); + testThrowsAssertion(engine, "var a = '1'; b = a; assertNotSame(a, b)", + "asserNotSame should fail comparing 2 references of the same object"); + testThrowsAssertion(engine, "assertNotSame(null, null);", "assertNotSame should fail on null values"); + testWorks(engine, "var a = '1'; b = '2'; assertNotSame(a, b)", + "assertNotSame should succeed comparing 2 different variables"); + testWorks(engine, "var a = 1; assertNotSame(a, null)", + "assertNotSame should succeed comparing non-null variable with a null value"); + } + + @Test + public void testAssertNotSame_python() { + ScriptEngine engine = getScriptEngine(); + testThrowsAssertion(engine, "a = '1'\n" + "assertNotSame(a, a)", + "assertNotSame should fail comparing one variable"); + testThrowsAssertion(engine, "a = '1'\n" + "b = a\n" + "assertNotSame(a, b)", + "asserNotSame should fail comparing 2 references of the same object"); + testThrowsAssertion(engine, "assertNotSame(None, None)", "assertNotSame should fail on null values"); + testWorks(engine, "a = '1'\n" + "b = '2'\n" + "assertNotSame(a, b)", + "assertNotSame should succeed comparing 2 different variables"); + testWorks(engine, "a = 1\n" + "assertNotSame(a, None)", + "assertNotSame should succeed comparing non-null variable with a null value"); + } + + private void testWorks(ScriptEngine engine, String script, String message) { try { engine.eval(script); } catch (ScriptException e) { @@ -145,7 +274,7 @@ public class ScriptAssertTest { } }
- private void testThrowsAssertion(String script, String message) { + private void testThrowsAssertion(ScriptEngine engine, String script, String message) { try { engine.eval(script); } catch (ScriptException e) {
commit e21a7eb14096c4b23b638ff9028eb04857710e64 Author: John Sanda jsanda@Johns-MacBook-Pro.local Date: Wed Aug 22 15:22:43 2012 -0400
[BZ 802796] Do not report entire stack trace for display in UI
After some discussion it has been decied to *not* display the entire stack trace in the resource creation error message. Instead we will display the new, detailed error message along with the more brief exception message that reports the plugin component method in which the time out occurred. The full stack trace can still however be obtained from the agent logs with DEBUG logging enabled.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java index b3c65bd..8d34e9f 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java @@ -163,8 +163,15 @@ public class CreateResourceRunner implements Callable, Runnable { status = CreateResourceStatus.TIMED_OUT; errorMessage = "The time out has been exceeded; however, the deployment may have been successful. You " + "may want to run a discovery scan to see if the deployment did complete successfully. Also consider " + - "using a higher time out value for future deployments.\n\nRoot Cause:\n"; - errorMessage += ThrowableUtil.getStackAsString(e); + "using a higher time out value for future deployments."; + + if (log.isDebugEnabled()) { + log.debug("Failed to create resource for " + report + ". " + errorMessage, e); + } else { + log.info("Failed to create resource for " + report + ". " + errorMessage, e); + } + + errorMessage += "\n\nRoot Cause:\n" + e.getMessage(); } catch (Throwable t) { status = CreateResourceStatus.FAILURE; errorMessage = ThrowableUtil.getStackAsString(t);
commit 5ffd6e1eb155bf0208690cce526fb18b832ba344 Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Aug 21 16:04:42 2012 -0400
Make drift def sync more efficient, and possibly avoid an NPE that was seen intermittently. - DriftServerServiceImpl.getDriftDefinitions() now only generates Map entries for resources with drift definitions, avoiding unnecessary list creation and subsequent processing. - Added jdoc to that effect - Changed private DriftSyncManager.syncConfigs() to syncDriftDefinitions for clarity.
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java index a6df831..1b2d048 100644 --- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java +++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/drift/DriftServerService.java @@ -121,6 +121,11 @@ public interface DriftServerService { @Asynchronous void repeatChangeSet(int resourceId, String driftDefName, int version);
+ /** + * @param resourceIds The resourceIds for which to fetch definitions. + * @return A Map from resourceId to its list of DriftDefinitions. Resources without DriftDefinitions are not included + * in the Map. + */ Map<Integer, List<DriftDefinition>> getDriftDefinitions(Set<Integer> resourceIds);
DriftSnapshot getCurrentSnapshot(int driftDefinitionId); diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java index b24849b..5f4ec36 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/sync/DriftSyncManager.java @@ -111,11 +111,11 @@ public class DriftSyncManager { synchronizer = synchronizerFactory.getRuntimeSynchronizer(driftMgr); }
- syncConfigs(synchronizer, resourceIds); + syncDriftDefinitions(synchronizer, resourceIds); syncContent(synchronizer); }
- private void syncConfigs(DriftSynchronizer synchronizer, Set<Integer> resourceIds) { + private void syncDriftDefinitions(DriftSynchronizer synchronizer, Set<Integer> resourceIds) { log.info("Starting server sync for drift definitions..."); long startTime = System.currentTimeMillis();
@@ -127,15 +127,15 @@ public class DriftSyncManager { int totalAdded = 0;
for (Integer resourceId : driftDefs.keySet()) { - Set<DriftDefinition> resourceConfigsOnServer = new TreeSet<DriftDefinition>(comparator); - resourceConfigsOnServer.addAll(driftDefs.get(resourceId)); + Set<DriftDefinition> driftDefinitionsOnServer = new TreeSet<DriftDefinition>(comparator); + driftDefinitionsOnServer.addAll(driftDefs.get(resourceId));
List<DriftDefinition> deletedDefs = synchronizer.getDeletedDefinitions(resourceId, - resourceConfigsOnServer); + driftDefinitionsOnServer); totalDeleted += deletedDefs.size(); synchronizer.purgeFromLocalInventory(resourceId, deletedDefs);
- List<DriftDefinition> addedDefs = synchronizer.getAddedDefinitions(resourceId, resourceConfigsOnServer); + List<DriftDefinition> addedDefs = synchronizer.getAddedDefinitions(resourceId, driftDefinitionsOnServer); totalAdded += addedDefs.size(); synchronizer.addToLocalInventory(resourceId, addedDefs); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java index b22caa7..b206b54 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/drift/DriftServerServiceImpl.java @@ -84,17 +84,19 @@ public class DriftServerServiceImpl implements DriftServerService { Subject overlord = getSubjectManager().getOverlord(); PageList<DriftDefinition> definitions = getDriftManager().findDriftDefinitionsByCriteria(overlord, criteria);
- Map<Integer, List<DriftDefinition>> map = new HashMap<Integer, List<DriftDefinition>>(); - for (Integer resourceId : resourceIds) { - map.put(resourceId, new ArrayList<DriftDefinition>()); - } - for (DriftDefinition c : definitions) { - List<DriftDefinition> list = map.get(c.getResource().getId()); - list.add(c); - map.put(c.getResource().getId(), list); + Map<Integer, List<DriftDefinition>> result = new HashMap<Integer, List<DriftDefinition>>(); + + for (DriftDefinition driftDef : definitions) { + Integer resourceId = driftDef.getResource().getId(); + List<DriftDefinition> list = result.get(resourceId); + if (null == list) { + list = new ArrayList<DriftDefinition>(); + result.put(resourceId, list); + } + list.add(driftDef); }
- return map; + return result; }
@Override
commit 1b9503fa343a8ae8add7a65757a7e21a96186a5b Author: John Sanda jsanda@redhat.com Date: Tue Aug 21 14:03:14 2012 -0400
Delete any old copy of AS 7 zip file to force download
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml index a640c0541..ecd2295 100644 --- a/modules/plugins/jboss-as-7/pom.xml +++ b/modules/plugins/jboss-as-7/pom.xml @@ -303,6 +303,7 @@ </condition> <property name="as7.zipfile" location="${java.io.tmpdir}/jboss-${as7.product}-${as7.version}.zip"/> + <delete file="${as7.zipfile}"/> <get src="${as7.url}" dest="${as7.zipfile}" usetimestamp="true" verbose="true"/> <unzip src="${as7.zipfile}" dest="${java.io.tmpdir}"/> <delete dir="${jboss7.home}" verbose="true"/>
commit d5ddeaababea5b8ba7573d4dc752c1636ae52f65 Author: Mike Thompson mithomps@redhat.com Date: Tue Aug 21 09:38:38 2012 -0700
Remove Opera browser support from GWT compile. Will speed up compile times from elimination of 7 language permutations.
diff --git a/modules/enterprise/gui/coregui/pom.xml b/modules/enterprise/gui/coregui/pom.xml index a4b08b0..82292eb 100644 --- a/modules/enterprise/gui/coregui/pom.xml +++ b/modules/enterprise/gui/coregui/pom.xml @@ -43,17 +43,15 @@
ie9: IE9 (although for smartgwt we fallback to IE8) ie8: IE8 - gecko: FF1 (NOTE: Support for this was dropped in GWT 2.1.) gecko1_8: FF2 and later safari: Safari/Chrome - opera: Opera
*NOTE*: Since we specify the meta "X-UA-Compatible: IE=IE8" HTTP header in CoreGUI.html, IE9 and later will emulate IE8. Multiple agents can be specified as a comma-delimited list, as demonstrated by the default value below. --> - <gwt.userAgent>ie8,ie9,gecko1_8,safari,opera</gwt.userAgent> + <gwt.userAgent>ie8,ie9,gecko1_8,safari</gwt.userAgent>
<!-- Change this to "true" via the mvn command line or your ~/.m2/settings.xml to speed up gwt compilation. --> diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml index c5c4391..f797482 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml @@ -11,11 +11,6 @@ <inherits name='com.smartgwt.SmartGwt' /> <inherits name="com.smartgwt.tools.SmartGwtTools"/>
- <!-- TODO: Consider uncommenting this instead of enabling compression in Tomcat's server.xml once we upgrade to GWT - 2.1 or later. --> - <!-- precompress .html, .js, and .css files --> - <!--<inherits name="com.google.gwt.precompress.Precompress"/>--> -
<inherits name='ca.nanometrics.gflot.GFlot'/>
@@ -66,7 +61,6 @@ ie9: IE9 (new support for IE9 with GWT 2.3.0+) gecko1_8: FF2 and later safari: Safari/Chrome - opera: Opera
*NOTE*: Since we specify the meta "X-UA-Compatible: IE=IE8" HTTP header in CoreGUI.html, IE9 and later will emulate IE8 (although the gwt IE9 js libs will still get loaded).
commit 963a082f73dd9cc4656998029bac99317b648424 Author: Jirka Kremser jkremser@redhat.com Date: Tue Aug 21 15:21:55 2012 +0200
[BZ 818083 - [IE 8.0] GUI components not aligned properly on monitoring tab] Added invisible form item on the right side
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java index 8bad3dd..9b39faa 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/measurement/AbstractMeasurementRangeEditor.java @@ -24,10 +24,12 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.List;
+import com.smartgwt.client.types.Alignment; import com.smartgwt.client.widgets.form.fields.ButtonItem; import com.smartgwt.client.widgets.form.fields.CheckboxItem; import com.smartgwt.client.widgets.form.fields.DateTimeItem; import com.smartgwt.client.widgets.form.fields.SelectItem; +import com.smartgwt.client.widgets.form.fields.SpacerItem; import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; import com.smartgwt.client.widgets.form.fields.events.ClickEvent; @@ -62,6 +64,7 @@ public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicFor private boolean displayEnableButton = false; private boolean displayRangeItemGrouping = false; protected CheckboxItem enableRangeItem; + private SpacerItem space;
private ButtonItem setButton; public static String ENABLE_RANGE_ITEM = "ENABLE_RANGE_ITEM"; @@ -83,8 +86,9 @@ public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicFor
public AbstractMeasurementRangeEditor(String locatorId) { super(locatorId); - setNumCols(12); + setNumCols(10); setWrapItemTitles(false); + setAlign(Alignment.LEFT); }
/** @@ -106,7 +110,6 @@ public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicFor setGroupTitle("Filter by: Time"); } enableRangeItem = new CheckboxItem(ENABLE_RANGE_ITEM, ""); - enableRangeItem.setStartRow(true); enableRangeItem.setShowTitle(false); enableRangeItem.setShowLabel(false); enableRangeItem.addChangeHandler(new ChangeHandler() { @@ -119,35 +122,24 @@ public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicFor
//combobox of last items simpleLastValuesItem = new SelectItem(SIMPLE_VALUE_ITEM, MSG.view_measureRange_last()); - simpleLastValuesItem.setStartRow(false); - simpleLastValuesItem.setEndRow(false); simpleLastValuesItem.setValueMap(lastValues); - simpleLastValuesItem.setWidth("*"); - simpleLastValuesItem.setRedrawOnChange(true); + simpleLastValuesItem.setTitleAlign(Alignment.LEFT);
//combobox of units of time simpleLastUnitsItem = new SelectItem(SIMPLE_UNIT_ITEM); - simpleLastUnitsItem.setStartRow(false); - simpleLastUnitsItem.setEndRow(false); simpleLastUnitsItem.setValueMap(lastUnits); simpleLastUnitsItem.setShowTitle(false); - simpleLastUnitsItem.setWidth("*"); - simpleLastUnitsItem.setRedrawOnChange(true);
//time range start from advancedStartItem = new DateTimeItem(ADVANCED_START_ITEM, MSG.view_measureRange_start()); - advancedStartItem.setStartRow(false); - advancedStartItem.setEndRow(false); + advancedStartItem.setTitleAlign(Alignment.LEFT);
//time range end advancedEndItem = new DateTimeItem(ADVANCED_END_ITEM, MSG.common_title_end()); - advancedEndItem.setStartRow(false); - advancedEndItem.setEndRow(false);
setButton = new ButtonItem(SET_ITEM, MSG.common_button_set()); setButton.setStartRow(false); setButton.setEndRow(false); - setButton.setShowTitle(false); setButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { @@ -167,30 +159,31 @@ public abstract class AbstractMeasurementRangeEditor extends LocatableDynamicFor advancedSimpleButton = new ButtonItem(ADVANCED_BUTTON_ITEM, MSG.common_button_advanced()); advancedSimpleButton.setStartRow(false); advancedSimpleButton.setEndRow(false); - advancedSimpleButton.setShowTitle(false); advancedSimpleButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent clickEvent) { advanced = !advanced; update(); } }); + + space = new SpacerItem(); + space.setWidth(300);
MetricRangePreferences metricRangePrefs = getMetricRangePreferences(); if (metricRangePrefs != null) { advanced = (metricRangePrefs.explicitBeginEnd); } - + if (displaySetButton) { setItems(simpleLastValuesItem, simpleLastUnitsItem, advancedStartItem, advancedEndItem, setButton, - advancedSimpleButton); + advancedSimpleButton, space); } else {//not displaying Set button if (displayEnableButton) { setItems(enableRangeItem, simpleLastValuesItem, simpleLastUnitsItem, advancedStartItem, - advancedEndItem, advancedSimpleButton); - setNumCols(9);//extend to encompass expanded + advancedEndItem, advancedSimpleButton, space); } else { setItems(simpleLastValuesItem, simpleLastUnitsItem, advancedStartItem, advancedEndItem, - advancedSimpleButton); + advancedSimpleButton, space); } } update();
commit 2f1ce1944b3307fa790225f91889fc642abfcc0e Author: Lukas Krejci lkrejci@redhat.com Date: Tue Aug 21 10:57:28 2012 +0200
[BZ 840662] - Python scripting is now bundled by default with RHQ. It can be excluded by explicitely switching off the "bundle-additional-script-languages" profile. E.g. mvn clean install -P '!bundle-additional-script-languages'
diff --git a/modules/enterprise/remoting/cli/pom.xml b/modules/enterprise/remoting/cli/pom.xml index 3924ff0..e0e4243 100644 --- a/modules/enterprise/remoting/cli/pom.xml +++ b/modules/enterprise/remoting/cli/pom.xml @@ -34,6 +34,13 @@ </dependency>
<dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-scripting-javascript</artifactId> + <version>${project.version}</version> + <scope>runtime</scope> + </dependency> + + <dependency> <groupId>${project.groupId}</groupId> <artifactId>rhq-core-domain</artifactId> <version>${project.version}</version> @@ -131,6 +138,7 @@ <property name="persistence-api.version" value="${persistence-api.version}" /> <property name="rhq.client.build.exclude.cli.jar" value="${rhq.client.build.exclude.cli.jar}" /> <property name="rhq.client.build.include.client.jar" value="${rhq.client.build.include.client.jar}" /> + <property name="rhq.bundle-additional-script-languages" value="${rhq.bundle-additional-script-languages}"/> </ant> </target> </configuration> @@ -220,6 +228,25 @@
<profiles>
+ <!-- NOTE: this profile HAS TO have the same activation policy as the profile with the same name in the root pom.xml of RHQ --> + <profile> + <id>bundle-additional-script-languages</id> + <activation> + <property> + <name>java.home</name> + </property> + </activation> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>rhq-scripting-python</artifactId> + <version>${project.version}</version> + <scope>runtime</scope> + </dependency> + </dependencies> + </profile> + <!-- Unlike most of RHQ, this module requires JDK6, so replace the Java 5 bootclasspath that was added to the compiler args by the root POM with a bootclasspath based on the java.home sysprop (which should be Java 6 or later if the enforcer plugin did its job). --> <profile> <id>check-java-api</id> diff --git a/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml b/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml index 808bd82..715bd9b 100644 --- a/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml +++ b/modules/enterprise/remoting/cli/src/main/scripts/rhq-client.build.xml @@ -70,6 +70,15 @@
<copy file="${settings.localRepository}/org/rhq/rhq-scripting-api/${project.version}/rhq-scripting-api-${project.version}.jar" tofile="${lib.home}/rhq-scripting-api-${project.version}.jar" verbose="true" /> <copy file="${settings.localRepository}/org/rhq/rhq-scripting-javascript/${project.version}/rhq-scripting-javascript-${project.version}.jar" tofile="${lib.home}/rhq-scripting-javascript-${project.version}.jar" verbose="true" /> + + <echo>*** Including additional script languages: ${rhq.bundle-additional-script-languages}</echo> + <!-- Copy all the additional script language support jars if we are told to do so --> + <copy todir="${lib.home}" verbose="true"> + <fileset dir="${settings.localRepository}/org/rhq"> + <include if="${rhq.bundle-additional-script-languages}" name="**/rhq-scripting-python-${project.version}.jar"/> + </fileset> + <mapper type="flatten" /> + </copy> </target>
<target name="prepare-samples-dir"> diff --git a/modules/enterprise/scripting/javascript/pom.xml b/modules/enterprise/scripting/javascript/pom.xml index 38ead44..adbe85a 100644 --- a/modules/enterprise/scripting/javascript/pom.xml +++ b/modules/enterprise/scripting/javascript/pom.xml @@ -22,6 +22,8 @@ <groupId>org.mozilla</groupId> <artifactId>rhino</artifactId> <version>1.7R4</version> + <!-- we actually repackage Rhino inside our jar --> + <scope>provided</scope> </dependency> </dependencies>
diff --git a/modules/enterprise/scripting/pom.xml b/modules/enterprise/scripting/pom.xml index c786cdc..f439f11 100644 --- a/modules/enterprise/scripting/pom.xml +++ b/modules/enterprise/scripting/pom.xml @@ -17,11 +17,12 @@ </modules>
<profiles> + <!-- NOTE: this profile HAS TO have the same activation policy as the profile with the same name in the root pom.xml of RHQ --> <profile> - <id>experimental</id> + <id>bundle-additional-script-languages</id> <activation> <property> - <name>experimental-script-languages</name> + <name>java.home</name> </property> </activation>
diff --git a/modules/enterprise/scripting/python/pom.xml b/modules/enterprise/scripting/python/pom.xml index 39d3895..4b34699 100644 --- a/modules/enterprise/scripting/python/pom.xml +++ b/modules/enterprise/scripting/python/pom.xml @@ -21,6 +21,8 @@ <groupId>org.python</groupId> <artifactId>jython-standalone</artifactId> <version>2.5.2</version> + <!-- we actually repackage jython inside our jar --> + <scope>provided</scope> </dependency> </dependencies>
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml index 10b613e..0bed079 100644 --- a/modules/enterprise/server/ear/pom.xml +++ b/modules/enterprise/server/ear/pom.xml @@ -447,6 +447,26 @@
<profiles>
+ <!-- NOTE: this profile HAS TO have the same activation policy as the profile with the same name in the root pom.xml of RHQ --> + <profile> + <id>bundle-additional-script-languages</id> + <activation> + <property> + <!-- we want this always active but activeByDefault doesn't work --> + <!-- see http://maven.apache.org/guides/introduction/introduction-to-profiles.html --> + <name>java.home</name> + </property> + </activation> + + <dependencies> + <dependency> + <groupId>org.rhq</groupId> + <artifactId>rhq-scripting-python</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </profile> + <profile> <id>bundle-plugins</id> <activation> diff --git a/pom.xml b/pom.xml index 36b9c62..f6bd80d 100644 --- a/pom.xml +++ b/pom.xml @@ -1171,6 +1171,25 @@
<profiles>
+ <!-- NOTE: This profile is extended upon in several other submodules. + If you need to change its activation policy, make sure to do that in + *ALL* the modules that define this profile. --> + <profile> + <id>bundle-additional-script-languages</id> + <activation> + <property> + <!-- we want this always active but activeByDefault doesn't work --> + <!-- see http://maven.apache.org/guides/introduction/introduction-to-profiles.html --> + <name>java.home</name> + </property> + </activation> + + <!-- Can be used to pass a flag down to deployment composing ANT scripts and somesuch --> + <properties> + <rhq.bundle-additional-script-languages>true</rhq.bundle-additional-script-languages> + </properties> + </profile> + <profile> <id>ojdbc-driver</id> <activation>
commit 851461ab89dac1da41b9c85ae1d87eac54de2ef3 Author: Stefan Negrea snegrea@redhat.com Date: Mon Aug 20 14:42:06 2012 -0500
[BZ 830841] Added a descriptive error message for cases where content is not available for a resource. The user is asked to try again in a few minutes if content was deployed recently since the deploy and discovery process might still be running.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java index 0199c77..7361fe8 100644 --- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java +++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java @@ -576,19 +576,25 @@ public class ResourceClientProxy {
InstalledPackage installedPackage = getBackingContent();
- if (fileName == null ) - fileName = installedPackage.getPackageVersion().getFileName(); - - File file = new File(fileName); + if (installedPackage != null) { + if (fileName == null) { + fileName = installedPackage.getPackageVersion().getFileName(); + }
- byte[] data = remoteClient.getProxy(ContentManagerRemote.class).getPackageBytes( - remoteClient.getSubject(), resourceClientProxy.resourceId, installedPackage.getId()); + File file = new File(fileName);
- FileOutputStream fos = new FileOutputStream(file); - try { - fos.write(data); - } finally { - fos.close(); + byte[] data = remoteClient.getProxy(ContentManagerRemote.class).getPackageBytes( + remoteClient.getSubject(), resourceClientProxy.resourceId, installedPackage.getId()); + + FileOutputStream fos = new FileOutputStream(file); + try { + fos.write(data); + } finally { + fos.close(); + } + } else { + throw new RuntimeException( + "Content not available in the content repository. If you recently deployed content to this resource, then the content repository has not yet received the content or content information. The content for a resource is available only after the deployment and discovery process completes. Please try again in a few minutes."); } }
commit 414ccdf3fd964dc6d64abe511ec02f4e9170aa40 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Aug 20 14:59:13 2012 -0400
[Bug 849751 - RFE: protect resource tree from direct navigation to a resource with many siblings] Apply the new ResourceManager.findResourcesByCriteriaBounded() method to getResourceLineageAndSiblings() in order to similarly bound the initial tree building fetch. Currently getResourceLineageAndSiblings() will use the defaults applied to findResourcesByCriteriaBounded(), although we may find that providing separate overrides will be useful.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java index 0fe906a..a016f8e 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java @@ -113,6 +113,7 @@ import org.rhq.core.domain.resource.group.composite.AutoGroupComposite; import org.rhq.core.domain.server.PersistenceUtility; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; +import org.rhq.core.domain.util.PageOrdering; import org.rhq.core.util.IntExtractor; import org.rhq.core.util.collection.ArrayUtils; import org.rhq.enterprise.server.RHQConstants; @@ -796,14 +797,16 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
// If the ancestor is not locked, include viewable children. if (!ancestor.isLocked() || ancestor.getResource() == parent) { - // Get all viewable committed children. - PageList<Resource> children = findChildResourcesByCategoryAndInventoryStatus(subject, - ancestor.getResource(), null, InventoryStatus.COMMITTED, PageControl.getUnlimitedInstance()); + // Get viewable committed children, but bounded to ensure it's not an overwhelming return set + ResourceCriteria criteria = new ResourceCriteria(); + criteria.addFilterParentResourceId(ancestor.getResource().getId()); + criteria.addSortName(PageOrdering.ASC); + List<Resource> children = findResourcesByCriteriaBounded(subject, criteria, 0, 0); // Remove any that are in the lineage to avoid repeated handling. children.removeAll(rawResourceLineage); for (Resource child : children) { - // Ensure the parentResource field is fetched. - //noinspection ConstantConditions + // Ensure the parentResource field is fetched. (do this here and not via criteria.fetchParentResource + // because that option would require inventory manager perm) child.getParentResource().getId(); // The query only returned viewable children, so the composite should not be locked. boolean isLocked = false;
commit 722b5c83eac64fd145863a154147f9bb0e1cf67a Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Aug 20 14:24:29 2012 -0400
trivial - fix some DriftManager logging
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java index 0924288..8b54320 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/DriftManager.java @@ -479,7 +479,7 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri
@Override public void updateDriftDetection(int resourceId, DriftDefinition driftDefinition) { - log.info("Recived request to update schedule for " + toString(resourceId, driftDefinition)); + log.info("Received request to update schedule for " + toString(resourceId, driftDefinition));
DriftDetectionSchedule updatedSchedule = schedulesQueue.update(resourceId, driftDefinition); if (updatedSchedule == null) { @@ -696,7 +696,7 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri case pluginConfiguration: { baseLocation = resource.getPluginConfiguration().getSimpleValue(baseDirValueName, null); if (baseLocation == null) { - throw new IllegalArgumentException("Cannot determine the bundle base deployment location - " + throw new IllegalArgumentException("Cannot determine the base directory - " + "there is no plugin configuration setting for [" + baseDirValueName + "]"); } break; @@ -704,7 +704,7 @@ public class DriftManager extends AgentService implements DriftAgentService, Dri case resourceConfiguration: { baseLocation = resource.getResourceConfiguration().getSimpleValue(baseDirValueName, null); if (baseLocation == null) { - throw new IllegalArgumentException("Cannot determine the bundle base deployment location - " + throw new IllegalArgumentException("Cannot determine the base directory - " + "there is no resource configuration setting for [" + baseDirValueName + "]"); } break;
commit 155c66f5fa5ac816de6ce8693875cc746f80096d Author: Mike Thompson mithomps@redhat.com Date: Mon Aug 20 09:31:13 2012 -0700
[BZ 848529 - Creating a domain deployment spins and never uploads the WAR on IE8]. IE8 had issues registering the listener when the upload was complete. This was a regression caused by smartgwt3.0 upgrade.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/DynamicCallbackFormImplIE8.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/DynamicCallbackFormImplIE8.java new file mode 100644 index 0000000..89c1615 --- /dev/null +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/upload/DynamicCallbackFormImplIE8.java @@ -0,0 +1,50 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.rhq.enterprise.gui.coregui.client.components.upload; + +import com.google.gwt.dom.client.Element; + +/** + * Implementation class used by {@link com.google.gwt.user.client.ui.FormPanel}. + */ +public class DynamicCallbackFormImplIE8 extends DynamicCallbackFormImpl { + + @Override + public native void hookEvents(Element iframe, + DynamicCallbackFormImplHost listener) /*-{ + if (iframe) { + iframe.onreadystatechange = function() { + // If there is no __formAction yet, this is a spurious onreadystatechange + // generated when the iframe is first added to the DOM. + if (!iframe.__formAction) + return; + + if (iframe.readyState == 'complete') { + // If the iframe's contentWindow has not navigated to the expected action + // url, then it must be an error, so we ignore it. + listener.@org.rhq.enterprise.gui.coregui.client.components.upload.DynamicCallbackFormImplHost::onFrameLoad()(); + } + }; + } + }-*/; + + @Override + public native void unhookEvents(Element iframe) /*-{ + if (iframe) + iframe.onreadystatechange = null; + }-*/; + +} \ No newline at end of file diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml index 78db5af..c5c4391 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml @@ -39,6 +39,12 @@ <when-type-is class="org.rhq.enterprise.gui.coregui.client.components.upload.DynamicCallbackFormImpl"/> </replace-with>
+ <!-- Special case for IE8 where upload onsubmit handlers need special registration code from other browsers --> + <replace-with class="org.rhq.enterprise.gui.coregui.client.components.upload.DynamicCallbackFormImplIE8"> + <when-type-is class="org.rhq.enterprise.gui.coregui.client.components.upload.DynamicCallbackFormImpl"/> + <when-property-is name="user.agent" value="ie8"/> + </replace-with> +
<generate-with class="org.rhq.enterprise.gui.coregui.user.rebind.rpc.TrackingServiceInterfaceProxyGenerator"> <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/>
commit dc966bdbe0ef18915cba3a1cdd69c4167f5bd4c1 Author: Mike Thompson mithomps@redhat.com Date: Fri Aug 10 15:29:53 2012 -0700
Removed unused methods from ImageManager.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java index e50fe14..a15857e 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/ImageManager.java @@ -403,9 +403,6 @@ public class ImageManager { return "subsystems/availability/availability_yellow_16.png"; }
- public static String getAvailabilityYellowLargeIcon() { - return "subsystems/availability/availability_yellow_24.png"; - }
public static String getAvailBarImagePath(AvailabilityType availType) {
@@ -437,13 +434,6 @@ public class ImageManager { return "subsystems/alert/Flag_blue_16.png"; }
- public static String getAlertLargeIcon() { - return "subsystems/alert/Flag_blue_24.png"; - } - - public static String getAlertEditIcon() { - return "subsystems/alert/Edit_Alert.png"; - }
public static String getMetricEditIcon() { return "subsystems/monitor/Edit_Metric.png"; @@ -551,9 +541,6 @@ public class ImageManager { return "subsystems/event/" + severity.name() + "_16.png"; }
- public static String getEventLargeIcon() { - return "subsystems/event/Events_24.png"; - }
public static String getEventIcon() { return "subsystems/event/Events_16.png"; @@ -563,45 +550,25 @@ public class ImageManager { return "subsystems/monitor/Monitor_16.png"; }
- public static String getMonitorLargeIcon() { - return "subsystems/monitor/Monitor_24.png"; - }
public static String getMonitorFailedIcon() { return "subsystems/monitor/Monitor_failed_16.png"; }
- public static String getMonitorFailedLargeIcon() { - return "subsystems/monitor/Monitor_failed_24.png"; - } - - public static String getOperationLargeIcon() { - return "subsystems/control/Operation_24.png"; - } - public static String getOperationIcon() { return "subsystems/control/Operation_16.png"; }
- public static String getActivityPackageLargeIcon() { - return "subsystems/content/Package_24.png"; - }
public static String getActivityPackageIcon() { return "subsystems/content/Package_16.png"; }
- public static String getBundleLargeIcon() { - return "subsystems/content/Content_24.png"; - }
public static String getBundleIcon() { return "subsystems/content/Content_16.png"; }
- public static String getConfigureLargeIcon() { - return "subsystems/configure/Configure_24.png"; - }
public static String getConfigureIcon() { return "subsystems/configure/Configure_16.png";
commit 8732f82745b97897372ce0d00a9b3ac0773fedea Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Aug 20 11:46:10 2012 -0400
Add unit test for new ResourceManager.findResourcesByCriteriaBounded().
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/LargeGroupCriteriaTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/LargeGroupCriteriaTest.java index 93bb887..323cf5c 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/LargeGroupCriteriaTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/LargeGroupCriteriaTest.java @@ -21,17 +21,21 @@ package org.rhq.enterprise.server.resource.group.test; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; +import java.util.List;
import org.testng.annotations.AfterMethod; import org.testng.annotations.Test;
import org.rhq.core.domain.authz.Permission; +import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.criteria.ResourceGroupCriteria; import org.rhq.core.domain.resource.InventoryStatus; import org.rhq.core.domain.resource.Resource; 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.enterprise.server.authz.AuthorizationManagerLocal; +import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal; import org.rhq.enterprise.server.test.LargeGroupTestBase; import org.rhq.enterprise.server.test.TestServerCommunicationsService; @@ -189,6 +193,57 @@ public class LargeGroupCriteriaTest extends LargeGroupTestBase { testGroupQueries(gacs); }
+ // test findResourcesByCriteriaBounded here instead of ResourceGroupManagerBeanTest because we want + // to work with a decent # or resources. + @Test(enabled = TEST_ENABLED) + public void testResourceCriteriaBounded() throws Exception { + ArrayList<GroupAvailCounts> gacs = new ArrayList<LargeGroupCriteriaTest.GroupAvailCounts>(); + gacs.add(new GroupAvailCounts(1100, 0, 0, 0)); // purposefully over 1,000, avails don't really matter + + ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); + AuthorizationManagerLocal authManager = LookupUtil.getAuthorizationManager(); + + env = new ArrayList<LargeGroupEnvironment>(gacs.size()); + + LargeGroupEnvironment lgeWithTypes = null; + for (GroupAvailCounts gac : gacs) { + env.add(createLargeGroupWithNormalUserRoleAccessWithInventoryStatus(lgeWithTypes, gac.total, gac.down, + gac.unknown, gac.disabled, gac.uncommitted, Permission.CONFIGURE_READ)); + lgeWithTypes = env.get(0); + } + + ResourceCriteria criteria = new ResourceCriteria(); + List<Resource> result; + + SessionTestHelper.simulateLogin(env.get(0).normalSubject); + + criteria.addFilterParentResourceId(lgeWithTypes.platformResource.getId()); + criteria.setPageControl(PageControl.getUnlimitedInstance()); + result = resourceManager.findResourcesByCriteria(env.get(0).normalSubject, criteria); + assert null != result; + assert result.size() == 1100 : "Expected unbounded query to return all 1100 resources"; + + result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 2000, 100); + assert null != result; + assert result.size() == 1100 : "Expected 2000/100 bounded query to return all 1100 resources"; + + result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 1100, 100); + assert null != result; + assert result.size() == 1100 : "Expected 1100/100 bounded query to return all 1100 resources"; + + result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 0, 0); + assert null != result; + assert result.size() == 200 : "Expected default (1000/200) bounded query to return 200 resources"; + + result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 0, 500); + assert null != result; + assert result.size() == 500 : "Expected default (1000)/500) bounded query to return 500 resources"; + + result = resourceManager.findResourcesByCriteriaBounded(env.get(0).normalSubject, criteria, 100, 200); + assert null != result; + assert result.size() == 100 : "Expected 100/200 bounded query to return 100 resources"; + } + private PageList<ResourceGroupComposite> testGroupQueriesWithSearchBar(GroupAvailCounts gac, String searchExpression) throws Exception { ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager();
commit 8cd529eb7b04e785ded5c7a3fb6e633e6bc90cc4 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Aug 20 10:25:47 2012 -0400
Reformat only!
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java index f0fe5b7..deac357 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java @@ -113,102 +113,89 @@ public class ResourceManagerBeanTest extends UpdatePluginMetadataTestBase { assert errors.size() == 0; }
- public void testResourceLineage() throws Exception { - // given a resource id for the leaf resource in a resource hierarchy - int leafResourceId = givenASampleResourceHierarchy(); + // given a resource id for the leaf resource in a resource hierarchy + int leafResourceId = givenASampleResourceHierarchy();
- // when - List<Resource> resourceLineage = resourceManager.getResourceLineage(leafResourceId); + // when + List<Resource> resourceLineage = resourceManager.getResourceLineage(leafResourceId);
assertEquals(resourceLineage.size(), 4); - - // then - StringBuilder stringBuilder = new StringBuilder(); - for (Resource resource : resourceLineage) { - stringBuilder.append(resource.getName()); - if (resourceLineage.indexOf(resource) != resourceLineage.size() - 1) { - stringBuilder.append("::"); - } - } - System.err.println(stringBuilder.toString()); + + // then + StringBuilder stringBuilder = new StringBuilder(); + for (Resource resource : resourceLineage) { + stringBuilder.append(resource.getName()); + if (resourceLineage.indexOf(resource) != resourceLineage.size() - 1) { + stringBuilder.append("::"); + } + } + System.err.println(stringBuilder.toString());
// cleanup the DB - for (int i = resourceLineage.size() - 1; i >=0; i--) { + for (int i = resourceLineage.size() - 1; i >= 0; i--) { deleteNewResourceAgentResourceType(resourceLineage.get(i)); } }
- private int givenASampleResourceHierarchy() throws NotSupportedException, - SystemException { - getTransactionManager().begin(); - EntityManager em = getEntityManager(); - int leafResourceId = 0; - try { - ResourceType platformType = createResourceType(em, "platform" - + System.currentTimeMillis(), "test", null, - ResourceCategory.PLATFORM); - ResourceType appserverType = createResourceType(em, "jboss AS 5" - + System.currentTimeMillis(), "jbossas5", platformType, - ResourceCategory.SERVER); - ResourceType jvmType = createResourceType(em, - "JVM" + System.currentTimeMillis(), "jbossas5", - appserverType, ResourceCategory.SERVICE); - ResourceType memType = createResourceType(em, "Memory Subsystem" - + System.currentTimeMillis(), "jbossas5", jvmType, - ResourceCategory.SERVICE); - Agent agent = new Agent("agent" + System.currentTimeMillis(), "host" + System.currentTimeMillis(), 1, "", + private int givenASampleResourceHierarchy() throws NotSupportedException, SystemException { + getTransactionManager().begin(); + EntityManager em = getEntityManager(); + int leafResourceId = 0; + try { + ResourceType platformType = createResourceType(em, "platform" + System.currentTimeMillis(), "test", null, + ResourceCategory.PLATFORM); + ResourceType appserverType = createResourceType(em, "jboss AS 5" + System.currentTimeMillis(), "jbossas5", + platformType, ResourceCategory.SERVER); + ResourceType jvmType = createResourceType(em, "JVM" + System.currentTimeMillis(), "jbossas5", + appserverType, ResourceCategory.SERVICE); + ResourceType memType = createResourceType(em, "Memory Subsystem" + System.currentTimeMillis(), "jbossas5", + jvmType, ResourceCategory.SERVICE); + Agent agent = new Agent("agent" + System.currentTimeMillis(), "host" + System.currentTimeMillis(), 1, "", "token" + System.currentTimeMillis()); - em.persist(agent); - em.flush(); - - Resource platform = createResource(em, platformType, agent, - "platformKey" + System.currentTimeMillis(), - "host.dev.corp", null); - Resource appserver = createResource(em, appserverType, agent, - "JEAP" + System.currentTimeMillis(), "JBOSS EAP 5.1.1", - platform); - Resource jvm = createResource(em, jvmType, agent, "jvm" - + System.currentTimeMillis(), "JBoss AS JVM", appserver); - Resource memSubystem = createResource(em, memType, agent, - "mem" + System.currentTimeMillis(), "Memory Subsystem", jvm); - leafResourceId = memSubystem.getId(); - - getTransactionManager().commit(); - } catch (Exception e) { - try { + em.persist(agent); + em.flush(); + + Resource platform = createResource(em, platformType, agent, "platformKey" + System.currentTimeMillis(), + "host.dev.corp", null); + Resource appserver = createResource(em, appserverType, agent, "JEAP" + System.currentTimeMillis(), + "JBOSS EAP 5.1.1", platform); + Resource jvm = createResource(em, jvmType, agent, "jvm" + System.currentTimeMillis(), "JBoss AS JVM", + appserver); + Resource memSubystem = createResource(em, memType, agent, "mem" + System.currentTimeMillis(), + "Memory Subsystem", jvm); + leafResourceId = memSubystem.getId(); + + getTransactionManager().commit(); + } catch (Exception e) { + try { System.out.println("CANNOT Prepare TEST: Cause: " + e); getTransactionManager().rollback(); } catch (Exception ignore) { } - } finally { - em.close(); - } - return leafResourceId; - } - - private Resource createResource(EntityManager em, ResourceType platformType, - Agent agent, String resourceKey, String resourceName, - Resource parent) { - Resource resource = new Resource(resourceKey, resourceName, platformType); + } finally { + em.close(); + } + return leafResourceId; + } + + private Resource createResource(EntityManager em, ResourceType platformType, Agent agent, String resourceKey, + String resourceName, Resource parent) { + Resource resource = new Resource(resourceKey, resourceName, platformType); resource.setUuid(UUID.randomUUID().toString()); resource.setAgent(agent); resource.setParentResource(parent); em.persist(resource); return resource; - } - - - private ResourceType createResourceType(EntityManager em, String name, - String pluginName, ResourceType parentResourceType, - ResourceCategory resourceCategory) { - ResourceType platformType = new ResourceType(name, pluginName, - resourceCategory, parentResourceType); - ResourceType resourceType = platformType; - em.persist(resourceType); - return resourceType; - } + }
+ private ResourceType createResourceType(EntityManager em, String name, String pluginName, + ResourceType parentResourceType, ResourceCategory resourceCategory) { + ResourceType platformType = new ResourceType(name, pluginName, resourceCategory, parentResourceType); + ResourceType resourceType = platformType; + em.persist(resourceType); + return resourceType; + }
private Resource createNewResourceWithNewType() throws Exception { getTransactionManager().begin(); @@ -257,7 +244,7 @@ public class ResourceManagerBeanTest extends UpdatePluginMetadataTestBase { resourceManager.uninventoryResourceAsyncWork(superuser, deletedResourceId); } em.flush(); - + ResourceType type = em.find(ResourceType.class, resource.getResourceType().getId()); System.out.println("Removing " + type + "..."); em.remove(type);
commit 5d472dceb665ec2e4b8b8c528c59c8c8b354d40d Author: John Sanda jsanda@redhat.com Date: Mon Aug 20 11:39:51 2012 -0400
[BZ 848893] Only hide empty groups for availability queries/searches
This regression was introduced during the work for BZ 826493. While testing the changes for this commit, I came across another, related issue where an empty compatible group does not show up in the compatible groups view. It does however show up in the mixed groups view. An empty mixed group appears in the mixed group view. This issue is already logged under BZ 708929.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java index e269475..a799311 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java @@ -50,7 +50,6 @@ import org.rhq.enterprise.gui.coregui.client.ImageManager; import org.rhq.enterprise.gui.coregui.client.Messages; import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync; -import org.rhq.enterprise.gui.coregui.client.util.Log; import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource; import org.rhq.enterprise.gui.coregui.client.util.message.Message;
@@ -125,12 +124,16 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou processResponse(request.getRequestId(), response); }
- private PageList<ResourceGroupComposite> filterEmptyMemberGroups(PageList<ResourceGroupComposite> result){ + private PageList<ResourceGroupComposite> applyAvailabilitySearchFilter( + PageList<ResourceGroupComposite> result){
+ if (!isAvailabilitySearch(criteria)) { + return result; + } PageList<ResourceGroupComposite> pageList = new PageList<ResourceGroupComposite>(result.getPageControl());
for (ResourceGroupComposite rgc : result) { - if (rgc.getExplicitCount() > 0 ){ + if (rgc.getExplicitCount() > 0) { pageList.add(rgc); } } @@ -139,7 +142,7 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou }
public void onSuccess(PageList<ResourceGroupComposite> result) { - PageList<ResourceGroupComposite> filteredResult = filterEmptyMemberGroups(result); + PageList<ResourceGroupComposite> filteredResult = applyAvailabilitySearchFilter(result); response.setData(buildRecords(filteredResult)); response.setTotalRows(filteredResult.getTotalSize()); // for paging to work we have to specify size of full result set processResponse(request.getRequestId(), response); @@ -147,6 +150,10 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou }); }
+ private boolean isAvailabilitySearch(ResourceGroupCriteria criteria) { + return criteria.getSearchExpression() != null && criteria.getSearchExpression().startsWith("availability"); + } + @Override protected ResourceGroupCriteria getFetchCriteria(final DSRequest request) { ResourceGroupCriteria criteria = new ResourceGroupCriteria();
commit c62b143dd5f065b54caf6692d3c04929d8b4539f Author: Stefan Negrea snegrea@redhat.com Date: Fri Aug 17 14:30:35 2012 -0500
[BZ 841684] Add config option to the wrapper script.
diff --git a/modules/enterprise/agent/src/etc/rhq-agent-wrapper.sh b/modules/enterprise/agent/src/etc/rhq-agent-wrapper.sh index 68d1856..f03c83a 100755 --- a/modules/enterprise/agent/src/etc/rhq-agent-wrapper.sh +++ b/modules/enterprise/agent/src/etc/rhq-agent-wrapper.sh @@ -246,6 +246,44 @@ case "$1" in fi ;;
+'config') + prepare_pid_dir + + if [ "$_RUNNING" = "1" ]; then + echo "Cannot run config - please stop the agent before running config" + echo $_STATUS + exit 0 + fi + + echo "Configure RHQ Agent..." + + # Determine the command to execute when starting the agent + if [ -z "$RHQ_AGENT_START_COMMAND" ]; then + # Find out where the agent start script is located + _START_SCRIPT="${RHQ_AGENT_HOME}/bin/rhq-agent.sh" + + if [ ! -f "$_START_SCRIPT" ]; then + echo "ERROR! Cannot find the RHQ Agent start script" + echo "Not found: $_START_SCRIPT" + exit 1 + fi + debug_wrapper_msg "Start script found here: $_START_SCRIPT" + + RHQ_AGENT_START_COMMAND="${_START_SCRIPT}" + fi + + RHQ_AGENT_CMDLINE_OPTS="--cleanconfig --nostart --daemon --setup --advanced" + export RHQ_AGENT_CMDLINE_OPTS + + # start the agent now! + if [ -n "$RHQ_AGENT_DEBUG" ] && [ "$RHQ_AGENT_DEBUG" != "false" ]; then + debug_wrapper_msg "Executing agent with command: ${RHQ_AGENT_START_COMMAND} ${RHQ_AGENT_CMDLINE_OPTS}" + fi + + . $RHQ_AGENT_START_COMMAND + + ;; + 'stop') prepare_pid_dir
@@ -326,7 +364,7 @@ case "$1" in exit $? ;; *) - echo "Usage: $0 { start | stop | kill | restart | status }" + echo "Usage: $0 { start | stop | kill | restart | status | config }" exit 1 ;; esac
commit 30c5e81759f5166873e49fd3486614c282203f47 Author: Lukas Krejci lkrejci@redhat.com Date: Fri Aug 17 19:20:48 2012 +0200
[BZ 834353] - Distinguish between BRMS 5.(1|2).0 and EWP 5.1.x by looking for BRMS specific jars in the client directory.
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstallationInfo.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstallationInfo.java index cae73f3..a45237d 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstallationInfo.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossInstallationInfo.java @@ -23,6 +23,7 @@ package org.rhq.plugins.jbossas5.helper;
import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.util.jar.Attributes; import java.util.jar.JarFile; @@ -43,11 +44,11 @@ public class JBossInstallationInfo { private static final String EPP_IMPL_VERSION_PREFIX = "JBoss-EPP"; private static final ComparableVersion VERSION_4_2 = new ComparableVersion("4.2");
- private final JBossProductType productType; - private final String version; - private final String defaultBindAddress; - private final boolean isEap; - private final String majorVersion; + private JBossProductType productType; + private String version; + private String defaultBindAddress; + private boolean isEap; + private String majorVersion;
public JBossInstallationInfo(File installationDir) throws IOException { File binDir = new File(installationDir, "bin"); @@ -63,11 +64,47 @@ public class JBossInstallationInfo { if (-1 == majorVersionIndex) { throw new RuntimeException("Unexpected run.jar implementation version, can't parse: " + this.version); } + + fixProductTypeAndVersion(jarManifestAttributes, installationDir); + this.defaultBindAddress = getDefaultServerName(this.version); this.isEap = determineEap(jarManifestAttributes); this.majorVersion = version.substring(0, version.indexOf('.')); }
+ /** + * Tries to make sense of the mess of JBoss product versioning. + * + * @param jarManifestAttributes + * @param installationDir + */ + private void fixProductTypeAndVersion(Attributes jarManifestAttributes, File installationDir) { + //the main mess is with BRMS < 5.3.0 being advertised as EWP + if (productType == JBossProductType.EWP && version.startsWith("5.1")) { + //this still can be a BRMS server... We can check that by looking for drools jars + //in the client. Brittle you say? Yes, of course ;) + File client = new File(installationDir, "client"); + if (client.exists() && client.isDirectory()) { + boolean containsBrmsJars = false; + + for(String file : client.list()) { + if (file.endsWith("BRMS.jar")) { + containsBrmsJars = true; + break; + } + } + + if (containsBrmsJars) { + productType = JBossProductType.BRMS; + if ("5.1.1".equals(version)) { + //BRMS 5.2.0 is based on EWP 5.1.1 + version = "5.2.0"; + } + } + } + } + } + public JBossProductType getProductType() { return this.productType; } diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProductType.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProductType.java index de5d837..312ea80 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProductType.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/JBossProductType.java @@ -54,7 +54,12 @@ public enum JBossProductType {
/** * Determines the product type (AS, EAP, EWP, or SOA) based on the Implementation-Title MANIFEST.MF attribute. - * + * <p> + * Note that this method is <b>NOT</b> always correct about the actual version of the product, because + * certain version of certain products don't advertise the correct product/version in the manifest. + * <p> + * Use {@link JBossInstallationInfo} for a more thorough detection of the type and version of a product. + * * @param attributes the attributes from a manifest file (typically run.jar or jboss-j2ee.jar) * * @return the product type (AS, EAP, EWP, or SOA)
commit 32ad4e17b0f75fcccb84107e01956a519175670f Author: Stefan Negrea snegrea@redhat.com Date: Fri Aug 17 09:09:04 2012 -0500
[BZ 848800] Adding back old constructor signature for backwards compatibility reasons. Marked the old constructor as deprecated.
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/CreateChildResourceFacetDelegate.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/CreateChildResourceFacetDelegate.java index af18723..c5e85bb 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/CreateChildResourceFacetDelegate.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/helper/CreateChildResourceFacetDelegate.java @@ -59,6 +59,19 @@ public class CreateChildResourceFacetDelegate implements CreateChildResourceFace this.parentResourceContext = parentResourceContext; }
+ /** + * @deprecated This constructor is deprecated because it does not handle properly the SHA256 computation for + * exploded content. If used, this constructor will lead to a calculation of the SHA256 for exploded content + * based on exploded files. This method of computation is not preferred due to changes in content archive + * matching. Replaced by (@link {@link #CreateChildResourceFacetDelegate(ProfileServiceComponent, ResourceContext)} + * + * @param component component + */ + @Deprecated + public CreateChildResourceFacetDelegate(ProfileServiceComponent component) { + this.component = component; + } + public CreateResourceReport createResource(CreateResourceReport createResourceReport) { // ProfileServiceFactory.refreshCurrentProfileView(); ResourceType resourceType = createResourceReport.getResourceType();
commit f0f52f180b65682996586b4a0438a1865cae8381 Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Aug 16 16:06:57 2012 -0400
Adding perftest scenario support to help test bug 784571
diff --git a/modules/plugins/perftest/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/perftest/src/main/resources/META-INF/rhq-plugin.xml index 72fae98..7a34f7e 100644 --- a/modules/plugins/perftest/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/perftest/src/main/resources/META-INF/rhq-plugin.xml @@ -114,6 +114,14 @@ </resource-configuration> </service>
+ <service name="service-gamma" class="PerfTestComponent" discovery="PerfTestDiscoveryComponent" description="Omega Service Gamma"> + <plugin-configuration> + <c:simple-property name="gamma-property0"/> + </plugin-configuration> + + <metric displayName="Gamma Metric 0" property="gamma-metric0" defaultOn="false"/> + </service> + </server>
<!-- try to make server-a and its children representative of "average" resources --> diff --git a/modules/plugins/perftest/src/main/resources/configurable-7.xml b/modules/plugins/perftest/src/main/resources/configurable-7.xml new file mode 100644 index 0000000..8c6051f --- /dev/null +++ b/modules/plugins/perftest/src/main/resources/configurable-7.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> + +<scenario xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:xmlns:jboss.org:rhq-perftest"> + + <!-- + Sets up "omega servers" that have three kinds of child services, "alpha", "beta" and "gamma". + + This is currently for simple services, not all of the service featured are exposed, only numeric metrics. + + Example: + + -Drhq.perftest.scenario=configurable-7 + -Drhq.perftest.server-omega-count=10 + -Drhq.perftest.service-alpha-count=25 + -Drhq.perftest.service-beta-count=2 + -Drhq.perftest.service-gamma-count=10 + --> + + <resource type="server-omega"> + <simpleResourceGenerator property="rhq.perftest.server-omega-count"/> + <simpleNumericMeasurementGenerator/> + </resource> + + <resource type="service-alpha"> + <simpleResourceGenerator property="rhq.perftest.service-alpha-count"/> + <simpleNumericMeasurementGenerator/> + </resource> + + <resource type="service-beta"> + <simpleResourceGenerator property="rhq.perftest.service-beta-count"/> + <simpleNumericMeasurementGenerator/> + </resource> + + <resource type="service-gamma"> + <simpleResourceGenerator property="rhq.perftest.service-gamma-count"/> + <simpleNumericMeasurementGenerator/> + </resource> + +</scenario>
commit 1ace95e35c4684847526df65f46e8ae4c559b92e Author: Heiko W. Rupp hwr@redhat.com Date: Thu Aug 16 16:03:47 2012 -0400
BZ 844217 - do not "hardcode" the deployment directory at discovery time, but make it a trait so that changes the user is making will be relected.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java index 6eb19f6..573742e 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASComponent.java @@ -18,7 +18,9 @@ */ package org.rhq.modules.plugins.jbossas7;
+import java.io.File; import java.util.HashSet; +import java.util.Map; import java.util.Set;
import org.jetbrains.annotations.NotNull; @@ -27,6 +29,7 @@ import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.configuration.PropertyMap; +import org.rhq.core.domain.measurement.MeasurementDataTrait; import org.rhq.core.domain.measurement.MeasurementReport; import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; @@ -37,6 +40,7 @@ import org.rhq.core.pluginapi.operation.OperationResult; import org.rhq.modules.plugins.jbossas7.json.Address; import org.rhq.modules.plugins.jbossas7.json.Operation; import org.rhq.modules.plugins.jbossas7.json.ReadAttribute; +import org.rhq.modules.plugins.jbossas7.json.ReadResource; import org.rhq.modules.plugins.jbossas7.json.Result;
/** @@ -65,6 +69,8 @@ public class StandaloneASComponent<T extends ResourceComponent<?>> extends BaseS collectConfigTrait(report, request); } else if (requestName.equals("multicastAddress")) { collectMulticastAddressTrait(report, request); + } else if (requestName.equals("deployDir")) { + resolveDeployDir(report,request); } else { leftovers.add(request); // handled below } @@ -73,6 +79,62 @@ public class StandaloneASComponent<T extends ResourceComponent<?>> extends BaseS super.getValues(report, leftovers); }
+ /** + * Try to determine the deployment directory (usually $as/standalone/deployments ). + * For JDG we return fake data, as JDG does not have such a directory. + * @param report Measurement report to tack the value on + * @param request Measurement request with the schedule id to use + */ + private void resolveDeployDir(MeasurementReport report, MeasurementScheduleRequest request) { + + if ("JDG".equals(pluginConfiguration.getSimpleValue("productType","AS7"))) { + log.debug("This is a JDG server, so there is no deployDir"); + MeasurementDataTrait trait = new MeasurementDataTrait(request,"- not applicable to JDG -"); + report.addData(trait); + return; + } + + // So we have an AS7/EAP6 + Address scanner = new Address("subsystem=deployment-scanner,scanner=default"); + ReadResource op = new ReadResource(scanner); + Result res = getASConnection().execute(op); + if (res.isSuccess()) { + Map<String,String> scannerMap = (Map<String, String>) res.getResult(); + String path = scannerMap.get("path"); + String relativeTo = scannerMap.get("relative-to"); + File basePath = resolveRelativePath(relativeTo); + + // It is safe to use File.separator, as the agent we are running in, will also lay down the plugins + String deployDir = new File(basePath, path).getAbsolutePath(); + + MeasurementDataTrait trait = new MeasurementDataTrait(request,deployDir); + report.addData(trait); + } + else { + log.error("No default deployment scanner was found, returning no value"); + } + } + + private File resolveRelativePath(String relativeTo) { + + Address addr = new Address("path",relativeTo); + ReadResource op = new ReadResource(addr); + Result res = getASConnection().execute(op); + if (res.isSuccess()) { + Map<String,String> pathMap = (Map<String, String>) res.getResult(); + String path = pathMap.get("path"); + String relativeToProp = pathMap.get("relative-to"); + if (relativeToProp==null) + return new File(path); + else { + File basePath = resolveRelativePath(relativeToProp); + return new File(basePath, path); + } + } + log.warn("The requested path property " + relativeTo + " is not registered in the server, so not resolving it."); + return new File(relativeTo); + } + @Override protected Address getServerAddress() { return getAddress(); diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java index 9d93300..efa814d 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/StandaloneASDiscovery.java @@ -84,13 +84,6 @@ public class StandaloneASDiscovery extends BaseProcessDiscovery { DiscoveredResourceDetails resourceDetails = super.buildResourceDetails(discoveryContext, process, commandLine); Configuration pluginConfig = resourceDetails.getPluginConfiguration();
- // Set deployment directory, which only exists for standalone servers - String baseDir = pluginConfig.getSimpleValue("baseDir"); - if (baseDir != null) { - File deployDir = new File(baseDir, "deployments"); - pluginConfig.put(new PropertySimple("deployDir", deployDir.getPath())); - } - return resourceDetails; }
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 638f542..8143d04 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 @@ -1164,7 +1164,6 @@ <c:simple-property name="baseDir" type="file" description="Base directory for server content" displayName="Base Directory" readOnly="true" required="false"/> <c:simple-property name="configDir" type="file" description="Base configuration directory" displayName="Configuration Directory" readOnly="true" required="false"/> <c:simple-property name="logDir" type="file" description="the directory where log files will be written for this server" displayName="Log Directory" readOnly="true" required="false"/> - <c:simple-property name="deployDir" type="file" description="Deploy directory for standalone servers" displayName="Deployment directory" readOnly="true" required="false"/> <c:simple-property name="productType" type="string" readOnly="true" required="false" description="Server product type (e.g. AS or EAP)"/>
&startScriptPluginConfigGroup; @@ -1224,6 +1223,8 @@
<metric property="config-file" dataType="trait" displayName="Server Config File" displayType="summary" defaultInterval="3600000" description="The name of the server configuration file this server is using"/> + <metric property="deployDir" dataType="trait" displayName="Deploy Directory" defaultInterval="600000" defaultOn="true" + description="The deployment directory for bundles (usually 'standalone/deployments'"/>
<event name="logEntry" description="an entry in a log file"/>
@@ -1321,14 +1322,14 @@ name="Template-Deploy Files" description="Monitor standalone deployment dir for drift. "> <basedir> - <value-context>pluginConfiguration</value-context> + <value-context>measurementTrait</value-context> <value-name>deployDir</value-name> </basedir> </drift-definition>
<bundle-target> <destination-base-dir name="Deploy Directory" description="The deployment directory for a standalone server"> - <value-context>pluginConfiguration</value-context> + <value-context>measurementTrait</value-context> <value-name>deployDir</value-name> </destination-base-dir> </bundle-target>
commit 2e9bce71d9e26e1a7034650a56f6d3118b20ebaa Author: John Sanda jsanda@redhat.com Date: Thu Aug 16 13:18:09 2012 -0400
[BZ 826604] fix parsing of quoted named args
This commit addresses the parsing problems of using quoted strings with named arguments.
diff --git a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/ClientMain.java b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/ClientMain.java index c7f6bbf..e068272 100644 --- a/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/ClientMain.java +++ b/modules/enterprise/remoting/cli/src/main/java/org/rhq/enterprise/client/ClientMain.java @@ -431,6 +431,7 @@ public class ClientMain { boolean keep_going = true;
boolean isScriptFileCommand = false; + boolean isNamedArgs = false;
// we don't want to parse numbers and we want ' to be a normal word // character @@ -471,12 +472,39 @@ public class ClientMain { isScriptFileCommand = true; } args.add(strtok.sval); + if (strtok.sval.equals("--args-style=named")) { + isNamedArgs = true; + } } else if (nextToken == '"' || nextToken == ''') { args.add(strtok.sval); } else if ((nextToken == java.io.StreamTokenizer.TT_EOF) || (nextToken == java.io.StreamTokenizer.TT_EOL)) { keep_going = false; } } + + if (isNamedArgs) { + List<String> newArgs = new ArrayList<String>(); + int namedArgsIndex = args.indexOf("--args-style=named"); + + for (int i = 0; i <= namedArgsIndex; ++i) { + newArgs.add(args.get(i)); + } + + String namedArg = null; + for (int i = namedArgsIndex + 1; i < args.size(); ++i) { + if (namedArg == null && args.get(i).endsWith("=")) { + namedArg = args.get(i); + } else if (namedArg != null) { + newArgs.add(args.get(i - 1) + args.get(i)); + namedArg = null; + } else { + newArgs.add(args.get(i)); + } + } + + return newArgs.toArray(new String[newArgs.size()]); + } + return args.toArray(new String[args.size()]); }
commit 30a6818e7ae101dc8df7edc198c5ee9ac790683e Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Aug 16 12:39:22 2012 -0400
[Bug 784571 - Resource tree not complete when more than 200 children] We decided not to allow an unlimited number of child resources be returned when expanding a node in the tree. But there are major problems with simply limiting the children to 200. This is what we do today, and the results are unordered. Meaning you can lose any number of resources of any types and it is not possible to know what you are missing. And we don't indicate that the tree is incomplete. If we add ordering (alphabetical by resource name) you still lose any number of resources, but always the same ones. In this way it is much easier to realize that you are missing child resources (and/or entire child types) because the resources returned obviously stop as some lexigraphical point.
Still, we don't want to allow an unbounded fetch in the GUI. The solution here is to move the unbounded fetch to the server side and to introduce SLSB support to prune the results and return the pruned child set. In this way we can limit the max child resources while returning a much more reasonable resource set.
The way it works is as follows: There are two variable in use:
maxResources Will not return more than this number of resources. If the original fetch exceeds maxResources then maxResourcesByType will be enforced. If, after trimming by type, maxResources is still exceeded, then the tail resources (assuming a sorted set) will be removed to enforce the limit. If <=0 the default (currently set to 1000) will be used.
maxResourcesByType If maxResources is exceeded by the initial result set then members of each type will be trimmed down to meet this limit. If <=0 the default (currently set to 200) will be used.
The defaults may change after this check-in based on testing results. The GUI will not set these values in the fetch, so the defaults will be applied.
The default values can be overriden (and applied to all fetches/sessions) by setting the following system properties (in rhq-server.properties and restarting): rhq.server.findResourcesByCriteriaBounded.maxResources rhq.server.findResourcesByCriteriaBounded.maxResourcesByType
So, this allows us to: - Avoid an unbounded fetch. - Have any distribution of child resources of various types as long as the maxResources limit is not exceeded. - Apply an even and understandable pruning when necessary.
It does not yet allow us to indicate in the tree which resource types have been pruned. This will be a future enhancement and tracked as https://bugzilla.redhat.com/show_bug.cgi?id=848853.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java index 59d96c6..1cdc64c 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java @@ -70,6 +70,9 @@ public interface ResourceGWTService extends RemoteService {
PageList<Resource> findResourcesByCriteria(ResourceCriteria criteria) throws RuntimeException;
+ List<Resource> findResourcesByCriteriaBounded(ResourceCriteria criteria, int maxResources, int maxResourcesByType) + throws RuntimeException; + PageList<ResourceComposite> findResourceCompositesByCriteria(ResourceCriteria criteria) throws RuntimeException;
List<ResourceError> findResourceErrors(int resourceId) throws RuntimeException; diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java index 5c58a70..b6a5f5f 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java @@ -44,8 +44,7 @@ import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceSubCategory; import org.rhq.core.domain.resource.ResourceType; -import org.rhq.core.domain.util.PageControl; -import org.rhq.core.domain.util.PageList; +import org.rhq.core.domain.util.PageOrdering; import org.rhq.enterprise.gui.coregui.client.CoreGUI; import org.rhq.enterprise.gui.coregui.client.Messages; import org.rhq.enterprise.gui.coregui.client.ViewChangedException; @@ -159,12 +158,16 @@ public class ResourceTreeDatasource extends DataSource { } else { Log.debug("ResourceTreeDatasource: Loading Resource [" + parentResourceId + "]...");
+ // This fetch limits the number of resources that can be returned to protect against fetching a massive + // number of children for a parent. Doing so may cause an unacceptably slow tree rendering, too much vertical + // scroll, or perhaps even hang the gui if it consumed too many resources. To see all children the + // user will need to visit the Inventory->Children view for the resource. ResourceCriteria criteria = new ResourceCriteria(); criteria.addFilterParentResourceId(Integer.parseInt(parentResourceId)); - // we don't need sorting since we get everything and the tree nodes are already sorted - criteria.setPageControl(PageControl.getUnlimitedInstance()); + // we must sort the results to ensure that if cropped we at least show the same results each time + criteria.addSortName(PageOrdering.ASC);
- resourceService.findResourcesByCriteria(criteria, new AsyncCallback<PageList<Resource>>() { + resourceService.findResourcesByCriteriaBounded(criteria, -1, -1, new AsyncCallback<List<Resource>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_children(), caught); response.setStatus(RPCResponse.STATUS_FAILURE); @@ -173,7 +176,7 @@ public class ResourceTreeDatasource extends DataSource { loadingLabel.hide(); }
- public void onSuccess(PageList<Resource> result) { + public void onSuccess(List<Resource> result) { processIncomingData(result, response, requestId); } }); diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java index 17ccd78..4ee821b 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java @@ -145,6 +145,20 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re } }
+ public List<Resource> findResourcesByCriteriaBounded(ResourceCriteria criteria, int maxResources, + int maxResourcesByType) throws RuntimeException { + try { + List<Resource> result = resourceManager.findResourcesByCriteriaBounded(getSessionSubject(), criteria, + maxResources, maxResourcesByType); + + ObjectFilter.filterFieldsInCollection(result, importantFieldsSet); + + return SerialUtility.prepare(result, "ResourceService.findResourcesByCriteriaBounded"); + } catch (Throwable t) { + throw getExceptionToThrowToClient(t); + } + } + public PageList<ResourceComposite> findResourceCompositesByCriteria(ResourceCriteria criteria) throws RuntimeException { try { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java index dce2e23..0fe906a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -142,6 +143,9 @@ import org.rhq.enterprise.server.util.QueryUtility; public class ResourceManagerBean implements ResourceManagerLocal, ResourceManagerRemote { private final Log log = LogFactory.getLog(ResourceManagerBean.class);
+ private final static String BOUNDED_MAX_RESOURCES = "1000"; + private final static String BOUNDED_MAX_RESOURCES_BY_TYPE = "200"; + @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME) private EntityManager entityManager;
@@ -2472,6 +2476,70 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage return results; }
+ @Override + public List<Resource> findResourcesByCriteriaBounded(Subject subject, ResourceCriteria criteria, int maxResources, + int maxResourcesByType) { + + // find all of the requested resources but don't return them until they meet our bounded return requirements + // maintain any requested sorting + criteria.clearPaging(); + + // perform the requested criteria query + PageList<Resource> results = findResourcesByCriteria(subject, criteria); + + // If not specified use the default maxResources + if (maxResources <= 0) { + try { + maxResources = Integer.parseInt(System.getProperty( + "rhq.server.findResourcesByCriteriaBounded.maxResources", BOUNDED_MAX_RESOURCES)); + } catch (NumberFormatException e) { + } + if (maxResources <= 0) { + maxResources = Integer.parseInt(BOUNDED_MAX_RESOURCES); + } + } + + if (results.getTotalSize() <= maxResources) { + return results; + } + + // If not specified use the default maxResourcesByType + if (maxResourcesByType <= 0) { + try { + maxResourcesByType = Integer.parseInt(System.getProperty( + "rhq.server.findResourcesByCriteriaBounded.maxResourcesByType", BOUNDED_MAX_RESOURCES_BY_TYPE)); + } catch (NumberFormatException e) { + } + if (maxResourcesByType <= 0) { + maxResourcesByType = Integer.parseInt(BOUNDED_MAX_RESOURCES_BY_TYPE); + } + } + + // We need to trim the returned resources, enforce maxResourcesByType + Map<Integer, Integer> typeCounts = new HashMap<Integer, Integer>(); + + for (Iterator<Resource> i = results.iterator(); i.hasNext();) { + Resource r = i.next(); + Integer typeId = r.getResourceType().getId(); + Integer count = typeCounts.get(typeId); + if (null == count) { + count = 0; + } + typeCounts.put(typeId, ++count); + if (count > maxResourcesByType) { + i.remove(); + } + } + + // If after we've trimmed all types the results are still more than maxSize then we need to just chop + // keeping the most important (presumably the beginning of the list, if it's sorted) + while (maxResources < results.size()) { + results.remove(maxResources); + } + + return results; + } + public Resource getPlaformOfResource(Subject subject, int resourceId) { Resource resource = null; Resource parent = null; diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java index fc075be..f555116 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java @@ -446,6 +446,24 @@ public interface ResourceManagerLocal { */ public void updateAncestry(Subject subject, int resourceId);
+ /** + * This method exists to support the GUI resource tree, by not returning an unlimited number of resources + * but instead bounding the returned size. Note, this routine does not offer paging and any PageControl set in + * the Criteria is ignored. This is for use when paging is not required or possible, such as in a tree. + * + * @param subject + * @param criteria + * @param maxResources Will not return more than this number of resources. If the original fetch exceeds maxResources + * then maxResourcesByType will be enforced. If, after trimming by type, maxResources is still exceeded, then the least + * significant resources (the tail, assuming a sorted set) will be removed to enforce the limit. If <=0 the default + * will be used. + * @param maxResourcesByType If maxResources is exceeded by the initial result set then members of each type will be + * trimmed down to meet this limit. If <=0 the default will be used. + * @return The resulting resources, trimmed if necessary to meet the specify sizing bounds. + */ + List<Resource> findResourcesByCriteriaBounded(Subject subject, ResourceCriteria criteria, int maxResources, + int maxResourcesByType); + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // // The following are shared with the Remote Interface
commit 10ad78d37ed54185afee537929c7411f0f40b694 Author: Stefan Negrea snegrea@redhat.com Date: Thu Aug 16 11:03:47 2012 -0500
[BZ 824818] Removing required from keepalive-time because the validation rules on AS7 are too complex and not consistent with the resource definition.
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 a1eb285..638f542 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 @@ -2516,16 +2516,15 @@ </plugin-configuration>
<metric property="current-thread-count" description="The current number of threads in the pool."/> - <metric property="keepalive-time:time" description="The time"/> <metric property="largest-thread-count" description="The largest number of threads that have ever simultaneously been in the pool."/> <metric property="rejected-count" description="The number of tasks that have been passed to the handoff-executor (if one is specified) or discarded."/>
<resource-configuration> <c:simple-property name="allow-core-timeout" required="false" type="boolean" readOnly="true" defaultValue="false" displayName="Allow Core Timeout" description="Whether core threads may time out. The default value is false."/> <c:simple-property name="core-threads:expr" required="false" type="integer" readOnly="true" displayName="Core Threads" description="The core thread pool size which is smaller than the maximum pool size. If undefined, the core thread pool size is the same as the maximum thread pool size."/> - <c:map-property name="keepalive-time" required="true" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="true" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="true" description="The time unit"/> + <c:map-property name="keepalive-time" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> + <c:simple-property name="time" type="long" readOnly="true" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="true" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="integer" readOnly="true" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" displayName="Name" description="The name of the thread pool."/> @@ -2544,16 +2543,15 @@ </plugin-configuration>
<metric property="current-thread-count" description="The current number of threads in the pool."/> - <metric property="keepalive-time:time" description="The time"/> <metric property="largest-thread-count" description="The largest number of threads that have ever simultaneously been in the pool."/> <metric property="rejected-count" description="The number of tasks that have been passed to the handoff-executor (if one is specified) or discarded."/>
<resource-configuration> <c:simple-property name="allow-core-timeout" required="false" type="boolean" readOnly="true" defaultValue="false" displayName="Allow Core Timeout" description="Whether core threads may time out. The default value is false."/> <c:simple-property name="core-threads:expr" required="false" type="integer" readOnly="true" displayName="Core Threads" description="The core thread pool size which is smaller than the maximum pool size. If undefined, the core thread pool size is the same as the maximum thread pool size."/> - <c:map-property name="keepalive-time" required="true" readOnly="true" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="true" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="true" description="The time unit"/> + <c:map-property name="keepalive-time" readOnly="true" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> + <c:simple-property name="time" type="long" readOnly="true" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="true" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="integer" readOnly="true" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" displayName="Name" description="The name of the thread pool."/> @@ -2856,15 +2854,14 @@ <metric property="active-count" description="The approximate number of threads that are actively executing tasks."/> <metric property="completed-task-count" description="The approximate total number of tasks that have completed execution."/> <metric property="current-thread-count" description="The current number of threads in the pool."/> - <metric property="keepalive-time:time" description="The time"/> <metric property="largest-thread-count" description="The largest number of threads that have ever simultaneously been in the pool."/> <metric property="rejected-count" description="The number of tasks that have been rejected."/> <metric property="task-count" description="The approximate total number of tasks that have ever been scheduled for execution."/>
<resource-configuration> <c:map-property name="keepalive-time" readOnly="true" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="true" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="true" description="The time unit"/> + <c:simple-property name="time" type="long" readOnly="true" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="true" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" displayName="Max Threads" required="false" type="string" readOnly="true" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" description="The name of the thread pool."/> @@ -3081,8 +3078,8 @@
<resource-configuration> <c:map-property name="keepalive-time" readOnly="false" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" readOnly="false" type="long" description="The time"/> - <c:simple-property name="unit" required="true" readOnly="false" type="string" description="The time unit"/> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="string" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" description="The name of the thread pool."/> @@ -5499,9 +5496,9 @@ <resource-configuration> <c:simple-property name="allow-core-timeout" required="false" type="boolean" readOnly="false" defaultValue="false" displayName="Allow Core Timeout" description="Whether core threads may time out. The default value is false."/> <c:simple-property name="core-threads:expr" required="false" type="integer" readOnly="false" displayName="Core Threads" description="The core thread pool size which is smaller than the maximum pool size. If undefined, the core thread pool size is the same as the maximum thread pool size."/> - <c:map-property name="keepalive-time" required="true" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="false" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="false" description="The time unit"/> + <c:map-property name="keepalive-time" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="integer" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" displayName="Name" description="The name of the thread pool."/> @@ -5523,9 +5520,9 @@ <resource-configuration> <c:simple-property name="allow-core-timeout" required="false" type="boolean" readOnly="false" defaultValue="false" displayName="Allow Core Timeout" description="Whether core threads may time out. The default value is false."/> <c:simple-property name="core-threads:expr" required="false" type="integer" readOnly="false" displayName="Core Threads" description="The core thread pool size which is smaller than the maximum pool size. If undefined, the core thread pool size is the same as the maximum thread pool size."/> - <c:map-property name="keepalive-time" required="true" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="false" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="false" description="The time unit"/> + <c:map-property name="keepalive-time" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="integer" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" displayName="Name" description="The name of the thread pool."/> @@ -5711,8 +5708,8 @@
<resource-configuration> <c:map-property name="keepalive-time" readOnly="false" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="false" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="false" description="The time unit"/> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="false" type="string" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" description="The name of the thread pool."/> @@ -5927,8 +5924,8 @@
<resource-configuration> <c:map-property name="keepalive-time" readOnly="false" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" readOnly="false" type="long" description="The time"/> - <c:simple-property name="unit" required="true" readOnly="false" type="string" description="The time unit"/> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="string" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" description="The name of the thread pool."/> @@ -10269,16 +10266,15 @@ </plugin-configuration>
<metric property="current-thread-count" description="The current number of threads in the pool."/> - <metric property="keepalive-time:time" description="The time"/> <metric property="largest-thread-count" description="The largest number of threads that have ever simultaneously been in the pool."/> <metric property="rejected-count" description="The number of tasks that have been passed to the handoff-executor (if one is specified) or discarded."/>
<resource-configuration> <c:simple-property name="allow-core-timeout" required="false" type="boolean" readOnly="false" defaultValue="false" displayName="Allow Core Timeout" description="Whether core threads may time out. The default value is false."/> <c:simple-property name="core-threads:expr" required="false" type="integer" readOnly="false" displayName="Core Threads" description="The core thread pool size which is smaller than the maximum pool size. If undefined, the core thread pool size is the same as the maximum thread pool size."/> - <c:map-property name="keepalive-time" required="true" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="false" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="false" description="The time unit"/> + <c:map-property name="keepalive-time" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="integer" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" displayName="Name" description="The name of the thread pool."/> @@ -10298,16 +10294,15 @@ </plugin-configuration>
<metric property="current-thread-count" description="The current number of threads in the pool."/> - <metric property="keepalive-time:time" description="The time"/> <metric property="largest-thread-count" description="The largest number of threads that have ever simultaneously been in the pool."/> <metric property="rejected-count" description="The number of tasks that have been passed to the handoff-executor (if one is specified) or discarded."/>
<resource-configuration> <c:simple-property name="allow-core-timeout" required="false" type="boolean" readOnly="false" defaultValue="false" displayName="Allow Core Timeout" description="Whether core threads may time out. The default value is false."/> <c:simple-property name="core-threads:expr" required="false" type="integer" readOnly="false" displayName="Core Threads" description="The core thread pool size which is smaller than the maximum pool size. If undefined, the core thread pool size is the same as the maximum thread pool size."/> - <c:map-property name="keepalive-time" required="true" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="false" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="false" description="The time unit"/> + <c:map-property name="keepalive-time" displayName="Keepalive Time" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="integer" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" displayName="Name" description="The name of the thread pool."/> @@ -10863,8 +10858,8 @@
<resource-configuration> <c:map-property name="keepalive-time" readOnly="false" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" readOnly="false" type="long" description="The time"/> - <c:simple-property name="unit" required="true" readOnly="false" type="string" description="The time unit"/> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="true" type="string" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" description="The name of the thread pool."/> @@ -10942,8 +10937,8 @@
<resource-configuration> <c:map-property name="keepalive-time" readOnly="false" description="Used to specify the amount of time that pool threads should be kept running when idle; if not specified, threads will run until the executor is shut down."> - <c:simple-property name="time" required="true" type="long" readOnly="false" description="The time"/> - <c:simple-property name="unit" required="true" type="string" readOnly="false" description="The time unit"/> + <c:simple-property name="time" type="long" readOnly="false" description="The time"/> + <c:simple-property name="unit" type="string" readOnly="false" description="The time unit"/> </c:map-property> <c:simple-property name="max-threads:expr" required="false" type="string" readOnly="false" displayName="Max Threads" description="The maximum thread pool size."/> <c:simple-property name="name" required="false" type="string" readOnly="true" description="The name of the thread pool."/>
commit 8000e712dd98fd8ee8e1ff52940e15b07f11e782 Author: Jirka Kremser jkremser@redhat.com Date: Wed Aug 15 20:13:14 2012 +0200
[BZ 845277] - quick fix: removed the doctype declaration and removed overcasting to int
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java index 3da090a..8445a46 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java @@ -312,7 +312,7 @@ public abstract class AbstractMetricGraphView extends LocatableVLayout {
for (MeasurementDataNumericHighLowComposite d : data) { if (!Double.isNaN(d.getValue())) { - handler.add(new DataPoint(d.getTimestamp(), (int) d.getValue())); + handler.add(new DataPoint(d.getTimestamp(), d.getValue())); } }
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html index a0a4d2a..6a78aab 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html +++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html @@ -1,4 +1,3 @@ -<!DOCTYPE html> <html> <head> <!-- this forces us to emulate IE8 "quirks" mode regardless of IE browser version. It:
commit 5d243b30f5315f18329f6f4fa9db22ae47eb32bd Author: Jirka Kremser jkremser@redhat.com Date: Wed Aug 15 19:42:24 2012 +0200
[BZ 845277 - JBoss ON dashboard shows messed metric graph on IE 8/9] Version of gflot upgraded to 2.4.2 (it contains the excanvas library for IE8/9 support of HTML canvas el.), version of sparkline upgraded to 2.0, version of jquery upgraded to 1.7.2
diff --git a/modules/enterprise/gui/coregui/pom.xml b/modules/enterprise/gui/coregui/pom.xml index e3aca30..a4b08b0 100644 --- a/modules/enterprise/gui/coregui/pom.xml +++ b/modules/enterprise/gui/coregui/pom.xml @@ -143,9 +143,10 @@ to provide jquery explcitly for jquery.sparkline support. See CoreGUI.gwt.xml for the jquery.sparkline declaration and coregui/webapp/js for the lib inclusion.) --> <dependency> - <groupId>ca.nanometrics</groupId> + <groupId>com.googlecode.gflot</groupId> <artifactId>gflot</artifactId> - <version>1.0.0</version> + <version>2.4.2</version> + <scope>provided</scope> </dependency>
@@ -283,8 +284,8 @@ <configuration> <noServer>true</noServer> <inplace>false</inplace> - <!-- <logLevel>INFO' -bindAddress 0.0.0.0 -logLevel 'INFO</logLevel> --> - <logLevel>INFO</logLevel> +<!-- <logLevel>INFO' -bindAddress 0.0.0.0 -logLevel 'INFO</logLevel> --> + <logLevel>INFO</logLevel> <runTarget>${coreGuiRunTarget}</runTarget> <extraJvmArgs>${gwt-plugin.extraJvmArgs}</extraJvmArgs> <localWorkers>${gwt-plugin.localWorkers}</localWorkers> diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java index 224125d..3da090a 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/AbstractMetricGraphView.java @@ -23,14 +23,15 @@ import java.util.List;
import ca.nanometrics.gflot.client.Axis; import ca.nanometrics.gflot.client.DataPoint; -import ca.nanometrics.gflot.client.PlotItem; import ca.nanometrics.gflot.client.PlotModel; -import ca.nanometrics.gflot.client.PlotPosition; import ca.nanometrics.gflot.client.SeriesHandler; import ca.nanometrics.gflot.client.SimplePlot; import ca.nanometrics.gflot.client.event.PlotHoverListener; +import ca.nanometrics.gflot.client.event.PlotItem; +import ca.nanometrics.gflot.client.event.PlotPosition; import ca.nanometrics.gflot.client.jsni.Plot; import ca.nanometrics.gflot.client.options.AxisOptions; +import ca.nanometrics.gflot.client.options.GlobalSeriesOptions; import ca.nanometrics.gflot.client.options.GridOptions; import ca.nanometrics.gflot.client.options.LineSeriesOptions; import ca.nanometrics.gflot.client.options.PlotOptions; @@ -201,9 +202,11 @@ public abstract class AbstractMetricGraphView extends LocatableVLayout {
PlotModel model = new PlotModel(); PlotOptions plotOptions = new PlotOptions(); - plotOptions.setDefaultLineSeriesOptions(new LineSeriesOptions().setLineWidth(1).setShow(true)); - plotOptions.setDefaultPointsOptions(new PointsSeriesOptions().setRadius(2).setShow(true)); - plotOptions.setDefaultShadowSize(0); + GlobalSeriesOptions globalSeriesOptions = new GlobalSeriesOptions(); + globalSeriesOptions.setLineSeriesOptions(new LineSeriesOptions().setLineWidth(1).setShow(true)); + globalSeriesOptions.setPointsOptions(new PointsSeriesOptions().setRadius(2).setShow(true)); + globalSeriesOptions.setShadowSize(0); + plotOptions.setGlobalSeriesOptions(globalSeriesOptions);
// You need make the grid hoverable <<<<<<<<< plotOptions @@ -308,10 +311,12 @@ public abstract class AbstractMetricGraphView extends LocatableVLayout { SeriesHandler handler = model.addSeries(definition.getDisplayName(), "#007f00");
for (MeasurementDataNumericHighLowComposite d : data) { - handler.add(new DataPoint(d.getTimestamp(), d.getValue())); + if (!Double.isNaN(d.getValue())) { + handler.add(new DataPoint(d.getTimestamp(), (int) d.getValue())); + } }
- plotOptions.setYAxisOptions(new AxisOptions().setTicks(5).setLabelWidth(70) + plotOptions.addYAxisOptions(new AxisOptions().setTicks(5).setLabelWidth(70) .setTickFormatter(new TickFormatter() { public String formatTickValue(double v, Axis axis) { return MeasurementConverterClient.format(v, definition.getUnits(), true); @@ -323,7 +328,7 @@ public abstract class AbstractMetricGraphView extends LocatableVLayout {
int xTicks = getDefaultWidth() / 140;
- plotOptions.setXAxisOptions(new AxisOptions().setTicks(xTicks).setMinimum(min).setMaximum(max) + plotOptions.addXAxisOptions(new AxisOptions().setTicks(xTicks).setMinimum(min).setMaximum(max) .setTickFormatter(new TickFormatter() { public String formatTickValue(double tickValue, Axis axis) { com.google.gwt.i18n.client.DateTimeFormat dateFormat = DateTimeFormat diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/LiveGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/LiveGraphView.java index edc1611..330eaf0 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/LiveGraphView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/LiveGraphView.java @@ -24,15 +24,16 @@ import java.util.Set;
import ca.nanometrics.gflot.client.Axis; import ca.nanometrics.gflot.client.DataPoint; -import ca.nanometrics.gflot.client.PlotItem; import ca.nanometrics.gflot.client.PlotModel; import ca.nanometrics.gflot.client.PlotModelStrategy; -import ca.nanometrics.gflot.client.PlotPosition; import ca.nanometrics.gflot.client.SeriesHandler; import ca.nanometrics.gflot.client.SimplePlot; import ca.nanometrics.gflot.client.event.PlotHoverListener; +import ca.nanometrics.gflot.client.event.PlotItem; +import ca.nanometrics.gflot.client.event.PlotPosition; import ca.nanometrics.gflot.client.jsni.Plot; import ca.nanometrics.gflot.client.options.AxisOptions; +import ca.nanometrics.gflot.client.options.GlobalSeriesOptions; import ca.nanometrics.gflot.client.options.GridOptions; import ca.nanometrics.gflot.client.options.LineSeriesOptions; import ca.nanometrics.gflot.client.options.PlotOptions; @@ -133,9 +134,11 @@ public class LiveGraphView extends LocatableVLayout {
PlotModel model = new PlotModel(); PlotOptions plotOptions = new PlotOptions(); - plotOptions.setDefaultLineSeriesOptions(new LineSeriesOptions().setLineWidth(1).setShow(true)); - plotOptions.setDefaultPointsOptions(new PointsSeriesOptions().setRadius(2).setShow(true)); - plotOptions.setDefaultShadowSize(0); + GlobalSeriesOptions globalSeriesOptions = new GlobalSeriesOptions(); + globalSeriesOptions.setLineSeriesOptions(new LineSeriesOptions().setLineWidth(1).setShow(true)); + globalSeriesOptions.setPointsOptions(new PointsSeriesOptions().setRadius(2).setShow(true)); + globalSeriesOptions.setShadowSize(0); + plotOptions.setGlobalSeriesOptions(globalSeriesOptions);
// You need make the grid hoverable <<<<<<<<< plotOptions @@ -258,7 +261,7 @@ public class LiveGraphView extends LocatableVLayout {
dataLoader.scheduleRepeating(1000);
- plotOptions.setYAxisOptions(new AxisOptions().setLabelWidth(70).setTicks(5) + plotOptions.addYAxisOptions(new AxisOptions().setLabelWidth(70).setTicks(5) .setTickFormatter(new TickFormatter() { public String formatTickValue(double v, Axis axis) { return MeasurementConverterClient.format(v, definition.getUnits(), true); @@ -268,7 +271,7 @@ public class LiveGraphView extends LocatableVLayout { min = System.currentTimeMillis(); max = System.currentTimeMillis() + (1000L * 60);
- plotOptions.setXAxisOptions(new AxisOptions().setTicks(8).setTickFormatter(new TickFormatter() { + plotOptions.addXAxisOptions(new AxisOptions().setTicks(8).setTickFormatter(new TickFormatter() { public String formatTickValue(double tickValue, Axis axis) { DateTimeFormat dateFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_TIME_MEDIUM); return dateFormat.format(new Date((long) tickValue)); diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml index 614e6f7..78db5af 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml @@ -46,12 +46,10 @@
<!-- External javascript libraries --> <!-- jquery.sparkline requires jquery. We don't explicitly provide jquery here because it is already - embedded in the GFlot JAR (the charting lib used for GraphPortlet). Furthermore, GFlot 1.0.0 requires - its older, embedded version of jquery (1.3.2). Fortunately, sparkline is compatible with this older version. - We will need to provide jquery explicitly (like the commented version below) if we remove GFlot. - <script src="/coregui/js/jquery-1.4.4.js"/> + embedded in the GFlot JAR (the charting lib used for GraphPortlet). Furthermore, GFlot 2.4.2 requires + the version of jquery (1.7.2). --> - <script src="/coregui/js/jquery.sparkline-1.6.js"/> + <script src="/coregui/js/jquery.sparkline-2.0.min.js"/>
<!-- Limit compilation to your preferred browser(s) to speed up compile time. diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html index 2c6e285..a0a4d2a 100644 --- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html +++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html @@ -1,3 +1,4 @@ +<!DOCTYPE html> <html> <head> <!-- this forces us to emulate IE8 "quirks" mode regardless of IE browser version. It: @@ -21,7 +22,8 @@ document.write("<meta name='gwt:property' content='locale="+lang +"'>"); } </script> - + <script src="/coregui/js/jquery-1.7.2.min.js"/> + <title>RHQ</title> <link rel="icon" type="image/png" href="/images/favicon.png" /> <link rel="apple-touch-icon" href="/images/favicon.png" /> diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.7.2.min.js b/modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.7.2.min.js new file mode 100644 index 0000000..16ad06c --- /dev/null +++ b/modules/enterprise/gui/coregui/src/main/webapp/js/jquery-1.7.2.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.2 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p; for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e +"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b]; if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"? c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a ,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for( c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*/?>(?:</\1>)?$/,n=/^[],:{}\s]*$/,o=/\(?:["\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\n\r]*"|true|false|null|-?\d+(?:.\d*)?(?:[eE][+-]?\d+)?/g,q=/(?:^|:|,)(?:\s*[)+/g,r=/(webkit)[ /]([\w.]+)/,s=/(opera)(?:.*version)?[ /]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return th is;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArra y:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=a rguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.a ttachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace( q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:func tion(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){v ar d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b )},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.s hift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progr ess:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=ar guments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.ge tAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name"," t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr>< td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g. style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:{.*}|[.*])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].dat a)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a !==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function( ){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this. each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.e ach(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.val Hooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j! ==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:fu nction(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a ,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.op tSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^.]*)?(?:.(.+))?$/,B=/(?:^|\s)hover(.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w-]+))?(?:.([\w-]+))?$/,G=function( +a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\s)"+b[3]+"(?:\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,gu id:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\.)"+l.split(".").sort().join("\.(?:.*\.)?")+"(\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p .remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\.)"+i.join("\.(?:.*\.)?")+"(\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArr ay(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(ar guments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c); return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if( !(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.cont ains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this. _just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c! ="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||" **",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):thi s.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:((?:([^()]+)|[^()]+)+)|[(?:[[^[]]*]|['"][^'"]*['"]|[^[]'"]+)+]|\.|[^ >+~,([\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[] ,d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t] !=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k= o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\.)+)/,CLASS:/.((?:[\w\u00c0-\uFFFF-]|\.)+)/,NAME:/[name=['"]*((?:[\w\u 00c0-\uFFFF-]|\.)+)['"]*]/,ATTR:/[\s*((?:[\w\u00c0-\uFFFF-]|\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF-]|\.)*)|)|)\s*]/,TAG:/^((?:[\w\u00c0-\uFFFF*-]|\.)+)/,CHILD:/:(only|nth|last|first)-child(?:(\s*(even|odd|(?:[+-]?\d+|(?:[+-]?\d*)?n\s*(?:[+-]\s*\d+)?))\s*))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:((\d*)))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\.)+)(?:((['"]?)((?:([^)]+)|[^()]*)+)\2))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++) {c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&& (" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^+|\s*/g,"");var b=/(-?)(\d*)(?:n([+-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){re turn a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toL owerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i, j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f=== "$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^[]*])(?![^(]*))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compa reDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter. ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^.([\w-]+$)|^#([\w-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagNam e(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/=\s*([^'"\ ]]*)\s*]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){va r d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#[.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.co ntains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,t his)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNode s)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|me ta|param)(([\w:]+)[^>]*)/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=//(java|ecma)script/i,bf=/^\s*<!(?:[CDATA[|--)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a ))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&& this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f +.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W," "):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragm ents[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e) {var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0] &&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha([^)]*)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[-+]?(?:\d*.)?\d+$/i,bt=/^-?(?:\d*.)?\d+(?!px)[^\d\s]+$/i,bu=/^([-+])=([-+ .\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch (l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f, f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=fun ction(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/[]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^///,bL=/?/,bM=/<script\b[^<]*(?:(?!</script>)<[^<]*)*</script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w+.-]+:)(?://([^/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement ("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.na me,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String ,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once mem ory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d .data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error :1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(=)?(&|$)|??/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application/x-www-form-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d. async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-Wit h"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+-]=)?([\d+.-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3) ,a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:functi on(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidd en");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue ===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.proto type={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!= =b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this .prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,l eft:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position ==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFuncti on(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo( d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-1.6.js b/modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-1.6.js deleted file mode 100644 index d60cf18..0000000 --- a/modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-1.6.js +++ /dev/null @@ -1,1271 +0,0 @@ -/** -* -* jquery.sparkline.js -* -* v1.6 -* (c) Splunk, Inc -* Contact: Gareth Watts (gareth@splunk.com) -* http://omnipotent.net/jquery.sparkline/ -* -* Generates inline sparkline charts from data supplied either to the method -* or inline in HTML -* -* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag -* (Firefox 2.0+, Safari, Opera, etc) -* -* License: New BSD License -* -* Copyright (c) 2010, Splunk Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* * Redistributions of source code must retain the above copyright notice, -* this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright notice, -* this list of conditions and the following disclaimer in the documentation -* and/or other materials provided with the distribution. -* * Neither the name of Splunk Inc nor the names of its contributors may -* be used to endorse or promote products derived from this software without -* specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* -* Usage: -* $(selector).sparkline(values, options) -* -* If values is undefined or set to 'html' then the data values are read from the specified tag: -* <p>Sparkline: <span class="sparkline">1,4,6,6,8,5,3,5</span></p> -* $('.sparkline').sparkline(); -* There must be no spaces in the enclosed data set -* -* Otherwise values must be an array of numbers or null values -* <p>Sparkline: <span id="sparkline1">This text replaced if the browser is compatible</span></p> -* $('#sparkline1').sparkline([1,4,6,6,8,5,3,5]) -* $('#sparkline2').sparkline([1,4,6,null,null,5,3,5]) -* -* Values can also be specified in an HTML comment, or as a values attribute: -* <p>Sparkline: <span class="sparkline"><!--1,4,6,6,8,5,3,5 --></span></p> -* <p>Sparkline: <span class="sparkline" values="1,4,6,6,8,5,3,5"></span></p> -* $('.sparkline').sparkline(); -* -* For line charts, x values can also be specified: -* <p>Sparkline: <span class="sparkline">1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5</span></p> -* $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ]) -* -* By default, options should be passed in as teh second argument to the sparkline function: -* $('.sparkline').sparkline([1,2,3,4], {type: 'bar'}) -* -* Options can also be set by passing them on the tag itself. This feature is disabled by default though -* as there's a slight performance overhead: -* $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true}) -* <p>Sparkline: <span class="sparkline" sparkType="bar" sparkBarColor="red">loading</span></p> -* Prefix all options supplied as tag attribute with "spark" (configurable by setting tagOptionPrefix) -* -* Supported options: -* lineColor - Color of the line used for the chart -* fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart -* width - Width of the chart - Defaults to 3 times the number of values in pixels -* height - Height of the chart - Defaults to the height of the containing element -* chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied -* chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied -* chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax -* chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied -* chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied -* composite - If true then don't erase any existing chart attached to the tag, but draw -* another chart over the top - Note that width and height are ignored if an -* existing chart is detected. -* tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values' -* enableTagOptions - Whether to check tags for sparkline options -* tagOptionPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark' -* -* There are 7 types of sparkline, selected by supplying a "type" option of 'line' (default), -* 'bar', 'tristate', 'bullet', 'discrete', 'pie' or 'box' -* line - Line chart. Options: -* spotColor - Set to '' to not end each line in a circular spot -* minSpotColor - If set, color of spot at minimum value -* maxSpotColor - If set, color of spot at maximum value -* spotRadius - Radius in pixels -* lineWidth - Width of line in pixels -* normalRangeMin -* normalRangeMax - If set draws a filled horizontal bar between these two values marking the "normal" -* or expected range of values -* normalRangeColor - Color to use for the above bar -* drawNormalOnTop - Draw the normal range above the chart fill color if true -* defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart -* -* bar - Bar chart. Options: -* barColor - Color of bars for postive values -* negBarColor - Color of bars for negative values -* zeroColor - Color of bars with zero values -* nullColor - Color of bars with null values - Defaults to omitting the bar entirely -* barWidth - Width of bars in pixels -* colorMap - Optional mappnig of values to colors to override the *BarColor values above -* can be an Array of values to control the color of individual bars -* barSpacing - Gap between bars in pixels -* zeroAxis - Centers the y-axis around zero if true -* -* tristate - Charts values of win (>0), lose (<0) or draw (=0) -* posBarColor - Color of win values -* negBarColor - Color of lose values -* zeroBarColor - Color of draw values -* barWidth - Width of bars in pixels -* barSpacing - Gap between bars in pixels -* colorMap - Optional mappnig of values to colors to override the *BarColor values above -* can be an Array of values to control the color of individual bars -* -* discrete - Options: -* lineHeight - Height of each line in pixels - Defaults to 30% of the graph height -* thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor -* thresholdColor -* -* bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ... -* options: -* targetColor - The color of the vertical target marker -* targetWidth - The width of the target marker in pixels -* performanceColor - The color of the performance measure horizontal bar -* rangeColors - Colors to use for each qualitative range background color -* -* pie - Pie chart. Options: -* sliceColors - An array of colors to use for pie slices -* offset - Angle in degrees to offset the first slice - Try -90 or +90 -* -* box - Box plot. Options: -* raw - Set to true to supply pre-computed plot points as values -* values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier -* When set to false you can supply any number of values and the box plot will -* be computed for you. Default is false. -* showOutliers - Set to true (default) to display outliers as circles -* outlierIRQ - Interquartile range used to determine outliers. Default 1.5 -* boxLineColor - Outline color of the box -* boxFillColor - Fill color for the box -* whiskerColor - Line color used for whiskers -* outlierLineColor - Outline color of outlier circles -* outlierFillColor - Fill color of the outlier circles -* spotRadius - Radius of outlier circles -* medianColor - Line color of the median line -* target - Draw a target cross hair at the supplied value (default undefined) -* -* -* -* Examples: -* $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false }); -* $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 }); -* $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }): -* $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' }); -* $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' }); -* $('#pie').sparkline([1,1,2], { type:'pie' }); -*/ - - -(function($) { - - /* - * Default configuration settings - */ - var defaults = { - // Settings common to most/all chart types - common: { - type : 'line', - lineColor : '#00f', - fillColor : '#cdf', - defaultPixelsPerValue : 3, - width : 'auto', - height : 'auto', - composite : false, - tagValuesAttribute: 'values', - tagOptionsPrefix: 'spark', - enableTagOptions: false - }, - // Defaults for line charts - line: { - spotColor : '#f80', - spotRadius : 1.5, - minSpotColor : '#f80', - maxSpotColor : '#f80', - lineWidth: 1, - normalRangeMin : undefined, - normalRangeMax : undefined, - normalRangeColor : '#ccc', - drawNormalOnTop: false, - chartRangeMin : undefined, - chartRangeMax : undefined, - chartRangeMinX : undefined, - chartRangeMaxX : undefined - }, - // Defaults for bar charts - bar: { - barColor : '#00f', - negBarColor : '#f44', - zeroColor: undefined, - nullColor: undefined, - zeroAxis : undefined, - barWidth : 4, - barSpacing : 1, - chartRangeMax: undefined, - chartRangeMin: undefined, - chartRangeClip: false, - colorMap : undefined - }, - // Defaults for tristate charts - tristate: { - barWidth : 4, - barSpacing : 1, - posBarColor: '#6f6', - negBarColor : '#f44', - zeroBarColor : '#999', - colorMap : {} - }, - // Defaults for discrete charts - discrete: { - lineHeight: 'auto', - thresholdColor: undefined, - thresholdValue : 0, - chartRangeMax: undefined, - chartRangeMin: undefined, - chartRangeClip: false - }, - // Defaults for bullet charts - bullet: { - targetColor : 'red', - targetWidth : 3, // width of the target bar in pixels - performanceColor : 'blue', - rangeColors : ['#D3DAFE', '#A8B6FF', '#7F94FF' ], - base : undefined // set this to a number to change the base start number - }, - // Defaults for pie charts - pie: { - sliceColors : ['#f00', '#0f0', '#00f'] - }, - // Defaults for box plots - box: { - raw: false, - boxLineColor: 'black', - boxFillColor: '#cdf', - whiskerColor: 'black', - outlierLineColor: '#333', - outlierFillColor: 'white', - medianColor: 'red', - showOutliers: true, - outlierIQR: 1.5, - spotRadius: 1.5, - target: undefined, - targetColor: '#4a2', - chartRangeMax: undefined, - chartRangeMin: undefined - } - }; - - // Provide a cross-browser interface to a few simple drawing primitives - var VCanvas_base, VCanvas_canvas, VCanvas_vml; - $.fn.simpledraw = function(width, height, use_existing) { - if (use_existing && this[0].VCanvas) { - return this[0].VCanvas; - } - if (width === undefined) { - width=$(this).innerWidth(); - } - if (height === undefined) { - height=$(this).innerHeight(); - } - if ($.browser.hasCanvas) { - return new VCanvas_canvas(width, height, this); - } else if ($.browser.msie) { - return new VCanvas_vml(width, height, this); - } else { - return false; - } - }; - - var pending = []; - - - $.fn.sparkline = function(uservalues, userOptions) { - return this.each(function() { - var options = new $.fn.sparkline.options(this, userOptions); - var render = function() { - var values, width, height; - if (uservalues==='html' || uservalues===undefined) { - var vals = this.getAttribute(options.get('tagValuesAttribute')); - if (vals===undefined || vals===null) { - vals = $(this).html(); - } - values = vals.replace(/(^\s*<!--)|(-->\s*$)|\s+/g, '').split(','); - } else { - values = uservalues; - } - - width = options.get('width')=='auto' ? values.length*options.get('defaultPixelsPerValue') : options.get('width'); - if (options.get('height') == 'auto') { - if (!options.get('composite') || !this.VCanvas) { - // must be a better way to get the line height - var tmp = document.createElement('span'); - tmp.innerHTML = 'a'; - $(this).html(tmp); - height = $(tmp).innerHeight(); - $(tmp).remove(); - } - } else { - height = options.get('height'); - } - - $.fn.sparkline[options.get('type')].call(this, values, options, width, height); - }; - // jQuery 1.3.0 completely changed the meaning of :hidden :-/ - if (($(this).html() && $(this).is(':hidden')) || ($.fn.jquery < "1.3.0" && $(this).parents().is(':hidden')) || !$(this).parents('body').length) { - pending.push([this, render]); - } else { - render.call(this); - } - }); - }; - - $.fn.sparkline.defaults = defaults; - - - $.sparkline_display_visible = function() { - for (var i=pending.length-1; i>=0; i--) { - var el = pending[i][0]; - if ($(el).is(':visible') && !$(el).parents().is(':hidden')) { - pending[i][1].call(el); - pending.splice(i, 1); - } - } - }; - - - /** - * User option handler - */ - var UNSET_OPTION = {}; - var normalizeValue = function(val) { - switch(val) { - case 'undefined': - val = undefined; - break; - case 'null': - val = null; - break; - case 'true': - val = true; - break; - case 'false': - val = false; - break; - default: - var nf = parseFloat(val); - if (val == nf) { - val = nf; - } - } - return val; - }; - $.fn.sparkline.options = function(tag, userOptions) { - var extendedOptions; - this.userOptions = userOptions = userOptions || {}; - this.tag = tag; - this.tagValCache = {}; - var defaults = $.fn.sparkline.defaults; - var base = defaults.common; - this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix); - - var tagOptionType = this.getTagSetting('type'); - if (tagOptionType === UNSET_OPTION) { - extendedOptions = defaults[userOptions.type || base.type]; - } else { - extendedOptions = defaults[tagOptionType]; - } - this.mergedOptions = $.extend({}, base, extendedOptions, userOptions); - }; - - - $.fn.sparkline.options.prototype.getTagSetting = function(key) { - var val, i, prefix = this.tagOptionsPrefix; - if (prefix === false || prefix === undefined) { - return UNSET_OPTION; - } - if (this.tagValCache.hasOwnProperty(key)) { - val = this.tagValCache.key; - } else { - val = this.tag.getAttribute(prefix + key); - if (val === undefined || val === null) { - val = UNSET_OPTION; - } else if (val.substr(0, 1) == '[') { - val = val.substr(1, val.length-2).split(','); - for(i=val.length; i--;) { - val[i] = normalizeValue(val[i].replace(/(^\s*)|(\s*$)/g, '')); - } - } else if (val.substr(0, 1) == '{') { - var pairs= val.substr(1, val.length-2).split(','); - val = {}; - for(i=pairs.length; i--;) { - var keyval = pairs[i].split(':', 2); - val[keyval[0].replace(/(^\s*)|(\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\s*)|(\s*$)/g, '')); - } - } else { - val = normalizeValue(val); - } - this.tagValCache.key = val; - } - return val; - }; - - $.fn.sparkline.options.prototype.get = function(key) { - var tagOption = this.getTagSetting(key); - if (tagOption !== UNSET_OPTION) { - return tagOption; - } - return this.mergedOptions[key]; - }; - - - /** - * Line charts - */ - $.fn.sparkline.line = function(values, options, width, height) { - var xvalues = [], yvalues = [], yminmax = []; - for (var i=0; i<values.length; i++) { - var val = values[i]; - var isstr = typeof(values[i])=='string'; - var isarray = typeof(values[i])=='object' && values[i] instanceof Array; - var sp = isstr && values[i].split(':'); - if (isstr && sp.length == 2) { // x:y - xvalues.push(Number(sp[0])); - yvalues.push(Number(sp[1])); - yminmax.push(Number(sp[1])); - } else if (isarray) { - xvalues.push(val[0]); - yvalues.push(val[1]); - yminmax.push(val[1]); - } else { - xvalues.push(i); - if (values[i]===null || values[i]=='null') { - yvalues.push(null); - } else { - yvalues.push(Number(val)); - yminmax.push(Number(val)); - } - } - } - if (options.get('xvalues')) { - xvalues = options.get('xvalues'); - } - - var maxy = Math.max.apply(Math, yminmax); - var maxyval = maxy; - var miny = Math.min.apply(Math, yminmax); - var minyval = miny; - - var maxx = Math.max.apply(Math, xvalues); - var minx = Math.min.apply(Math, xvalues); - - var normalRangeMin = options.get('normalRangeMin'); - var normalRangeMax = options.get('normalRangeMax'); - - if (normalRangeMin!==undefined) { - if (normalRangeMin<miny) { - miny = normalRangeMin; - } - if (normalRangeMax>maxy) { - maxy = normalRangeMax; - } - } - if (options.get('chartRangeMin')!==undefined && (options.get('chartRangeClip') || options.get('chartRangeMin')<miny)) { - miny = options.get('chartRangeMin'); - } - if (options.get('chartRangeMax')!==undefined && (options.get('chartRangeClip') || options.get('chartRangeMax')>maxy)) { - maxy = options.get('chartRangeMax'); - } - if (options.get('chartRangeMinX')!==undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX')<minx)) { - minx = options.get('chartRangeMinX'); - } - if (options.get('chartRangeMaxX')!==undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX')>maxx)) { - maxx = options.get('chartRangeMaxX'); - } - var rangex = maxx-minx === 0 ? 1 : maxx-minx; - var rangey = maxy-miny === 0 ? 1 : maxy-miny; - var vl = yvalues.length-1; - - if (vl<1) { - this.innerHTML = ''; - return; - } - - var target = $(this).simpledraw(width, height, options.get('composite')); - if (target) { - var canvas_width = target.pixel_width; - var canvas_height = target.pixel_height; - var canvas_top = 0; - var canvas_left = 0; - - var spotRadius = options.get('spotRadius'); - if (spotRadius && (canvas_width < (spotRadius*4) || canvas_height < (spotRadius*4))) { - spotRadius = 0; - } - if (spotRadius) { - // adjust the canvas size as required so that spots will fit - if (options.get('minSpotColor') || (options.get('spotColor') && yvalues[vl]==miny)) { - canvas_height -= Math.ceil(spotRadius); - } - if (options.get('maxSpotColor') || (options.get('spotColor') && yvalues[vl]==maxy)) { - canvas_height -= Math.ceil(spotRadius); - canvas_top += Math.ceil(spotRadius); - } - if (options.get('minSpotColor') || options.get('maxSpotColor') && (yvalues[0]==miny || yvalues[0]==maxy)) { - canvas_left += Math.ceil(spotRadius); - canvas_width -= Math.ceil(spotRadius); - } - if (options.get('spotColor') || (options.get('minSpotColor') || options.get('maxSpotColor') && (yvalues[vl]==miny||yvalues[vl]==maxy))) { - canvas_width -= Math.ceil(spotRadius); - } - } - - - canvas_height--; - - var drawNormalRange = function() { - if (normalRangeMin!==undefined) { - var ytop = canvas_top+Math.round(canvas_height-(canvas_height*((normalRangeMax-miny)/rangey))); - var height = Math.round((canvas_height*(normalRangeMax-normalRangeMin))/rangey); - target.drawRect(canvas_left, ytop, canvas_width, height, undefined, options.get('normalRangeColor')); - } - }; - - if (!options.get('drawNormalOnTop')) { - drawNormalRange(); - } - - var path = []; - var paths = [path]; - var x, y, vlen=yvalues.length; - for(i=0; i<vlen; i++) { - x=xvalues[i]; - y=yvalues[i]; - if (y===null) { - if (i) { - if (yvalues[i-1]!==null) { - path = []; - paths.push(path); - } - } - } else { - if (y < miny) { - y=miny; - } - if (y > maxy) { - y=maxy; - } - if (!path.length) { - // previous value was null - path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)), canvas_top+canvas_height]); - } - path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)), canvas_top+Math.round(canvas_height-(canvas_height*((y-miny)/rangey)))]); - } - } - var lineshapes = []; - var fillshapes = []; - var plen=paths.length; - for(i=0; i<plen; i++) { - path = paths[i]; - if (!path.length) { - continue; // last value was null - } - if (options.get('fillColor')) { - path.push([path[path.length-1][0], canvas_top+canvas_height-1]); - fillshapes.push(path.slice(0)); - path.pop(); - } - // if there's only a single point in this path, then we want to display it as a vertical line - // which means we keep path[0] as is - if (path.length>2) { - // else we want the first value - path[0] = [ path[0][0], path[1][1] ]; - } - lineshapes.push(path); - } - - // draw the fill first, then optionally the normal range, then the line on top of that - plen = fillshapes.length; - for(i=0; i<plen; i++) { - target.drawShape(fillshapes[i], undefined, options.get('fillColor')); - } - - if (options.get('drawNormalOnTop')) { - drawNormalRange(); - } - - plen = lineshapes.length; - for(i=0; i<plen; i++) { - target.drawShape(lineshapes[i], options.get('lineColor'), undefined, options.get('lineWidth')); - } - - if (spotRadius && options.get('spotColor')) { - target.drawCircle(canvas_left+Math.round(xvalues[xvalues.length-1]*(canvas_width/rangex)), canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[vl]-miny)/rangey))), spotRadius, undefined, options.get('spotColor')); - } - if (maxy!=minyval) { - if (spotRadius && options.get('minSpotColor')) { - x = xvalues[$.inArray(minyval, yvalues)]; - target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)), canvas_top+Math.round(canvas_height-(canvas_height*((minyval-miny)/rangey))), spotRadius, undefined, options.get('minSpotColor')); - } - if (spotRadius && options.get('maxSpotColor')) { - x = xvalues[$.inArray(maxyval, yvalues)]; - target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)), canvas_top+Math.round(canvas_height-(canvas_height*((maxyval-miny)/rangey))), spotRadius, undefined, options.get('maxSpotColor')); - } - } - - } else { - // Remove the tag contents if sparklines aren't supported - this.innerHTML = ''; - } - }; - - - /** - * Bar charts - */ - $.fn.sparkline.bar = function(values, options, width, height) { - width = (values.length * options.get('barWidth')) + ((values.length-1) * options.get('barSpacing')); - var num_values = []; - for(var i=0, vlen=values.length; i<vlen; i++) { - if (values[i]=='null' || values[i]===null) { - values[i] = null; - } else { - values[i] = Number(values[i]); - num_values.push(Number(values[i])); - } - } - var max = Math.max.apply(Math, num_values), - min = Math.min.apply(Math, num_values); - if (options.get('chartRangeMin')!==undefined && (options.get('chartRangeClip') || options.get('chartRangeMin')<min)) { - min = options.get('chartRangeMin'); - } - if (options.get('chartRangeMax')!==undefined && (options.get('chartRangeClip') || options.get('chartRangeMax')>max)) { - max = options.get('chartRangeMax'); - } - var zeroAxis = options.get('zeroAxis'); - if (zeroAxis === undefined) { - zeroAxis = min<0; - } - var range = max-min === 0 ? 1 : max-min; - - var colorMapByIndex, colorMapByValue; - if ($.isArray(options.get('colorMap'))) { - colorMapByIndex = options.get('colorMap'); - colorMapByValue = null; - } else { - colorMapByIndex = null; - colorMapByValue = options.get('colorMap'); - } - - var target = $(this).simpledraw(width, height, options.get('composite')); - if (target) { - var color, - canvas_height = target.pixel_height, - yzero = min<0 && zeroAxis ? canvas_height-Math.round(canvas_height * (Math.abs(min)/range))-1 : canvas_height-1; - - for(i=values.length; i--;) { - var x = i*(options.get('barWidth')+options.get('barSpacing')), - y, - val = values[i]; - if (val===null) { - if (options.get('nullColor')) { - color = options.get('nullColor'); - val = (zeroAxis && min<0) ? 0 : min; - height = 1; - y = (zeroAxis && min<0) ? yzero : canvas_height - height; - } else { - continue; - } - } else { - if (val < min) { - val=min; - } - if (val > max) { - val=max; - } - color = (val < 0) ? options.get('negBarColor') : options.get('barColor'); - if (zeroAxis && min<0) { - height = Math.round(canvas_height*((Math.abs(val)/range)))+1; - y = (val < 0) ? yzero : yzero-height; - } else { - height = Math.round(canvas_height*((val-min)/range))+1; - y = canvas_height-height; - } - if (val===0 && options.get('zeroColor')!==undefined) { - color = options.get('zeroColor'); - } - if (colorMapByValue && colorMapByValue[val]) { - color = colorMapByValue[val]; - } else if (colorMapByIndex && colorMapByIndex.length>i) { - color = colorMapByIndex[i]; - } - if (color===null) { - continue; - } - } - target.drawRect(x, y, options.get('barWidth')-1, height-1, color, color); - } - } else { - // Remove the tag contents if sparklines aren't supported - this.innerHTML = ''; - } - }; - - - /** - * Tristate charts - */ - $.fn.sparkline.tristate = function(values, options, width, height) { - values = $.map(values, Number); - width = (values.length * options.get('barWidth')) + ((values.length-1) * options.get('barSpacing')); - - var colorMapByIndex, colorMapByValue; - if ($.isArray(options.get('colorMap'))) { - colorMapByIndex = options.get('colorMap'); - colorMapByValue = null; - } else { - colorMapByIndex = null; - colorMapByValue = options.get('colorMap'); - } - - var target = $(this).simpledraw(width, height, options.get('composite')); - if (target) { - var canvas_height = target.pixel_height, - half_height = Math.round(canvas_height/2); - - for(var i=values.length; i--;) { - var x = i*(options.get('barWidth')+options.get('barSpacing')), - y, color; - if (values[i] < 0) { - y = half_height; - height = half_height-1; - color = options.get('negBarColor'); - } else if (values[i] > 0) { - y = 0; - height = half_height-1; - color = options.get('posBarColor'); - } else { - y = half_height-1; - height = 2; - color = options.get('zeroBarColor'); - } - if (colorMapByValue && colorMapByValue[values[i]]) { - color = colorMapByValue[values[i]]; - } else if (colorMapByIndex && colorMapByIndex.length>i) { - color = colorMapByIndex[i]; - } - if (color===null) { - continue; - } - target.drawRect(x, y, options.get('barWidth')-1, height-1, color, color); - } - } else { - // Remove the tag contents if sparklines aren't supported - this.innerHTML = ''; - } - }; - - - /** - * Discrete charts - */ - $.fn.sparkline.discrete = function(values, options, width, height) { - values = $.map(values, Number); - width = options.get('width')=='auto' ? values.length*2 : width; - var interval = Math.floor(width / values.length); - - var target = $(this).simpledraw(width, height, options.get('composite')); - if (target) { - var canvas_height = target.pixel_height, - line_height = options.get('lineHeight') == 'auto' ? Math.round(canvas_height * 0.3) : options.get('lineHeight'), - pheight = canvas_height - line_height, - min = Math.min.apply(Math, values), - max = Math.max.apply(Math, values); - if (options.get('chartRangeMin')!==undefined && (options.get('chartRangeClip') || options.get('chartRangeMin')<min)) { - min = options.get('chartRangeMin'); - } - if (options.get('chartRangeMax')!==undefined && (options.get('chartRangeClip') || options.get('chartRangeMax')>max)) { - max = options.get('chartRangeMax'); - } - var range = max-min; - - for(var i=values.length; i--;) { - var val = values[i]; - if (val < min) { - val=min; - } - if (val > max) { - val=max; - } - var x = (i*interval), - ytop = Math.round(pheight-pheight*((val-min)/range)); - target.drawLine(x, ytop, x, ytop+line_height, (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor')); - } - } else { - // Remove the tag contents if sparklines aren't supported - this.innerHTML = ''; - } - - }; - - - /** - * Bullet charts - */ - $.fn.sparkline.bullet = function(values, options, width, height) { - values = $.map(values, Number); - // target, performance, range1, range2, range3 - - width = options.get('width')=='auto' ? '4.0em' : width; - - var target = $(this).simpledraw(width, height, options.get('composite')); - if (target && values.length>1) { - var canvas_width = target.pixel_width-Math.ceil(options.get('targetWidth')/2), - canvas_height = target.pixel_height, - min = Math.min.apply(Math, values), - max = Math.max.apply(Math, values); - - if (options.get('base') === undefined) { - min = min < 0 ? min : 0; - } else { - min = options.get('base'); - } - var range = max-min; - - // draw range values - for(var i=2, vlen=values.length; i<vlen; i++) { - var rangeval = values[i], - rangewidth = Math.round(canvas_width*((rangeval-min)/range)); - target.drawRect(0, 0, rangewidth-1, canvas_height-1, options.get('rangeColors')[i-2], options.get('rangeColors')[i-2]); - } - - // draw the performance bar - var perfval = values[1], - perfwidth = Math.round(canvas_width*((perfval-min)/range)); - target.drawRect(0, Math.round(canvas_height*0.3), perfwidth-1, Math.round(canvas_height*0.4)-1, options.get('performanceColor'), options.get('performanceColor')); - - // draw the target line - var targetval = values[0], - x = Math.round(canvas_width*((targetval-min)/range)-(options.get('targetWidth')/2)), - targettop = Math.round(canvas_height*0.10), - targetheight = canvas_height-(targettop*2); - target.drawRect(x, targettop, options.get('targetWidth')-1, targetheight-1, options.get('targetColor'), options.get('targetColor')); - } else { - // Remove the tag contents if sparklines aren't supported - this.innerHTML = ''; - } - }; - - - /** - * Pie charts - */ - $.fn.sparkline.pie = function(values, options, width, height) { - values = $.map(values, Number); - width = options.get('width')=='auto' ? height : width; - - var target = $(this).simpledraw(width, height, options.get('composite')); - if (target && values.length>1) { - var canvas_width = target.pixel_width, - canvas_height = target.pixel_height, - radius = Math.floor(Math.min(canvas_width, canvas_height)/2), - total = 0, - next = 0, - circle = 2*Math.PI; - - for(var i=values.length; i--;) { - total += values[i]; - } - - if (options.get('offset')) { - next += (2*Math.PI)*(options.get('offset')/360); - } - var vlen = values.length; - for(i=0; i<vlen; i++) { - var start = next; - var end = next; - if (total > 0) { // avoid divide by zero - end = next + (circle*(values[i]/total)); - } - target.drawPieSlice(radius, radius, radius, start, end, undefined, options.get('sliceColors')[i % options.get('sliceColors').length]); - next = end; - } - } - }; - - - /** - * Box plots - */ - var quartile = function(values, q) { - if (q==2) { - var vl2 = Math.floor(values.length/2); - return values.length % 2 ? values[vl2] : (values[vl2]+values[vl2+1])/2; - } else { - var vl4 = Math.floor(values.length/4); - return values.length % 2 ? (values[vl4*q]+values[vl4*q+1])/2 : values[vl4*q]; - } - }; - - $.fn.sparkline.box = function(values, options, width, height) { - values = $.map(values, Number); - width = options.get('width')=='auto' ? '4.0em' : width; - - var minvalue = options.get('chartRangeMin')===undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'), - maxvalue = options.get('chartRangeMax')===undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'), - target = $(this).simpledraw(width, height, options.get('composite')), - vlen = values.length, - lwhisker, loutlier, q1, q2, q3, rwhisker, routlier; - - if (target && values.length>1) { - var canvas_width = target.pixel_width, - canvas_height = target.pixel_height; - if (options.get('raw')) { - if (options.get('showOutliers') && values.length>5) { - loutlier=values[0]; lwhisker=values[1]; q1=values[2]; q2=values[3]; q3=values[4]; rwhisker=values[5]; routlier=values[6]; - } else { - lwhisker=values[0]; q1=values[1]; q2=values[2]; q3=values[3]; rwhisker=values[4]; - } - } else { - values.sort(function(a, b) { return a-b; }); - q1 = quartile(values, 1); - q2 = quartile(values, 2); - q3 = quartile(values, 3); - var iqr = q3-q1; - if (options.get('showOutliers')) { - lwhisker=undefined; rwhisker=undefined; - for(var i=0; i<vlen; i++) { - if (lwhisker===undefined && values[i] > q1-(iqr*options.get('outlierIQR'))) { - lwhisker = values[i]; - } - if (values[i] < q3+(iqr*options.get('outlierIQR'))) { - rwhisker = values[i]; - } - } - loutlier = values[0]; - routlier = values[vlen-1]; - } else { - lwhisker = values[0]; - rwhisker = values[vlen-1]; - } - } - - var unitsize = canvas_width / (maxvalue-minvalue+1), - canvas_left = 0; - if (options.get('showOutliers')) { - canvas_left = Math.ceil(options.get('spotRadius')); - canvas_width -= 2*Math.ceil(options.get('spotRadius')); - unitsize = canvas_width / (maxvalue-minvalue+1); - if (loutlier < lwhisker) { - target.drawCircle((loutlier-minvalue)*unitsize+canvas_left, canvas_height/2, options.get('spotRadius'), options.get('outlierLineColor'), options.get('outlierFillColor')); - } - if (routlier > rwhisker) { - target.drawCircle((routlier-minvalue)*unitsize+canvas_left, canvas_height/2, options.get('spotRadius'), options.get('outlierLineColor'), options.get('outlierFillColor')); - } - } - - // box - target.drawRect( - Math.round((q1-minvalue)*unitsize+canvas_left), - Math.round(canvas_height*0.1), - Math.round((q3-q1)*unitsize), - Math.round(canvas_height*0.8), - options.get('boxLineColor'), - options.get('boxFillColor')); - // left whisker - target.drawLine( - Math.round((lwhisker-minvalue)*unitsize+canvas_left), - Math.round(canvas_height/2), - Math.round((q1-minvalue)*unitsize+canvas_left), - Math.round(canvas_height/2), - options.get('lineColor')); - target.drawLine( - Math.round((lwhisker-minvalue)*unitsize+canvas_left), - Math.round(canvas_height/4), - Math.round((lwhisker-minvalue)*unitsize+canvas_left), - Math.round(canvas_height-canvas_height/4), - options.get('whiskerColor')); - // right whisker - target.drawLine(Math.round((rwhisker-minvalue)*unitsize+canvas_left), - Math.round(canvas_height/2), - Math.round((q3-minvalue)*unitsize+canvas_left), - Math.round(canvas_height/2), - options.get('lineColor')); - target.drawLine( - Math.round((rwhisker-minvalue)*unitsize+canvas_left), - Math.round(canvas_height/4), - Math.round((rwhisker-minvalue)*unitsize+canvas_left), - Math.round(canvas_height-canvas_height/4), - options.get('whiskerColor')); - // median line - target.drawLine( - Math.round((q2-minvalue)*unitsize+canvas_left), - Math.round(canvas_height*0.1), - Math.round((q2-minvalue)*unitsize+canvas_left), - Math.round(canvas_height*0.9), - options.get('medianColor')); - if (options.get('target')) { - var size = Math.ceil(options.get('spotRadius')); - target.drawLine( - Math.round((options.get('target')-minvalue)*unitsize+canvas_left), - Math.round((canvas_height/2)-size), - Math.round((options.get('target')-minvalue)*unitsize+canvas_left), - Math.round((canvas_height/2)+size), - options.get('targetColor')); - target.drawLine( - Math.round((options.get('target')-minvalue)*unitsize+canvas_left-size), - Math.round(canvas_height/2), - Math.round((options.get('target')-minvalue)*unitsize+canvas_left+size), - Math.round(canvas_height/2), - options.get('targetColor')); - } - } else { - // Remove the tag contents if sparklines aren't supported - this.innerHTML = ''; - } - }; - - - // Setup a very simple "virtual canvas" to make drawing the few shapes we need easier - // This is accessible as $(foo).simpledraw() - - if ($.browser.msie && !document.namespaces.v) { - document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML'); - } - - if ($.browser.hasCanvas === undefined) { - var t = document.createElement('canvas'); - $.browser.hasCanvas = t.getContext!==undefined; - } - - VCanvas_base = function(width, height, target) { - }; - - VCanvas_base.prototype = { - init : function(width, height, target) { - this.width = width; - this.height = height; - this.target = target; - if (target[0]) { - target=target[0]; - } - target.VCanvas = this; - }, - - drawShape : function(path, lineColor, fillColor, lineWidth) { - alert('drawShape not implemented'); - }, - - drawLine : function(x1, y1, x2, y2, lineColor, lineWidth) { - return this.drawShape([ [x1,y1], [x2,y2] ], lineColor, lineWidth); - }, - - drawCircle : function(x, y, radius, lineColor, fillColor) { - alert('drawCircle not implemented'); - }, - - drawPieSlice : function(x, y, radius, startAngle, endAngle, lineColor, fillColor) { - alert('drawPieSlice not implemented'); - }, - - drawRect : function(x, y, width, height, lineColor, fillColor) { - alert('drawRect not implemented'); - }, - - getElement : function() { - return this.canvas; - }, - - _insert : function(el, target) { - $(target).html(el); - } - }; - - VCanvas_canvas = function(width, height, target) { - return this.init(width, height, target); - }; - - VCanvas_canvas.prototype = $.extend(new VCanvas_base(), { - _super : VCanvas_base.prototype, - - init : function(width, height, target) { - this._super.init(width, height, target); - this.canvas = document.createElement('canvas'); - if (target[0]) { - target=target[0]; - } - target.VCanvas = this; - $(this.canvas).css({ display:'inline-block', width:width, height:height, verticalAlign:'top' }); - this._insert(this.canvas, target); - this.pixel_height = $(this.canvas).height(); - this.pixel_width = $(this.canvas).width(); - this.canvas.width = this.pixel_width; - this.canvas.height = this.pixel_height; - $(this.canvas).css({width: this.pixel_width, height: this.pixel_height}); - }, - - _getContext : function(lineColor, fillColor, lineWidth) { - var context = this.canvas.getContext('2d'); - if (lineColor !== undefined) { - context.strokeStyle = lineColor; - } - context.lineWidth = lineWidth===undefined ? 1 : lineWidth; - if (fillColor !== undefined) { - context.fillStyle = fillColor; - } - return context; - }, - - drawShape : function(path, lineColor, fillColor, lineWidth) { - var context = this._getContext(lineColor, fillColor, lineWidth); - context.beginPath(); - context.moveTo(path[0][0]+0.5, path[0][1]+0.5); - for(var i=1, plen=path.length; i<plen; i++) { - context.lineTo(path[i][0]+0.5, path[i][1]+0.5); // the 0.5 offset gives us crisp pixel-width lines - } - if (lineColor !== undefined) { - context.stroke(); - } - if (fillColor !== undefined) { - context.fill(); - } - }, - - drawCircle : function(x, y, radius, lineColor, fillColor) { - var context = this._getContext(lineColor, fillColor); - context.beginPath(); - context.arc(x, y, radius, 0, 2*Math.PI, false); - if (lineColor !== undefined) { - context.stroke(); - } - if (fillColor !== undefined) { - context.fill(); - } - }, - - drawPieSlice : function(x, y, radius, startAngle, endAngle, lineColor, fillColor) { - var context = this._getContext(lineColor, fillColor); - context.beginPath(); - context.moveTo(x, y); - context.arc(x, y, radius, startAngle, endAngle, false); - context.lineTo(x, y); - context.closePath(); - if (lineColor !== undefined) { - context.stroke(); - } - if (fillColor) { - context.fill(); - } - }, - - drawRect : function(x, y, width, height, lineColor, fillColor) { - return this.drawShape([ [x,y], [x+width, y], [x+width, y+height], [x, y+height], [x, y] ], lineColor, fillColor); - } - - }); - - VCanvas_vml = function(width, height, target) { - return this.init(width, height, target); - }; - - VCanvas_vml.prototype = $.extend(new VCanvas_base(), { - _super : VCanvas_base.prototype, - - init : function(width, height, target) { - this._super.init(width, height, target); - if (target[0]) { - target=target[0]; - } - target.VCanvas = this; - this.canvas = document.createElement('span'); - $(this.canvas).css({ display:'inline-block', position: 'relative', overflow:'hidden', width:width, height:height, margin:'0px', padding:'0px', verticalAlign: 'top'}); - this._insert(this.canvas, target); - this.pixel_height = $(this.canvas).height(); - this.pixel_width = $(this.canvas).width(); - this.canvas.width = this.pixel_width; - this.canvas.height = this.pixel_height; - var groupel = '<v:group coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'"' + - ' style="position:absolute;top:0;left:0;width:'+this.pixel_width+'px;height='+this.pixel_height+'px;"></v:group>'; - this.canvas.insertAdjacentHTML('beforeEnd', groupel); - this.group = $(this.canvas).children()[0]; - }, - - drawShape : function(path, lineColor, fillColor, lineWidth) { - var vpath = []; - for(var i=0, plen=path.length; i<plen; i++) { - vpath[i] = ''+(path[i][0])+','+(path[i][1]); - } - var initial = vpath.splice(0,1); - lineWidth = lineWidth === undefined ? 1 : lineWidth; - var stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="'+lineWidth+'" strokeColor="'+lineColor+'" '; - var fill = fillColor === undefined ? ' filled="false"' : ' fillColor="'+fillColor+'" filled="true" '; - var closed = vpath[0] == vpath[vpath.length-1] ? 'x ' : ''; - var vel = '<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" ' + - stroke + - fill + - ' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" ' + - ' path="m '+initial+' l '+vpath.join(', ')+' '+closed+'e">' + - ' </v:shape>'; - this.group.insertAdjacentHTML('beforeEnd', vel); - }, - - drawCircle : function(x, y, radius, lineColor, fillColor) { - x -= radius+1; - y -= radius+1; - var stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1" strokeColor="'+lineColor+'" '; - var fill = fillColor === undefined ? ' filled="false"' : ' fillColor="'+fillColor+'" filled="true" '; - var vel = '<v:oval ' + - stroke + - fill + - ' style="position:absolute;top:'+y+'px; left:'+x+'px; width:'+(radius*2)+'px; height:'+(radius*2)+'px"></v:oval>'; - this.group.insertAdjacentHTML('beforeEnd', vel); - - }, - - drawPieSlice : function(x, y, radius, startAngle, endAngle, lineColor, fillColor) { - if (startAngle == endAngle) { - return; // VML seems to have problem when start angle equals end angle. - } - if ((endAngle - startAngle) == (2*Math.PI)) { - startAngle = 0.0; // VML seems to have a problem when drawing a full circle that doesn't start 0 - endAngle = (2*Math.PI); - } - - var startx = x + Math.round(Math.cos(startAngle) * radius); - var starty = y + Math.round(Math.sin(startAngle) * radius); - var endx = x + Math.round(Math.cos(endAngle) * radius); - var endy = y + Math.round(Math.sin(endAngle) * radius); - - // Prevent very small slices from being mistaken as a whole pie - if (startx==endx && starty==endy && (endAngle-startAngle) < Math.PI) { - return; - } - - var vpath = [ x-radius, y-radius, x+radius, y+radius, startx, starty, endx, endy ]; - var stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1" strokeColor="'+lineColor+'" '; - var fill = fillColor === undefined ? ' filled="false"' : ' fillColor="'+fillColor+'" filled="true" '; - var vel = '<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" ' + - stroke + - fill + - ' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" ' + - ' path="m '+x+','+y+' wa '+vpath.join(', ')+' x e">' + - ' </v:shape>'; - this.group.insertAdjacentHTML('beforeEnd', vel); - }, - - drawRect : function(x, y, width, height, lineColor, fillColor) { - return this.drawShape( [ [x, y], [x, y+height], [x+width, y+height], [x+width, y], [x, y] ], lineColor, fillColor); - } - }); - -})(jQuery); diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-2.0.min.js b/modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-2.0.min.js new file mode 100644 index 0000000..ea174b6 --- /dev/null +++ b/modules/enterprise/gui/coregui/src/main/webapp/js/jquery.sparkline-2.0.min.js @@ -0,0 +1,5 @@ +/* jquery.sparkline 2.0 - http://omnipotent.net/jquery.sparkline/ +** Licensed under the New BSD License - see above site for details */ + +(function(a){"use strict";var b={},c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I=0;c=function(){return{common:{type:"line",lineColor:"#00f",fillColor:"#cdf",defaultPixelsPerValue:3,width:"auto",height:"auto",composite:!1,tagValuesAttribute:"values",tagOptionsPrefix:"spark",enableTagOptions:!1,enableHighlight:!0,highlightLighten:1.4,tooltipSkipNull:!0,tooltipPrefix:"",tooltipSuffix:"",disableHiddenCheck:!1,numberFormatter:!1,numberDigitGroupCount:3,numberDigitGroupSep:",",numberDecimalMark:".",disableTooltips:!1,disableInteraction:!1},line:{spotColor:"#f80",highlightSpotColor:"#5f5",highlightLineColor:"#f22",spotRadius:1.5,minSpotColor:"#f80",maxSpotColor:"#f80",lineWidth:1,normalRangeMin:undefined,normalRangeMax:undefined,normalRangeColor:"#ccc",drawNormalOnTop:!1,chartRangeMin:undefined,chartRangeMax:undefined,chartRangeMinX:undefined,chartRangeMaxX:undefined,tooltipFormat:new e('<span style="color: {{color}}">●</span> {{prefix}}{{y}}{{suffix}}')}, bar:{barColor:"#3366cc",negBarColor:"#f44",stackedBarColor:["#3366cc","#dc3912","#ff9900","#109618","#66aa00","#dd4477","#0099c6","#990099"],zeroColor:undefined,nullColor:undefined,zeroAxis:!0,barWidth:4,barSpacing:1,chartRangeMax:undefined,chartRangeMin:undefined,chartRangeClip:!1,colorMap:undefined,tooltipFormat:new e('<span style="color: {{color}}">●</span> {{prefix}}{{value}}{{suffix}}')},tristate:{barWidth:4,barSpacing:1,posBarColor:"#6f6",negBarColor:"#f44",zeroBarColor:"#999",colorMap:{},tooltipFormat:new e('<span style="color: {{color}}">●</span> {{value:map}}'),tooltipValueLookups:{map:{"-1":"Loss",0:"Draw",1:"Win"}}},discrete:{lineHeight:"auto",thresholdColor:undefined,thresholdValue:0,chartRangeMax:undefined,chartRangeMin:undefined,chartRangeClip:!1,tooltipFormat:new e("{{prefix}}{{value}}{{suffix}}")},bullet:{targetColor:"#f33",targetWidth:3,performanceColor:"#33f",rangeColors:["#d3dafe","#a8b6ff","#7f94ff"],base:undefined,tooltipFormat:new e("{{field key:fields}} - {{value}}"),tooltipValueLookups:{fields:{r:"Range",p:"Performance",t:"Target"}}},pie:{offset:0,sliceColors:["#3366cc","#dc3912","#ff9900","#109618","#66aa00","#dd4477","#0099c6","#990099"],borderWidth:0,borderColor:"#000",tooltipFormat:new e('<span style="color: {{color}}">●</span> {{value}} ({{percent.1}}%)')},box:{raw:!1,boxLineColor:"#000",boxFillColor:"#cdf",whiskerColor:"#000",outlierLineColor:"#333",outlierFillColor:"#fff",medianColor:"#f00",showOutliers:!0,outlierIQR:1.5,spotRadius:1.5,target:undefined,targetColor:"#4a2",chartRangeMax:undefined,chartRangeMin:undefined,tooltipFormat:new e("{{field:fields}}: {{value}}"),tooltipFormatFieldlistKey:"field",tooltipValueLookups:{fields:{lq:"Lower Quartile",med:"Median",uq:"Upper Quartile",lo:"Left Outlier",ro:"Right Outlier",lw:"Left Whisker",rw:"Right Whisker"}}}}},B='.jqstooltip { position: absolute;left: 0px;top: 0px;visibility: hidden;background: rgb(0, 0, 0) transparent;background-color: rgba(0,0,0, 0.6);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)";color: white;font: 10px arial, san serif;text-align: left;white-space: nowrap;padding: 5px;border: 1px solid white;}.jqsfield { color: white;font: 10px arial, san serif;text-align: left;}',C=function(){n(B)},a(C),d=function(){var b,c;return b=function(){this.init.apply(this,arguments)},arguments.length>1?(arguments[0]?(b.prototype=a.extend(new arguments[0],arguments[arguments.length-1]),b._super=arguments[0].prototype):b.prototype=arguments[arguments.length-1],arguments.length>2&&(c=Array.prototype.slice.call(arguments,1,-1),c.unshift(b.prototype),a.extend.apply(a,c))):b.prototype=arguments[0],b.prototype.cls=b,b},a.SPFormatClass=e=d({fre:/{{([\w.]+?)(:(.+?))?}}/g,precre:/(\w+).(\d+)/,init:function(a,b){this.format=a,this.fclass=b},render:function(a,b,c){var d=this, e=a,f,g,h,i,j;return this.format.replace(this.fre,function(){var a;return g=arguments[1],h=arguments[3],f=d.precre.exec(g),f?(j=f[2],g=f[1]):j=!1,i=e[g],i===undefined?"":h&&b&&b[h]?(a=b[h],a.get?b[h].get(i)||i:b[h][i]||i):(k(i)&&(c.get("numberFormatter")?i=c.get("numberFormatter")(i):i=p(i,j,c.get("numberDigitGroupCount"),c.get("numberDigitGroupSep"),c.get("numberDecimalMark"))),i)})}}),a.spformat=function(a,b){return new e(a,b)},f=function(a,b,c){return a<b?b:a>c?c:a},g=function(a,b){var c;return b===2?(c=Math.floor(a.length/2),a.length%2?a[c]:(a[c]+a[c+1])/2):(c=Math.floor(a.length/4),a.length%2?(a[c*b]+a[c*b+1])/2:a[c*b])},h=function(a){var b;switch(a){case"undefined":a=undefined;break;case"null":a=null;break;case"true":a=!0;break;case"false":a=!1;break;default:b=parseFloat(a),a==b&&(a=b)}return a},i=function(a){var b,c=[];for(b=a.length;b--;)c[b]=h(a[b]);return c},j=function(a,b){var c,d,e=[];for(c=0,d=a.length;c<d;c++)a[c]!==b&&e.push(a[c]);return e},k=function(a){retur n!isNaN(parseFloat(a))&&isFinite(a)},p=function(b,c,d,e,f){var g,h;b=(c===!1?parseFloat(b).toString():b.toFixed(c)).split(""),g=(g=a.inArray(".",b))<0?b.length:g,g<b.length&&(b[g]=f);for(h=g-d;h>0;h-=d)b.splice(h,0,e);return b.join("")},l=function(a,b,c){var d;for(d=b.length;d--;)if(b[d]!==a||!c&&a===null)return!1;return!0},m=function(a){var b=0,c;for(c=a.length;c--;)b+=typeof a[c]=="number"?a[c]:0;return b},o=function(b){return a.isArray(b)?b:[b]},n=function(a){var b;document.createStyleSheet?document.createStyleSheet().cssText=a:(b=document.createElement("style"),b.type="text/css",document.getElementsByTagName("head")[0].appendChild(b),b[typeof document.body.style.WebkitAppearance=="string"?"innerText":"innerHTML"]=a)},a.fn.simpledraw=function(b,c,d,e){var f,g;if(d&&(f=this.data("_jqs_vcanvas")))return f;b===undefined&&(b=a(this).innerWidth()),c===undefined&&(c=a(this).innerHeight());if(a.browser.hasCanvas)f=new F(b,c,this,e);else{if(!a.browser.msie)return!1;f=new G(b,c,th is)}return g=a(this).data("_jqs_mhandler"),g&&g.registerCanvas(f),f},a.fn.cleardraw=function(){var a=this.data("_jqs_vcanvas");a&&a.reset()},a.RangeMapClass=q=d({init:function(a){var b,c,d=[];for(b in a)a.hasOwnProperty(b)&&typeof b=="string"&&b.indexOf(":")>-1&&(c=b.split(":"),c[0]=c[0].length===0?-Infinity:parseFloat(c[0]),c[1]=c[1].length===0?Infinity:parseFloat(c[1]),c[2]=a[b],d.push(c));this.map=a,this.rangelist=d||!1},get:function(a){var b=this.rangelist,c,d,e;if((e=this.map[a])!==undefined)return e;if(b)for(c=b.length;c--;){d=b[c];if(d[0]<=a&&d[1]>=a)return d[2]}return undefined}}),a.range_map=function(a){return new q(a)},r=d({init:function(b,c){var d=a(b);this.$el=d,this.options=c,this.currentPageX=0,this.currentPageY=0,this.el=b,this.splist=[],this.tooltip=null,this.over=!1,this.displayTooltips=!c.get("disableTooltips"),this.highlightEnabled=!c.get("disableHighlight")},registerSparkline:function(a){this.splist.push(a),this.over&&this.updateDisplay()},registerCanvas: function(b){var c=a(b.canvas);this.canvas=b,this.$canvas=c,c.mouseenter(a.proxy(this.mouseenter,this)),c.mouseleave(a.proxy(this.mouseleave,this)),c.click(a.proxy(this.mouseclick,this))},reset:function(a){this.splist=[],this.tooltip&&a&&(this.tooltip.remove(),this.tooltip=undefined)},mouseclick:function(b){var c=a.Event("sparklineClick");c.originalEvent=b,c.sparklines=this.splist,this.$el.trigger(c)},mouseenter:function(b){a(document.body).unbind("mousemove.jqs"),a(document.body).bind("mousemove.jqs",a.proxy(this.mousemove,this)),this.over=!0,this.currentPageX=b.pageX,this.currentPageY=b.pageY,this.currentEl=b.target,!this.tooltip&&this.displayTooltips&&(this.tooltip=new s(this.options),this.tooltip.updatePosition(b.pageX,b.pageY)),this.updateDisplay()},mouseleave:function(){a(document.body).unbind("mousemove.jqs");var b=this.splist,c=b.length,d=!1,e,f;this.over=!1,this.currentEl=null,this.tooltip&&(this.tooltip.remove(),this.tooltip=null);for(f=0;f<c;f++)e=b[f],e.clearRegio nHighlight()&&(d=!0);d&&this.canvas.render()},mousemove:function(a){this.currentPageX=a.pageX,this.currentPageY=a.pageY,this.currentEl=a.target,this.tooltip&&this.tooltip.updatePosition(a.pageX,a.pageY),this.updateDisplay()},updateDisplay:function(){var b=this.splist,c=b.length,d=!1,e=this.$canvas.offset(),f=this.currentPageX-e.left,g=this.currentPageY-e.top,h,i,j,k,l;if(!this.over)return;for(j=0;j<c;j++)i=b[j],k=i.setRegionHighlight(this.currentEl,f,g),k&&(d=!0);if(d){l=a.Event("sparklineRegionChange"),l.sparklines=this.splist,this.$el.trigger(l);if(this.tooltip){h="";for(j=0;j<c;j++)i=b[j],h+=i.getCurrentRegionTooltip();this.tooltip.setContent(h)}this.disableHighlight||this.canvas.render()}k===null&&this.mouseleave()}}),s=d({sizeStyle:"position: static !important;display: block !important;visibility: hidden !important;float: left !important;",init:function(b){var c=b.get("tooltipClassname","jqstooltip"),d=this.sizeStyle,e;this.container=b.get("tooltipContainer")||document. body,this.tooltipOffsetX=b.get("tooltipOffsetX",10),this.tooltipOffsetY=b.get("tooltipOffsetY",12),a("#jqssizetip").remove(),a("#jqstooltip").remove(),this.sizetip=a("<div/>",{id:"jqssizetip",style:d,"class":c}),this.tooltip=a("<div/>",{id:"jqstooltip","class":c}).appendTo(this.container),e=this.tooltip.offset(),this.offsetLeft=e.left,this.offsetTop=e.top,this.hidden=!0,a(window).unbind("resize.jqs scroll.jqs"),a(window).bind("resize.jqs scroll.jqs",a.proxy(this.updateWindowDims,this)),this.updateWindowDims()},updateWindowDims:function(){this.scrollTop=a(window).scrollTop(),this.scrollLeft=a(window).scrollLeft(),this.scrollRight=this.scrollLeft+a(window).width(),this.updatePosition()},getSize:function(a){this.sizetip.html(a).appendTo(this.container),this.width=this.sizetip.width()+1,this.height=this.sizetip.height(),this.sizetip.remove()},setContent:function(a){if(!a){this.tooltip.css("visibility","hidden"),this.hidden=!0;return}this.getSize(a),this.tooltip.html(a).css({widt h:this.width,height:this.height,visibility:"visible"}),this.hidden&&(this.hidden=!1,this.updatePosition())},updatePosition:function(a,b){if(a===undefined){if(this.mousex===undefined)return;a=this.mousex-this.offsetLeft,b=this.mousey-this.offsetTop}else this.mousex=a-=this.offsetLeft,this.mousey=b-=this.offsetTop;if(!this.height||!this.width||this.hidden)return;b-=this.height+this.tooltipOffsetY,a+=this.tooltipOffsetX,b<this.scrollTop&&(b=this.scrollTop),a<this.scrollLeft?a=this.scrollLeft:a+this.width>this.scrollRight&&(a=this.scrollRight-this.width),this.tooltip.css({left:a,top:b})},remove:function(){this.tooltip.remove(),this.sizetip.remove(),this.sizetip=this.tooltip=undefined,a(window).unbind("resize.jqs scroll.jqs")}}),H=[],a.fn.sparkline=function(b,c){return this.each(function(){var d=new a.fn.sparkline.options(this,c),e=a(this),f,g;f=function(){var c,f,g,h,i,j,k;if(b==="html"||b===undefined){k=this.getAttribute(d.get("tagValuesAttribute"));if(k===undefined||k===null)k =e.html();c=k.replace(/(^\s*<!--)|(-->\s*$)|\s+/g,"").split(",")}else c=b;f=d.get("width")==="auto"?c.length*d.get("defaultPixelsPerValue"):d.get("width");if(d.get("height")==="auto"){if(!d.get("composite")||!a.data(this,"_jqs_vcanvas"))h=document.createElement("span"),h.innerHTML="a",e.html(h),g=a(h).innerHeight()||a(h).height(),a(h).remove(),h=null}else g=d.get("height");d.get("disableInteraction")?i=!1:(i=a.data(this,"_jqs_mhandler"),i?d.get("composite")||i.reset():(i=new r(this,d),a.data(this,"_jqs_mhandler",i)));if(d.get("composite")&&!a.data(this,"_jqs_vcanvas")){a.data(this,"_jqs_errnotify")||(alert("Attempted to attach a composite sparkline to an element with no existing sparkline"),a.data(this,"_jqs_errnotify",!0));return}j=new(a.fn.sparkline[d.get("type")])(this,c,d,f,g),j.render(),i&&i.registerSparkline(j)};if(a(this).html()&&!d.get("disableHiddenCheck")&&a(this).is(":hidden")||a.fn.jquery<"1.3.0"&&a(this).parents().is(":hidden")||!a(this).parents("body").length){ if(!d.get("composite")&&a.data(this,"_jqs_pending"))for(g=H.length;g;g--)H[g-1][0]==this&&H.splice(g-1,1);H.push([this,f]),a.data(this,"_jqs_pending",!0)}else f.call(this)})},a.fn.sparkline.defaults=c(),a.sparkline_display_visible=function(){var b,c,d,e=[];for(c=0,d=H.length;c<d;c++)b=H[c][0],a(b).is(":visible")&&!a(b).parents().is(":hidden")?(H[c][1].call(b),a.data(H[c][0],"_jqs_pending",!1),e.push(c)):!a(b).closest("html").length&&!a.data(b,"_jqs_pending")&&(a.data(H[c][0],"_jqs_pending",!1),e.push(c));for(c=e.length;c;c--)H.splice(e[c-1],1)},a.fn.sparkline.options=d({init:function(c,d){var e,f,g,h;this.userOptions=d=d||{},this.tag=c,this.tagValCache={},f=a.fn.sparkline.defaults,g=f.common,this.tagOptionsPrefix=d.enableTagOptions&&(d.tagOptionsPrefix||g.tagOptionsPrefix),h=this.getTagSetting("type"),h===b?e=f[d.type||g.type]:e=f[h],this.mergedOptions=a.extend({},g,e,d)},getTagSetting:function(a){var c=this.tagOptionsPrefix,d,e,f,g;if(c===!1||c===undefined)return b;if(this. tagValCache.hasOwnProperty(a))d=this.tagValCache.key;else{d=this.tag.getAttribute(c+a);if(d===undefined||d===null)d=b;else if(d.substr(0,1)==="["){d=d.substr(1,d.length-2).split(",");for(e=d.length;e--;)d[e]=h(d[e].replace(/(^\s*)|(\s*$)/g,""))}else if(d.substr(0,1)==="{"){f=d.substr(1,d.length-2).split(","),d={};for(e=f.length;e--;)g=f[e].split(":",2),d[g[0].replace(/(^\s*)|(\s*$)/g,"")]=h(g[1].replace(/(^\s*)|(\s*$)/g,""))}else d=h(d);this.tagValCache.key=d}return d},get:function(a,c){var d=this.getTagSetting(a),e;return d!==b?d:(e=this.mergedOptions[a])===undefined?c:e}}),a.fn.sparkline._base=d({disabled:!1,init:function(b,c,d,e,f){this.el=b,this.$el=a(b),this.values=c,this.options=d,this.width=e,this.height=f,this.currentRegion=undefined},initTarget:function(){var a=!this.options.get("disableInteraction");(this.target=this.$el.simpledraw(this.width,this.height,this.options.get("composite"),a))?(this.canvasWidth=this.target.pixelWidth,this.canvasHeight=this.target.pixelHe ight):this.disabled=!0},render:function(){return this.disabled?(this.el.innerHTML="",!1):!0},getRegion:function(a,b){},setRegionHighlight:function(a,b,c){var d=this.currentRegion,e=!this.options.get("disableHighlight"),f;return b>this.canvasWidth||c>this.canvasHeight||b<0||c<0?null:(f=this.getRegion(a,b,c),d!==f?(d!==undefined&&e&&this.removeHighlight(),this.currentRegion=f,f!==undefined&&e&&this.renderHighlight(),!0):!1)},clearRegionHighlight:function(){return this.currentRegion!==undefined?(this.removeHighlight(),this.currentRegion=undefined,!0):!1},renderHighlight:function(){this.changeHighlight(!0)},removeHighlight:function(){this.changeHighlight(!1)},changeHighlight:function(a){},getCurrentRegionTooltip:function(){var b=this.options,c="",d=[],f,g,h,i,j,k,l,m,n,o,p,q,r,s;if(this.currentRegion===undefined)return"";f=this.getCurrentRegionFields(),p=b.get("tooltipFormatter");if(p)return p(this,b,f);b.get("tooltipChartTitle")&&(c+='<div class="jqs jqstitle">'+b.get("tooltipC hartTitle")+"</div>\n"),g=this.options.get("tooltipFormat");if(!g)return"";a.isArray(g)||(g=[g]),a.isArray(f)||(f=[f]),l=this.options.get("tooltipFormatFieldlist"),m=this.options.get("tooltipFormatFieldlistKey");if(l&&m){n=[];for(k=f.length;k--;)o=f[k][m],(s=a.inArray(o,l))!=-1&&(n[s]=f[k]);f=n}h=g.length,r=f.length;for(k=0;k<h;k++){q=g[k],typeof q=="string"&&(q=new e(q)),i=q.fclass||"jqsfield";for(s=0;s<r;s++)if(!f[s].isNull||!b.get("tooltipSkipNull"))a.extend(f[s],{prefix:b.get("tooltipPrefix"),suffix:b.get("tooltipSuffix")}),j=q.render(f[s],b.get("tooltipValueLookups"),b),d.push('<div class="'+i+'">'+j+"</div>")}return d.length?c+d.join("\n"):""},getCurrentRegionFields:function(){},calcHighlightColor:function(a,b){var c=b.get("highlightColor"),d=b.get("highlightLighten"),e,g,h,i;if(c)return c;if(d){e=/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(a)||/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(a);if(e){h=[],g=a.length===4?16:1;for(i=0;i<3;i++)h[i]=f(Math.round(parseInt( e[i+1],16)*g*d),0,255);return"rgb("+h.join(",")+")"}}return a}}),t={changeHighlight:function(b){var c=this.currentRegion,d=this.target,e=this.regionShapes[c],f;e&&(f=this.renderRegion(c,b),a.isArray(f)||a.isArray(e)?(d.replaceWithShapes(e,f),this.regionShapes[c]=a.map(f,function(a){return a.id})):(d.replaceWithShape(e,f),this.regionShapes[c]=f.id))},render:function(){var b=this.values,c=this.target,d=this.regionShapes,e,f,g,h;if(!this.cls._super.render.call(this))return;for(g=b.length;g--;){e=this.renderRegion(g);if(e)if(a.isArray(e)){f=[];for(h=e.length;h--;)e[h].append(),f.push(e[h].id);d[g]=f}else e.append(),d[g]=e.id;else d[g]=null}c.render()}},a.fn.sparkline.line=u=d(a.fn.sparkline._base,{type:"line",init:function(a,b,c,d,e){u._super.init.call(this,a,b,c,d,e),this.vertices=[],this.regionMap=[],this.xvalues=[],this.yvalues=[],this.yminmax=[],this.hightlightSpotId=null,this.lastShapeId=null,this.initTarget()},getRegion:function(a,b,c){var d,e=this.regionMap;for(d=e.length ;d--;)if(e[d]!==null&&b>=e[d][0]&&b<=e[d][1])return e[d][2];return undefined},getCurrentRegionFields:function(){var a=this.currentRegion;return{isNull:this.yvalues[a]===null,x:this.xvalues[a],y:this.yvalues[a],color:this.options.get("lineColor"),fillColor:this.options.get("fillColor"),offset:a}},renderHighlight:function(){var a=this.currentRegion,b=this.target,c=this.vertices[a],d=this.options,e=d.get("spotRadius"),f=d.get("highlightSpotColor"),g=d.get("highlightLineColor"),h,i;if(!c)return;e&&f&&(h=b.drawCircle(c[0],c[1],e,undefined,f),this.highlightSpotId=h.id,b.insertAfterShape(this.lastShapeId,h)),g&&(i=b.drawLine(c[0],this.canvasTop,c[0],this.canvasTop+this.canvasHeight,g),this.highlightLineId=i.id,b.insertAfterShape(this.lastShapeId,i))},removeHighlight:function(){var a=this.target;this.highlightSpotId&&(a.removeShapeId(this.highlightSpotId),this.highlightSpotId=null),this.highlightLineId&&(a.removeShapeId(this.highlightLineId),this.highlightLineId=null)},scanValues:fu nction(){var a=this.values,b=a.length,c=this.xvalues,d=this.yvalues,e=this.yminmax,f,g,h,i,j;for(f=0;f<b;f++)g=a[f],h=typeof a[f]=="string",i=typeof a[f]=="object"&&a[f]instanceof Array,j=h&&a[f].split(":"),h&&j.length===2?(c.push(Number(j[0])),d.push(Number(j[1])),e.push(Number(j[1]))):i?(c.push(g[0]),d.push(g[1]),e.push(g[1])):(c.push(f),a[f]===null||a[f]==="null"?d.push(null):(d.push(Number(g)),e.push(Number(g))));this.options.get("xvalues")&&(c=this.options.get("xvalues")),this.maxy=this.maxyorg=Math.max.apply(Math,e),this.miny=this.minyorg=Math.min.apply(Math,e),this.maxx=Math.max.apply(Math,c),this.minx=Math.min.apply(Math,c),this.xvalues=c,this.yvalues=d,this.yminmax=e},processRangeOptions:function(){var a=this.options,b=a.get("normalRangeMin"),c=a.get("normalRangeMax");b!==undefined&&(b<this.miny&&(this.miny=b),c>this.maxy&&(this.maxy=c)),a.get("chartRangeMin")!==undefined&&(a.get("chartRangeClip")||a.get("chartRangeMin")<this.miny)&&(this.miny=a.get("chartRangeMin") ),a.get("chartRangeMax")!==undefined&&(a.get("chartRangeClip")||a.get("chartRangeMax")>this.maxy)&&(this.maxy=a.get("chartRangeMax")),a.get("chartRangeMinX")!==undefined&&(a.get("chartRangeClipX")||a.get("chartRangeMinX")<this.minx)&&(this.minx=a.get("chartRangeMinX")),a.get("chartRangeMaxX")!==undefined&&(a.get("chartRangeClipX")||a.get("chartRangeMaxX")>this.maxx)&&(this.maxx=a.get("chartRangeMaxX"))},drawNormalRange:function(a,b,c,d,e){var f=this.options.get("normalRangeMin"),g=this.options.get("normalRangeMax"),h=b+Math.round(c-c*((g-this.miny)/e)),i=Math.round(c*(g-f)/e);this.target.drawRect(a,h,d,i,undefined,this.options.get("normalRangeColor")).append()},render:function(){var b=this.options,c=this.target,d=this.canvasWidth,e=this.canvasHeight,f=this.vertices,g=b.get("spotRadius"),h=this.regionMap,i,j,k,l,m,n,o,p,r,s,t,v,w,x,y,z,A,B,C,D,E,F,G,H;if(!u._super.render.call(this))return;this.scanValues(),this.processRangeOptions(),F=this.xvalues,G=this.yvalues;if(!this.ymin max.length||this.yvalues.length<2)return;l=m=0,i=this.maxx-this.minx===0?1:this.maxx-this.minx,j=this.maxy-this.miny===0?1:this.maxy-this.miny,k=this.yvalues.length-1,g&&(d<g*4||e<g*4)&&(g=0);if(g){if(b.get("minSpotColor")||b.get("spotColor")&&G[k]===this.miny)e-=Math.ceil(g);if(b.get("maxSpotColor")||b.get("spotColor")&&G[k]===this.maxy)e-=Math.ceil(g),l+=Math.ceil(g);(b.get("minSpotColor")||b.get("maxSpotColor"))&&(G[0]===this.miny||G[0]===this.maxy)&&(m+=Math.ceil(g),d-=Math.ceil(g));if(b.get("spotColor")||b.get("minSpotColor")||b.get("maxSpotColor")&&(G[k]===this.miny||G[k]===this.maxy))d-=Math.ceil(g)}e--,b.get("normalRangeMin")&&!b.get("drawNormalOnTop")&&this.drawNormalRange(m,l,e,d,j),o=[],p=[o],x=y=null,z=G.length;for(H=0;H<z;H++)r=F[H],t=F[H+1],s=G[H],v=m+Math.round((r-this.minx)*(d/i)),w=H<z-1?m+Math.round((t-this.minx)*(d/i)):d,y=v+(w-v)/2,h[H]=[x||0,y,H],x=y,s===null?H&&G[H-1]!==null&&(o=[],p.push(o),f.push(null)):(s<this.miny&&(s=this.miny),s>this.maxy&&(s=this .maxy),o.length||o.push([v,l+e]),n=[v,l+Math.round(e-e*((s-this.miny)/j))],o.push(n),f.push(n));A=[],B=[],C=p.length;for(H=0;H<C;H++)o=p[H],o.length&&(b.get("fillColor")&&(o.push([o[o.length-1][0],l+e]),B.push(o.slice(0)),o.pop()),o.length>2&&(o[0]=[o[0][0],o[1][1]]),A.push(o));C=B.length;for(H=0;H<C;H++)c.drawShape(B[H],b.get("fillColor"),b.get("fillColor")).append();b.get("normalRangeMin")&&b.get("drawNormalOnTop")&&this.drawNormalRange(m,l,e,d,j),C=A.length;for(H=0;H<C;H++)c.drawShape(A[H],b.get("lineColor"),undefined,b.get("lineWidth")).append();if(g&&b.get("valueSpots")){D=b.get("valueSpots"),D.get===undefined&&(D=new q(D));for(H=0;H<z;H++)E=D.get(G[H]),E&&c.drawCircle(m+Math.round((F[H]-this.minx)*(d/i)),l+Math.round(e-e*((G[H]-this.miny)/j)),g,undefined,E).append()}g&&b.get("spotColor")&&c.drawCircle(m+Math.round((F[F.length-1]-this.minx)*(d/i)),l+Math.round(e-e*((G[k]-this.miny)/j)),g,undefined,b.get("spotColor")).append(),this.maxy!==this.minyorg&&(g&&b.get("minSpot Color")&&(r=F[a.inArray(this.minyorg,G)],c.drawCircle(m+Math.round((r-this.minx)*(d/i)),l+Math.round(e-e*((this.minyorg-this.miny)/j)),g,undefined,b.get("minSpotColor")).append()),g&&b.get("maxSpotColor")&&(r=F[a.inArray(this.maxyorg,G)],c.drawCircle(m+Math.round((r-this.minx)*(d/i)),l+Math.round(e-e*((this.maxyorg-this.miny)/j)),g,undefined,b.get("maxSpotColor")).append())),this.lastShapeId=c.getLastShapeId(),this.canvasTop=l,c.render()}}),a.fn.sparkline.bar=v=d(a.fn.sparkline._base,t,{type:"bar",init:function(b,c,d,e,g){var k=parseInt(d.get("barWidth"),10),l=parseInt(d.get("barSpacing"),10),m=d.get("chartRangeMin"),n=d.get("chartRangeMax"),o=d.get("chartRangeClip"),p=Infinity,r=-Infinity,s,t,u,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P;v._super.init.call(this,b,c,d,e,g);for(y=0,z=c.length;y<z;y++){M=c[y],s=typeof M=="string"&&M.indexOf(":")>-1;if(s||a.isArray(M))H=!0,s&&(M=c[y]=i(M.split(":"))),M=j(M,null),t=Math.min.apply(Math,M),u=Math.max.apply(Math,M),t<p&&(p=t),u>r&&(r=u )}this.stacked=H,this.regionShapes={},this.barWidth=k,this.barSpacing=l,this.totalBarWidth=k+l,this.width=e=c.length*k+(c.length-1)*l,this.initTarget(),o&&(F=m===undefined?-Infinity:m,G=n===undefined?Infinity:n),x=[],w=H?[]:x;var Q=[],R=[];for(y=0,z=c.length;y<z;y++)if(H){I=c[y],c[y]=L=[],Q[y]=0,w[y]=R[y]=0;for(J=0,K=I.length;J<K;J++)M=L[J]=o?f(I[J],F,G):I[J],M!==null&&(M>0&&(Q[y]+=M),p<0&&r>0?M<0?R[y]+=Math.abs(M):w[y]+=M:w[y]+=Math.abs(M-(M<0?r:p)),x.push(M))}else M=o?f(c[y],F,G):c[y],M=c[y]=h(M),M!==null&&x.push(M);this.max=E=Math.max.apply(Math,x),this.min=D=Math.min.apply(Math,x),this.stackMax=r=H?Math.max.apply(Math,Q):E,this.stackMin=p=H?Math.min.apply(Math,x):D,d.get("chartRangeMin")!==undefined&&(d.get("chartRangeClip")||d.get("chartRangeMin")<D)&&(D=d.get("chartRangeMin")),d.get("chartRangeMax")!==undefined&&(d.get("chartRangeClip")||d.get("chartRangeMax")>E)&&(E=d.get("chartRangeMax")),this.zeroAxis=B=d.get("zeroAxis",!0),D<=0&&E>=0&&B?C=0:B==0?C=D:D>0?C=D:C=E,thi s.xaxisOffset=C,A=H?Math.max.apply(Math,w)+Math.max.apply(Math,R):E-D,this.canvasHeightEf=B&&D<0?this.canvasHeight-2:this.canvasHeight-1,D<C?(O=H&&E>=0?r:E,N=(O-C)/A*this.canvasHeight,N!==Math.ceil(N)&&(this.canvasHeightEf-=2,N=Math.ceil(N))):N=this.canvasHeight,this.yoffset=N,a.isArray(d.get("colorMap"))?(this.colorMapByIndex=d.get("colorMap"),this.colorMapByValue=null):(this.colorMapByIndex=null,this.colorMapByValue=d.get("colorMap"),this.colorMapByValue&&this.colorMapByValue.get===undefined&&(this.colorMapByValue=new q(this.colorMapByValue))),this.range=A},getRegion:function(a,b,c){var d=Math.floor(b/this.totalBarWidth);return d<0||d>=this.values.length?undefined:d},getCurrentRegionFields:function(){var a=this.currentRegion,b=o(this.values[a]),c=[],d,e;for(e=b.length;e--;)d=b[e],c.push({isNull:d===null,value:d,color:this.calcColor(e,d,a),offset:a});return c},calcColor:function(b,c,d){var e=this.colorMapByIndex,f=this.colorMapByValue,g=this.options,h,i;return this.stacked? h=g.get("stackedBarColor"):h=c<0?g.get("negBarColor"):g.get("barColor"),c===0&&g.get("zeroColor")!==undefined&&(h=g.get("zeroColor")),f&&(i=f.get(c))?h=i:e&&e.length>d&&(h=e[d]),a.isArray(h)?h[b%h.length]:h},renderRegion:function(b,c){var d=this.values[b],e=this.options,f=this.xaxisOffset,g=[],h=this.range,i=this.stacked,j=this.target,k=b*this.totalBarWidth,m=this.canvasHeightEf,n=this.yoffset,o,p,q,r,s,t,u,v,w,x;d=a.isArray(d)?d:[d],u=d.length,v=d[0],r=l(null,d),x=l(f,d,!0);if(r)return e.get("nullColor")?(q=c?e.get("nullColor"):this.calcHighlightColor(e.get("nullColor"),e),o=n>0?n-1:n,j.drawRect(k,o,this.barWidth-1,0,q,q)):undefined;s=n;for(t=0;t<u;t++){v=d[t];if(i&&v===f){if(!x||w)continue;w=!0}h>0?p=Math.floor(m*(Math.abs(v-f)/h))+1:p=1,v<f||v===f&&n===0?(o=s,s+=p):(o=n-p,n-=p),q=this.calcColor(t,v,b),c&&(q=this.calcHighlightColor(q,e)),g.push(j.drawRect(k,o,this.barWidth-1,p-1,q,q))}return g.length===1?g[0]:g}}),a.fn.sparkline.tristate=w=d(a.fn.sparkline._base,t,{type:"t ristate",init:function(b,c,d,e,f){var g=parseInt(d.get("barWidth"),10),h=parseInt(d.get("barSpacing"),10);w._super.init.call(this,b,c,d,e,f),this.regionShapes={},this.barWidth=g,this.barSpacing=h,this.totalBarWidth=g+h,this.values=a.map(c,Number),this.width=e=c.length*g+(c.length-1)*h,a.isArray(d.get("colorMap"))?(this.colorMapByIndex=d.get("colorMap"),this.colorMapByValue=null):(this.colorMapByIndex=null,this.colorMapByValue=d.get("colorMap"),this.colorMapByValue&&this.colorMapByValue.get===undefined&&(this.colorMapByValue=new q(this.colorMapByValue))),this.initTarget()},getRegion:function(a,b,c){return Math.floor(b/this.totalBarWidth)},getCurrentRegionFields:function(){var a=this.currentRegion;return{isNull:this.values[a]===undefined,value:this.values[a],color:this.calcColor(this.values[a],a),offset:a}},calcColor:function(a,b){var c=this.values,d=this.options,e=this.colorMapByIndex,f=this.colorMapByValue,g,h;return f&&(h=f.get(a))?g=h:e&&e.length>b?g=e[b]:c[b]<0?g=d.get("n egBarColor"):c[b]>0?g=d.get("posBarColor"):g=d.get("zeroBarColor"),g},renderRegion:function(a,b){var c=this.values,d=this.options,e=this.target,f,g,h,i,j,k;f=e.pixelHeight,h=Math.round(f/2),i=a*this.totalBarWidth,c[a]<0?(j=h,g=h-1):c[a]>0?(j=0,g=h-1):(j=h-1,g=2),k=this.calcColor(c[a],a);if(k===null)return;return b&&(k=this.calcHighlightColor(k,d)),e.drawRect(i,j,this.barWidth-1,g-1,k,k)}}),a.fn.sparkline.discrete=x=d(a.fn.sparkline._base,t,{type:"discrete",init:function(b,c,d,e,f){x._super.init.call(this,b,c,d,e,f),this.regionShapes={},this.values=c=a.map(c,Number),this.min=Math.min.apply(Math,c),this.max=Math.max.apply(Math,c),this.range=this.max-this.min,this.width=e=d.get("width")==="auto"?c.length*2:this.width,this.interval=Math.floor(e/c.length),this.itemWidth=e/c.length,d.get("chartRangeMin")!==undefined&&(d.get("chartRangeClip")||d.get("chartRangeMin")<this.min)&&(this.min=d.get("chartRangeMin")),d.get("chartRangeMax")!==undefined&&(d.get("chartRangeClip")||d.get("cha rtRangeMax")>this.max)&&(this.max=d.get("chartRangeMax")),this.initTarget(),this.target&&(this.lineHeight=d.get("lineHeight")==="auto"?Math.round(this.canvasHeight*.3):d.get("lineHeight"))},getRegion:function(a,b,c){return Math.floor(b/this.itemWidth)},getCurrentRegionFields:function(){var a=this.currentRegion;return{isNull:this.values[a]===undefined,value:this.values[a],offset:a}},renderRegion:function(a,b){var c=this.values,d=this.options,e=this.min,g=this.max,h=this.range,i=this.interval,j=this.target,k=this.canvasHeight,l=this.lineHeight,m=k-l,n,o,p,q;return o=f(c[a],e,g),q=a*i,n=Math.round(m-m*((o-e)/h)),p=d.get("thresholdColor")&&o<d.get("thresholdValue")?d.get("thresholdColor"):d.get("lineColor"),b&&(p=this.calcHighlightColor(p,d)),j.drawLine(q,n,q,n+l,p)}}),a.fn.sparkline.bullet=y=d(a.fn.sparkline._base,{type:"bullet",init:function(b,c,d,e,f){var g,h;y._super.init.call(this,b,c,d,e,f),c=a.map(c,Number),g=Math.min.apply(Math,c),h=Math.max.apply(Math,c),d.get("base")== =undefined?g=g<0?g:0:g=d.get("base"),this.min=g,this.max=h,this.range=h-g,this.shapes={},this.valueShapes={},this.regiondata={},this.width=e=d.get("width")==="auto"?"4.0em":e,this.target=this.$el.simpledraw(e,f,d.get("composite")),c.length||(this.disabled=!0),this.initTarget()},getRegion:function(a,b,c){var d=this.target.getShapeAt(a,b,c);return d!==undefined&&this.shapes[d]!==undefined?this.shapes[d]:undefined},getCurrentRegionFields:function(){var a=this.currentRegion;return{fieldkey:a.substr(0,1),value:this.values[a.substr(1)],region:a}},changeHighlight:function(a){var b=this.currentRegion,c=this.valueShapes[b],d;delete this.shapes[c];switch(b.substr(0,1)){case"r":d=this.renderRange(b.substr(1),a);break;case"p":d=this.renderPerformance(a);break;case"t":d=this.renderTarget(a)}this.valueShapes[b]=d.id,this.shapes[d.id]=b,this.target.replaceWithShape(c,d)},renderRange:function(a,b){var c=this.values[a],d=Math.round(this.canvasWidth*((c-this.min)/this.range)),e=this.options.g et("rangeColors")[a-2];return b&&(e=this.calcHighlightColor(e,this.options)),this.target.drawRect(0,0,d-1,this.canvasHeight-1,e,e)},renderPerformance:function(a){var b=this.values[1],c=Math.round(this.canvasWidth*((b-this.min)/this.range)),d=this.options.get("performanceColor");return a&&(d=this.calcHighlightColor(d,this.options)),this.target.drawRect(0,Math.round(this.canvasHeight*.3),c-1,Math.round(this.canvasHeight*.4)-1,d,d)},renderTarget:function(a){var b=this.values[0],c=Math.round(this.canvasWidth*((b-this.min)/this.range)-this.options.get("targetWidth")/2),d=Math.round(this.canvasHeight*.1),e=this.canvasHeight-d*2,f=this.options.get("targetColor");return a&&(f=this.calcHighlightColor(f,this.options)),this.target.drawRect(c,d,this.options.get("targetWidth")-1,e-1,f,f)},render:function(){var a=this.values.length,b=this.target,c,d;if(!y._super.render.call(this))return;for(c=2;c<a;c++)d=this.renderRange(c).append(),this.shapes[d.id]="r"+c,this.valueShapes["r"+c]=d.id;d=t his.renderPerformance().append(),this.shapes[d.id]="p1",this.valueShapes.p1=d.id,d=this.renderTarget().append(),this.shapes[d.id]="t0",this.valueShapes.t0=d.id,b.render()}}),a.fn.sparkline.pie=z=d(a.fn.sparkline._base,{type:"pie",init:function(b,c,d,e,f){var g=0,h;z._super.init.call(this,b,c,d,e,f),this.shapes={},this.valueShapes={},this.values=c=a.map(c,Number),d.get("width")==="auto"&&(this.width=this.height);if(c.length>0)for(h=c.length;h--;)g+=c[h];this.total=g,this.initTarget(),this.radius=Math.floor(Math.min(this.canvasWidth,this.canvasHeight)/2)},getRegion:function(a,b,c){var d=this.target.getShapeAt(a,b,c);return d!==undefined&&this.shapes[d]!==undefined?this.shapes[d]:undefined},getCurrentRegionFields:function(){var a=this.currentRegion;return{isNull:this.values[a]===undefined,value:this.values[a],percent:this.values[a]/this.total*100,color:this.options.get("sliceColors")[a%this.options.get("sliceColors").length],offset:a}},changeHighlight:function(a){var b=this.cur rentRegion,c=this.renderSlice(b,a),d=this.valueShapes[b];delete this.shapes[d],this.target.replaceWithShape(d,c),this.valueShapes[b]=c.id,this.shapes[c.id]=b},renderSlice:function(a,b){var c=this.target,d=this.options,e=this.radius,f=d.get("borderWidth"),g=d.get("offset"),h=2*Math.PI,i=this.values,j=this.total,k=g?2*Math.PI*(g/360):0,l,m,n,o,p;o=i.length;for(n=0;n<o;n++){l=k,m=k,j>0&&(m=k+h*(i[n]/j));if(a===n)return p=d.get("sliceColors")[n%d.get("sliceColors").length],b&&(p=this.calcHighlightColor(p,d)),c.drawPieSlice(e,e,e-f,l,m,undefined,p);k=m}},render:function(){var a=this.target,b=this.values,c=this.options,d=this.radius,e=c.get("borderWidth"),f,g;if(!z._super.render.call(this))return;e&&a.drawCircle(d,d,Math.floor(d-e/2),c.get("borderColor"),undefined,e).append();for(g=b.length;g--;)f=this.renderSlice(g).append(),this.valueShapes[g]=f.id,this.shapes[f.id]=g;a.render()}}),a.fn.sparkline.box=A=d(a.fn.sparkline._base,{type:"box",init:function(b,c,d,e,f){A._super.init.cal l(this,b,c,d,e,f),this.values=a.map(c,Number),this.width=d.get("width")==="auto"?"4.0em":e,this.initTarget(),this.values.length||(this +.disabled=1)},getRegion:function(){return 1},getCurrentRegionFields:function(){var a=[{field:"lq",value:this.quartiles[0]},{field:"med",value:this.quartiles[1]},{field:"uq",value:this.quartiles[2]},{field:"lo",value:this.loutlier},{field:"ro",value:this.routlier}];return this.lwhisker!==undefined&&a.push({field:"lw",value:this.lwhisker}),this.rwhisker!==undefined&&a.push({field:"rw",value:this.rwhisker}),a},render:function(){var a=this.target,b=this.values,c=b.length,d=this.options,e=this.canvasWidth,f=this.canvasHeight,h=d.get("chartRangeMin")===undefined?Math.min.apply(Math,b):d.get("chartRangeMin"),i=d.get("chartRangeMax")===undefined?Math.max.apply(Math,b):d.get("chartRangeMax"),j=0,k,l,m,n,o,p,q,r,s,t,u;if(!A._super.render.call(this))return;if(d.get("raw"))d.get("showOutliers")&&b.length>5?(l=b[0],k=b[1],n=b[2],o=b[3],p=b[4],q=b[5],r=b[6]):(k=b[0],n=b[1],o=b[2],p=b[3],q=b[4]);else{b.sort(function(a,b){return a-b}),n=g(b,1),o=g(b,2),p=g(b,3),m=p-n;if(d.get("showOutliers" )){k=q=undefined;for(s=0;s<c;s++)k===undefined&&b[s]>n-m*d.get("outlierIQR")&&(k=b[s]),b[s]<p+m*d.get("outlierIQR")&&(q=b[s]);l=b[0],r=b[c-1]}else k=b[0],q=b[c-1]}this.quartiles=[n,o,p],this.lwhisker=k,this.rwhisker=q,this.loutlier=l,this.routlier=r,u=e/(i-h+1),d.get("showOutliers")&&(j=Math.ceil(d.get("spotRadius")),e-=2*Math.ceil(d.get("spotRadius")),u=e/(i-h+1),l<k&&a.drawCircle((l-h)*u+j,f/2,d.get("spotRadius"),d.get("outlierLineColor"),d.get("outlierFillColor")).append(),r>q&&a.drawCircle((r-h)*u+j,f/2,d.get("spotRadius"),d.get("outlierLineColor"),d.get("outlierFillColor")).append()),a.drawRect(Math.round((n-h)*u+j),Math.round(f*.1),Math.round((p-n)*u),Math.round(f*.8),d.get("boxLineColor"),d.get("boxFillColor")).append(),a.drawLine(Math.round((k-h)*u+j),Math.round(f/2),Math.round((n-h)*u+j),Math.round(f/2),d.get("lineColor")).append(),a.drawLine(Math.round((k-h)*u+j),Math.round(f/4),Math.round((k-h)*u+j),Math.round(f-f/4),d.get("whiskerColor")).append(),a.drawLine(Math .round((q-h)*u+j),Math.round(f/2),Math.round((p-h)*u+j),Math.round(f/2),d.get("lineColor")).append(),a.drawLine(Math.round((q-h)*u+j),Math.round(f/4),Math.round((q-h)*u+j),Math.round(f-f/4),d.get("whiskerColor")).append(),a.drawLine(Math.round((o-h)*u+j),Math.round(f*.1),Math.round((o-h)*u+j),Math.round(f*.9),d.get("medianColor")).append(),d.get("target")&&(t=Math.ceil(d.get("spotRadius")),a.drawLine(Math.round((d.get("target")-h)*u+j),Math.round(f/2-t),Math.round((d.get("target")-h)*u+j),Math.round(f/2+t),d.get("targetColor")).append(),a.drawLine(Math.round((d.get("target")-h)*u+j-t),Math.round(f/2),Math.round((d.get("target")-h)*u+j+t),Math.round(f/2),d.get("targetColor")).append()),a.render()}}),a.browser.msie&&!document.namespaces.v&&document.namespaces.add("v","urn:schemas-microsoft-com:vml","#default#VML"),a.browser.hasCanvas===undefined&&(a.browser.hasCanvas=document.createElement("canvas").getContext!==undefined),D=d({init:function(a,b,c,d){this.target=a,this.id=b,th is.type=c,this.args=d},append:function(){return this.target.appendShape(this),this}}),E=d({_pxregex:/(\d+)(px)?\s*$/i,init:function(b,c,d){if(!b)return;this.width=b,this.height=c,this.target=d,this.lastShapeId=null,d[0]&&(d=d[0]),a.data(d,"_jqs_vcanvas",this)},drawLine:function(a,b,c,d,e,f){return this.drawShape([[a,b],[c,d]],e,f)},drawShape:function(a,b,c,d){return this._genShape("Shape",[a,b,c,d])},drawCircle:function(a,b,c,d,e,f){return this._genShape("Circle",[a,b,c,d,e,f])},drawPieSlice:function(a,b,c,d,e,f,g){return this._genShape("PieSlice",[a,b,c,d,e,f,g])},drawRect:function(a,b,c,d,e,f){return this._genShape("Rect",[a,b,c,d,e,f])},getElement:function(){return this.canvas},getLastShapeId:function(){return this.lastShapeId},reset:function(){alert("reset not implemented")},_insert:function(b,c){a(c).html(b)},_calculatePixelDims:function(b,c,d){var e;e=this._pxregex.exec(c),e?this.pixelHeight=e[1]:this.pixelHeight=a(d).height(),e=this._pxregex.exec(b),e?this.pixelWidth= e[1]:this.pixelWidth=a(d).width()},_genShape:function(a,b){var c=I++;return b.unshift(c),new D(this,c,a,b)},appendShape:function(a){alert("appendShape not implemented")},replaceWithShape:function(a,b){alert("replaceWithShape not implemented")},insertAfterShape:function(a,b){alert("insertAfterShape not implemented")},removeShapeId:function(a){alert("removeShapeId not implemented")},getShapeAt:function(a,b,c){alert("getShapeAt not implemented")},render:function(){alert("render not implemented")}}),F=d(E,{init:function(b,c,d,e){F._super.init.call(this,b,c,d),this.canvas=document.createElement("canvas"),d[0]&&(d=d[0]),a.data(d,"_jqs_vcanvas",this),a(this.canvas).css({display:"inline-block",width:b,height:c,verticalAlign:"top"}),this._insert(this.canvas,d),this._calculatePixelDims(b,c,this.canvas),this.canvas.width=this.pixelWidth,this.canvas.height=this.pixelHeight,this.interact=e,this.shapes={},this.shapeseq=[],this.currentTargetShapeId=undefined,a(this.canvas).css({width:this. pixelWidth,height:this.pixelHeight})},_getContext:function(a,b,c){var d=this.canvas.getContext("2d");return a!==undefined&&(d.strokeStyle=a),d.lineWidth=c===undefined?1:c,b!==undefined&&(d.fillStyle=b),d},reset:function(){var a=this._getContext();a.clearRect(0,0,this.pixelWidth,this.pixelHeight),this.shapes={},this.shapeseq=[],this.currentTargetShapeId=undefined},_drawShape:function(a,b,c,d,e){var f=this._getContext(c,d,e),g,h;f.beginPath(),f.moveTo(b[0][0]+.5,b[0][1]+.5);for(g=1,h=b.length;g<h;g++)f.lineTo(b[g][0]+.5,b[g][1]+.5);c!==undefined&&f.stroke(),d!==undefined&&f.fill(),this.targetX!==undefined&&this.targetY!==undefined&&f.isPointInPath(this.targetX,this.targetY)&&(this.currentTargetShapeId=a)},_drawCircle:function(a,b,c,d,e,f,g){var h=this._getContext(e,f,g);h.beginPath(),h.arc(b,c,d,0,2*Math.PI,!1),this.targetX!==undefined&&this.targetY!==undefined&&h.isPointInPath(this.targetX,this.targetY)&&(this.currentTargetShapeId=a),e!==undefined&&h.stroke(),f!==undefined&&h .fill()},_drawPieSlice:function(a,b,c,d,e,f,g,h){var i=this._getContext(g,h);i.beginPath(),i.moveTo(b,c),i.arc(b,c,d,e,f,!1),i.lineTo(b,c),i.closePath(),g!==undefined&&i.stroke(),h&&i.fill(),this.targetX!==undefined&&this.targetY!==undefined&&i.isPointInPath(this.targetX,this.targetY)&&(this.currentTargetShapeId=a)},_drawRect:function(a,b,c,d,e,f,g){return this._drawShape(a,[[b,c],[b+d,c],[b+d,c+e],[b,c+e],[b,c]],f,g)},appendShape:function(a){return this.shapes[a.id]=a,this.shapeseq.push(a.id),this.lastShapeId=a.id,a.id},replaceWithShape:function(a,b){var c=this.shapeseq,d;this.shapes[b.id]=b;for(d=c.length;d--;)c[d]==a&&(c[d]=b.id);delete this.shapes[a]},replaceWithShapes:function(a,b){var c=this.shapeseq,d={},e,f,g;for(f=a.length;f--;)d[a[f]]=!0;for(f=c.length;f--;)e=c[f],d[e]&&(c.splice(f,1),delete this.shapes[e],g=f);for(f=b.length;f--;)c.splice(g,0,b[f].id),this.shapes[b[f].id]=b[f]},insertAfterShape:function(a,b){var c=this.shapeseq,d;for(d=c.length;d--;)if(c[d]===a){c .splice(d+1,0,b.id),this.shapes[b.id]=b;return}},removeShapeId:function(a){var b=this.shapeseq,c;for(c=b.length;c--;)if(b[c]===a){b.splice(c,1);break}delete this.shapes[a]},getShapeAt:function(a,b,c){return this.targetX=b,this.targetY=c,this.render(),this.currentTargetShapeId},render:function(){var a=this.shapeseq,b=this.shapes,c=a.length,d=this._getContext(),e,f,g;d.clearRect(0,0,this.pixelWidth,this.pixelHeight);for(g=0;g<c;g++)e=a[g],f=b[e],this["_draw"+f.type].apply(this,f.args);this.interact||(this.shapes={},this.shapeseq=[])}}),G=d(E,{init:function(b,c,d){var e;G._super.init.call(this,b,c,d),d[0]&&(d=d[0]),a.data(d,"_jqs_vcanvas",this),this.canvas=document.createElement("span"),a(this.canvas).css({display:"inline-block",position:"relative",overflow:"hidden",width:b,height:c,margin:"0px",padding:"0px",verticalAlign:"top"}),this._insert(this.canvas,d),this._calculatePixelDims(b,c,this.canvas),this.canvas.width=this.pixelWidth,this.canvas.height=this.pixelHeight,e='<v:gro up coordorigin="0 0" coordsize="'+this.pixelWidth+" "+this.pixelHeight+'"'+' style="position:absolute;top:0;left:0;width:'+this.pixelWidth+"px;height="+this.pixelHeight+'px;"></v:group>',this.canvas.insertAdjacentHTML("beforeEnd",e),this.group=a(this.canvas).children()[0],this.rendered=!1,this.prerender=""},_drawShape:function(a,b,c,d,e){var f=[],g,h,i,j,k,l,m;for(m=0,l=b.length;m<l;m++)f[m]=""+b[m][0]+","+b[m][1];return g=f.splice(0,1),e=e===undefined?1:e,h=c===undefined?' stroked="false" ':' strokeWeight="'+e+'px" strokeColor="'+c+'" ',i=d===undefined?' filled="false"':' fillColor="'+d+'" filled="true" ',j=f[0]===f[f.length-1]?"x ":"",k='<v:shape coordorigin="0 0" coordsize="'+this.pixelWidth+" "+this.pixelHeight+'" '+' id="jqsshape'+a+'" '+h+i+' style="position:absolute;left:0px;top:0px;height:'+this.pixelHeight+"px;width:"+this.pixelWidth+'px;padding:0px;margin:0px;" '+' path="m '+g+" l "+f.join(", ")+" "+j+'e">'+" </v:shape>",k},_drawCircle:function(a,b,c,d,e,f,g){var h ,i,j;return b-=d,c-=d,h=e===undefined?' stroked="false" ':' strokeWeight="'+g+'px" strokeColor="'+e+'" ',i=f===undefined?' filled="false"':' fillColor="'+f+'" filled="true" ',j='<v:oval id="jqsshape'+a+'" '+h+i+' style="position:absolute;top:'+c+"px; left:"+b+"px; width:"+d*2+"px; height:"+d*2+'px"></v:oval>',j},_drawPieSlice:function(a,b,c,d,e,f,g,h){var i,j,k,l,m,n,o,p;if(e===f)return;f-e===2*Math.PI&&(e=0,f=2*Math.PI),j=b+Math.round(Math.cos(e)*d),k=c+Math.round(Math.sin(e)*d),l=b+Math.round(Math.cos(f)*d),m=c+Math.round(Math.sin(f)*d);if(j===l&&k===m&&f-e<Math.PI)return;return i=[b-d,c-d,b+d,c+d,j,k,l,m],n=g===undefined?' stroked="false" ':' strokeWeight="1px" strokeColor="'+g+'" ',o=h===undefined?' filled="false"':' fillColor="'+h+'" filled="true" ',p='<v:shape coordorigin="0 0" coordsize="'+this.pixelWidth+" "+this.pixelHeight+'" '+' id="jqsshape'+a+'" '+n+o+' style="position:absolute;left:0px;top:0px;height:'+this.pixelHeight+"px;width:"+this.pixelWidth+'px;padding:0 px;margin:0px;" '+' path="m '+b+","+c+" wa "+i.join(", ")+' x e">'+" </v:shape>",p},_drawRect:function(a,b,c,d,e,f,g){return this._drawShape(a,[[b,c],[b,c+e],[b+d,c+e],[b+d,c],[b,c]],f,g)},reset:function(){this.group.innerHTML=""},appendShape:function(a){var b=this["_draw"+a.type].apply(this,a.args);return this.rendered?this.group.insertAdjacentHTML("beforeEnd",b):this.prerender+=b,this.lastShapeId=a.id,a.id},replaceWithShape:function(b,c){var d=a("#jqsshape"+b),e=this["_draw"+c.type].apply(this,c.args);d[0].outerHTML=e},replaceWithShapes:function(b,c){var d=a("#jqsshape"+b[0]),e="",f=c.length,g;for(g=0;g<f;g++)e+=this["_draw"+c[g].type].apply(this,c[g].args);d[0].outerHTML=e;for(g=1;g<b.length;g++)a("#jqsshape"+b[g]).remove()},insertAfterShape:function(b,c){var d=a("#jqsshape"+b),e=this["_draw"+c.type].apply(this,c.args);d[0].insertAdjacentHTML("afterEnd",e)},removeShapeId:function(b){var c=a("#jqsshape"+b);this.group.removeChild(c[0])},getShapeAt:function(a,b,c){var d=a.id .substr(8);return d},render:function(){this.rendered||(this.group.innerHTML=this.prerender,this.rendered=!0)}})})(jQuery); \ No newline at end of file
commit 12250e1e39fa3e4b48ca42c17eb561eff3d4d4bd Author: John Sanda jsanda@redhat.com Date: Wed Aug 15 13:24:37 2012 -0400
[BZ 802796] Provide more details for time outs
This commit add more details to the timeout help message. CreateResourceRunner has also been updated so that it sets the status of the respone to TIMED_OUT. Previously timed out deployments were getting flagged as just a FAILURE. The error message in the response now also contains additional details indicating that the deployment might still succeed and that the user may want to run a discovery scan to see if it did.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java index 7a01b88..b3c65bd 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/CreateResourceRunner.java @@ -22,22 +22,22 @@ */ package org.rhq.core.pc.inventory;
- import org.rhq.core.clientapi.agent.inventory.CreateResourceResponse; - import org.rhq.core.clientapi.server.discovery.InventoryReport; - import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService; - import org.rhq.core.domain.configuration.Configuration; - import org.rhq.core.domain.resource.CreateResourceStatus; - import org.rhq.core.domain.resource.Resource; - import org.rhq.core.pc.PluginContainer; - import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet; - import org.rhq.core.pluginapi.inventory.CreateResourceReport; - import org.rhq.core.util.exception.ThrowableUtil; - - import org.apache.commons.logging.Log; - import org.apache.commons.logging.LogFactory; - import java.util.concurrent.Callable;
+import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.clientapi.agent.inventory.CreateResourceResponse; +import org.rhq.core.clientapi.server.discovery.InventoryReport; +import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService; +import org.rhq.core.domain.configuration.Configuration; +import org.rhq.core.domain.resource.CreateResourceStatus; +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.pc.PluginContainer; +import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet; +import org.rhq.core.pluginapi.inventory.CreateResourceReport; +import org.rhq.core.util.exception.ThrowableUtil; + /** * Runnable implementation to process Resource create requests. * @@ -159,9 +159,15 @@ public class CreateResourceRunner implements Callable, Runnable { // If we still don't have an error message, populate it from the exception errorMessage = (errorMessage != null) ? (errorMessage + " - Cause: " + messages) : messages; } + } catch(TimeoutException e) { + status = CreateResourceStatus.TIMED_OUT; + errorMessage = "The time out has been exceeded; however, the deployment may have been successful. You " + + "may want to run a discovery scan to see if the deployment did complete successfully. Also consider " + + "using a higher time out value for future deployments.\n\nRoot Cause:\n"; + errorMessage += ThrowableUtil.getStackAsString(e); } catch (Throwable t) { - errorMessage = ThrowableUtil.getStackAsString(t); status = CreateResourceStatus.FAILURE; + errorMessage = ThrowableUtil.getStackAsString(t); }
// Send results back to the server diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties index f9b75f3..cfa1f6d 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties @@ -2035,8 +2035,8 @@ widget_resourceFactoryWizard_infoStepName = Resource Information widget_resourceFactoryWizard_infoStep_loadFail = Failed to get available Architectures widget_resourceFactoryWizard_namePrompt = New Resource Name widget_resourceFactoryWizard_templatePrompt = Connection Settings Template -widget_resourceFactoryWizard_timeoutFailure = Timed out. Note that it is possible that the deployment may still succeed. -widget_resourceFactoryWizard_timeoutHelp = A timeout duration. If specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. Useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. +widget_resourceFactoryWizard_timeoutFailure = Timed out +widget_resourceFactoryWizard_timeoutHelp = A timeout duration that if specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. A higher value may be useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. Note that if there is a timeout failure, it is still possible that the resource deployment succeeded. In the event of a timeout you may want to execute a discovery scan before attempting to redeploy the resource. widget_resourceFactoryWizard_uploadFailure = Failed to upload file widget_resourceFactoryWizard_uploadFileStepName = Upload Resource Content File widget_resourceFactoryWizard_uploadInProgress = The upload is in progress... This can take several minutes to complete for large distribution files. diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties index 11c4488..5be0d57 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties @@ -2052,8 +2052,8 @@ widget_resourceFactoryWizard_infoStepName = Informace o zdroji widget_resourceFactoryWizard_infoStep_loadFail = Nepodařilo se získat dostupné architektury widget_resourceFactoryWizard_namePrompt = Nové jméno zdroje widget_resourceFactoryWizard_templatePrompt = Šablona pro nastavení připojení -##widget_resourceFactoryWizard_timeoutFailure = Timed out. Note that it is possible that the deployment may still succeed. -##widget_resourceFactoryWizard_timeoutHelp = A timeout duration. If specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. Useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. +##widget_resourceFactoryWizard_timeoutFailure = Timed out +##widget_resourceFactoryWizard_timeoutHelp = A timeout duration that if specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. A higher value may be useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. Note that if there is a timeout failure, it is still possible that the resource deployment succeeded. In the event of a timeout you may want to execute a discovery scan before attempting to redeploy the resource. widget_resourceFactoryWizard_uploadFailure = Nepodařilo se nahrát soubor widget_resourceFactoryWizard_uploadFileStepName = Nahrát obsah souboru zdroje widget_resourceFactoryWizard_uploadInProgress = Upload právě probíhá... Může to trvat několik minut. diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties index 71d8367..d39f16a 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties @@ -1815,9 +1815,9 @@ widget_resourceFactoryWizard_infoStepName = Information über die Ressource widget_resourceFactoryWizard_infoStep_loadFail = Konnte die verfügbaren Architekturen nicht ermitteln widget_resourceFactoryWizard_namePrompt = Name der neuen Ressource widget_resourceFactoryWizard_templatePrompt = Vorlage für die Verbindungseinstellungen -##widget_resourceFactoryWizard_timeoutHelp = A timeout duration. If specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. Useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. +##widget_resourceFactoryWizard_timeoutHelp = A timeout duration that if specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. A higher value may be useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. Note that if there is a timeout failure, it is still possible that the resource deployment succeeded. In the event of a timeout you may want to execute a discovery scan before attempting to redeploy the resource. widget_resourceFactoryWizard_uploadFailure = Konnte die Datei nicht hochladen -###widget_resourceFactoryWizard_timeoutFailure = Timed out. Note that it is possible that the deployment may still succeed. +###widget_resourceFactoryWizard_timeoutFailure = Timed out ##widget_resourceFactoryWizard_uploadFileStepName = Upload Resource Content File ##widget_resourceFactoryWizard_uploadInProgress = The upload is in progress... This can take several minutes to complete for large distribution files. widget_resourceFactoryWizard_versionPrompt = Paketversion diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties index 33e39c8..6c2044a 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties @@ -2022,8 +2022,8 @@ widget_resourceFactoryWizard_infoStepName = リソース情報 widget_resourceFactoryWizard_infoStep_loadFail = アーキテクチャーを利用可能にするのに失敗しました widget_resourceFactoryWizard_namePrompt = 新規リソース名 widget_resourceFactoryWizard_templatePrompt = コネクション設定テンプレート -###widget_resourceFactoryWizard_timeoutFailure = Timed out. Note that it is possible that the deployment may still succeed. -##widget_resourceFactoryWizard_timeoutHelp = A timeout duration. If specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. Useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. +###widget_resourceFactoryWizard_timeoutFailure = Timed out +##widget_resourceFactoryWizard_timeoutHelp = A timeout duration that if specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. A higher value may be useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. Note that if there is a timeout failure, it is still possible that the resource deployment succeeded. In the event of a timeout you may want to execute a discovery scan before attempting to redeploy the resource. widget_resourceFactoryWizard_uploadFailure = ファイルアップロードの失敗 widget_resourceFactoryWizard_uploadFileStepName = リソースコンテントファイルのアップロード widget_resourceFactoryWizard_uploadInProgress = アップロードは処理中です... 大きなファイルを配布するには数分かかることもあります。 diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties index 2c1af7e..9f00c55 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties @@ -2137,8 +2137,8 @@ widget_resourceFactoryWizard_infoStepName = Informa\u00E7\u00E3o do Recurso widget_resourceFactoryWizard_infoStep_loadFail = Falha ao recuperar Arquiteturas dispon\u00EDveis. widget_resourceFactoryWizard_namePrompt = Novo Nome do Recurso widget_resourceFactoryWizard_templatePrompt = Modelo de Propriedades para Conex\u00E3o -##widget_resourceFactoryWizard_timeoutFailure = Timed out. Note that it is possible that the deployment may still succeed. -##widget_resourceFactoryWizard_timeoutHelp = A timeout duration. If specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. Useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. +##widget_resourceFactoryWizard_timeoutFailure = Timed out +##widget_resourceFactoryWizard_timeoutHelp = A timeout duration that if specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. A higher value may be useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. Note that if there is a timeout failure, it is still possible that the resource deployment succeeded. In the event of a timeout you may want to execute a discovery scan before attempting to redeploy the resource. widget_resourceFactoryWizard_uploadFailure = Falha ao realizar o upload do arquivo widget_resourceFactoryWizard_uploadFileStepName = Upload do Arquivo do Recurso widget_resourceFactoryWizard_uploadInProgress = Upload em andamento... Esse processo pode demorar alguns minutos para ser finalizado em caso de arquivos muito grandes. diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties index 29a3fa6..25671e1 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties @@ -2014,8 +2014,8 @@ #widget_resourceFactoryWizard_infoStep_loadFail = Failed to get available Architectures #widget_resourceFactoryWizard_namePrompt = New Resource Name #widget_resourceFactoryWizard_templatePrompt = Connection Settings Template -#widget_resourceFactoryWizard_timeoutHelp = A timeout duration. If specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. Useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. -#widget_resourceFactoryWizard_timeoutFailure = Timed out. Note that it is possible that the deployment may still succeed. +#widget_resourceFactoryWizard_timeoutHelp = A timeout duration that if specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. A higher value may be useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. Note that if there is a timeout failure, it is still possible that the resource deployment succeeded. In the event of a timeout you may want to execute a discovery scan before attempting to redeploy the resource. +#widget_resourceFactoryWizard_timeoutFailure = Timed out #widget_resourceFactoryWizard_uploadFailure = Failed to upload file #widget_resourceFactoryWizard_uploadFileStepName = Upload Resource Content File #widget_resourceFactoryWizard_uploadInProgress = The upload is in progress... This can take several minutes to complete for large distribution files. diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties index cd7f97f..827e01b 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties @@ -2020,8 +2020,8 @@ widget_resourceFactoryWizard_infoStepName = \u8d44\u6e90\u6d88\u606f widget_resourceFactoryWizard_infoStep_loadFail = \u65e0\u6cd5\u53d6\u5f97\u67b6\u6784 widget_resourceFactoryWizard_namePrompt = \u65b0\u8d44\u6e90\u540d widget_resourceFactoryWizard_templatePrompt = \u8fde\u63a5\u8bbe\u7f6e\u6a21\u677f -#widget_resourceFactoryWizard_timeoutHelp = A timeout duration. If specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. Useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. -#widget_resourceFactoryWizard_timeoutFailure = Timed out. Note that it is possible that the deployment may still succeed. +#widget_resourceFactoryWizard_timeoutHelp = A timeout duration that if specified will override the default timeout for child resource creation (on the {0} Agent). The default timeout is set to 60 seconds. A higher value may be useful for particularly long create actions, like deployment of a large application. Usually used if a previous attempt suffered a timeout failure. Note that if there is a timeout failure, it is still possible that the resource deployment succeeded. In the event of a timeout you may want to execute a discovery scan before attempting to redeploy the resource. +#widget_resourceFactoryWizard_timeoutFailure = Timed out widget_resourceFactoryWizard_uploadFailure = \u4e0a\u4f20\u6587\u4ef6\u5931\u8d25 widget_resourceFactoryWizard_uploadFileStepName = \u4e0a\u4f20\u8d44\u6e90Content\u6587\u4ef6 widget_resourceFactoryWizard_uploadInProgress = \u6b63\u5728\u4e0a\u4f20\u4e2d... \u5927\u7684\u53d1\u5e03\u6587\u4ef6\u9700\u8981\u6d88\u8017\u6570\u5206\u949f\u5b8c\u6210.
commit 7b82e90aa77706ec33c5195e02da0f374e410c86 Author: Jay Shaughnessy jshaughn@redhat.com Date: Wed Aug 15 12:07:13 2012 -0400
Upate this dev plugin to also allow for a delay when reporting metrics. This allows the plugin to be used for "slow" collection reporting when simulating an overloaded agent or misbehaving plugin.
For example, to see debug logging in the agent when metric collection is falling behind try:
1) Update pattern2 collection interval to 40s so that the two pattern metrics are not collected at the same time, thus creating more load. 2) Set the new "delay" plugin config prop to 25. So, each collection will take 25s, and quickly the agent will fall behind.
diff --git a/modules/plugins/pattern-generator/src/main/java/org/rhq/plugins/pattern/PatternComponent.java b/modules/plugins/pattern-generator/src/main/java/org/rhq/plugins/pattern/PatternComponent.java index 5c8d631..18c6036 100644 --- a/modules/plugins/pattern-generator/src/main/java/org/rhq/plugins/pattern/PatternComponent.java +++ b/modules/plugins/pattern-generator/src/main/java/org/rhq/plugins/pattern/PatternComponent.java @@ -1,4 +1,3 @@ - package org.rhq.plugins.pattern;
import java.util.Set; @@ -30,6 +29,8 @@ public class PatternComponent implements ResourceComponent, MeasurementFacet {
int[] wanted = new int[2];
+ long delay = 0L; // in seconds + /** * Return availability of this resource * @see org.rhq.core.pluginapi.inventory.ResourceComponent#getAvailability() @@ -38,7 +39,6 @@ public class PatternComponent implements ResourceComponent, MeasurementFacet { return AvailabilityType.UP; }
- /** * Start the resource connection * @see org.rhq.core.pluginapi.inventory.ResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext) @@ -46,19 +46,23 @@ public class PatternComponent implements ResourceComponent, MeasurementFacet { public void start(ResourceContext context) throws InvalidPluginConfigurationException {
Configuration conf = context.getPluginConfiguration(); - String tmp = conf.getSimpleValue("ones","1"); + String tmp = conf.getSimpleValue("ones", "1"); int wantedOnes = Integer.parseInt(tmp); - if (wantedOnes<1) + if (wantedOnes < 1) throw new InvalidPluginConfigurationException("Ones must be > 0"); - tmp = conf.getSimpleValue("zeros","1"); + tmp = conf.getSimpleValue("zeros", "1"); int wantedZeros = Integer.parseInt(tmp); - if (wantedZeros<1) + if (wantedZeros < 1) throw new InvalidPluginConfigurationException("Zeros must be > 0");
wanted[0] = wantedZeros; wanted[1] = wantedOnes; - }
+ tmp = conf.getSimpleValue("delay", "0"); + delay = Long.parseLong(tmp); + if (delay < 0L) + delay = 0L; + }
/** * Tear down the resource connection @@ -68,19 +72,22 @@ public class PatternComponent implements ResourceComponent, MeasurementFacet { // Nothing to do. }
- /** * Gather "measurement" data - actually a series of 1s and 0s starting with 0. * @see org.rhq.core.pluginapi.measurement.MeasurementFacet#getValues(org.rhq.core.domain.measurement.MeasurementReport, java.util.Set) */ - public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) throws Exception { + public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) throws Exception { + + if (delay > 0L) { + Thread.sleep(delay * 1000L); + }
- boolean flipMetrics = false; - boolean flipTraits = false; - for (MeasurementScheduleRequest request : requests) { - String metricName = request.getName(); + boolean flipMetrics = false; + boolean flipTraits = false; + for (MeasurementScheduleRequest request : requests) { + String metricName = request.getName();
- if (metricName.startsWith("pattern")) { + if (metricName.startsWith("pattern")) {
double value; if (metricName.equals("pattern1")) { @@ -98,15 +105,15 @@ public class PatternComponent implements ResourceComponent, MeasurementFacet {
double value; if (metricName.equals("text1")) { - value = numberForTrait; - flipTraits = true; + value = numberForTrait; + flipTraits = true; } else { - // text2 - value = 1 - numberForTrait; + // text2 + value = 1 - numberForTrait; } String traitValue = (value == 0) ? "red" : "green";
- MeasurementDataTrait datum = new MeasurementDataTrait(request,traitValue); + MeasurementDataTrait datum = new MeasurementDataTrait(request, traitValue); report.addData(datum); } } diff --git a/modules/plugins/pattern-generator/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/pattern-generator/src/main/resources/META-INF/rhq-plugin.xml index 70a8a59..e45ba0f 100644 --- a/modules/plugins/pattern-generator/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/pattern-generator/src/main/resources/META-INF/rhq-plugin.xml @@ -16,6 +16,7 @@ <plugin-configuration> <c:simple-property name="zeros" description="Number of zeros in a row" type="integer" default="1"/> <c:simple-property name="ones" description="Number of ones in a row" type="integer" default="2"/> + <c:simple-property name="delay" description="Number of seconds to delay each metric collection (to test slow reporting)" type="integer" default="0"/> </plugin-configuration>
<metric property="pattern1" displayName="Pattern 1 Metric" defaultInterval="30000" displayType="summary" defaultOn="true"/>
commit c9eb53bb8dab7393d9b5383fbe5bab99088487ed Author: Jay Shaughnessy jshaughn@redhat.com Date: Tue Aug 14 17:13:42 2012 -0400
[Bug 846353 - ORA-02049 during upgrade from JON-3.1.0.GA to JON-3.1.1.ER1 with Oracle] After a lot of investigation it seems that the problem occurs occasionally when we remove obsolete properties from resource configuration. It does not happen every time, on fact it's fairly rare, although for the same DB, and the same plugin update, it is repeatable. This makes it seem like the locking issue is due mainly to unpredictable locking at the db level, and likely the fact that we occasionally hit a page lock due to some other prior update to the config table. Since the config table stores so many different types of data it's not obvious how we would identify the conflict.
The approach taken was to try and reduce possible conflict by increasing the granularity of metadata update transactions. Prior to this change we used a single encompassing transaction for a plugin update, that means all types were updated under one umbrella transaction. Not one transaction, because we already use nested transactions in several places, but using one umbrella transaction increases the chance of that transaction holding a lock that could affect a nested transaction.
We still maintain the umbrella transaction but this commit breaks it up such that a nested transaction is used for the update of each resource type in the plugin.
That means each type update will not hold any locks when it has completed. This change seems to be working as the AS7 plugin now updates successfully.
Additionally: - added some more INFO level logging to give some basic progress during a plugin update. - added some more debug logging as well - removed a bunch of unnecessary em.flush calls - used the return value of some em.merge calls to ensure using the up to date entity.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java index dcc1a0b..b343f79 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/metadata/ConfigurationMetadataManagerBean.java @@ -73,24 +73,27 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa for (PropertyDefinition newProperty : newPropertyDefinitions) { PropertyDefinition existingProp = existingDefinition.get(newProperty.getName()); if (existingProp != null) { + log.debug("Updating nonGrouped property [" + existingProp + "]"); + updatePropertyDefinition(existingProp, newProperty); updateReport.addUpdatedPropertyDefinition(newProperty); } else { + log.debug("Adding nonGrouped property [" + newProperty + "]"); + existingDefinition.put(newProperty); updateReport.addNewPropertyDefinition(newProperty); } }
- // delete outdated properties - removeNoLongerUsedProperties(newDefinition, existingDefinition, existingPropertyDefinitions); + existingDefinition = removeNoLongerUsedProperties(newDefinition, existingDefinition, + existingPropertyDefinitions); + } else { // TODO what if existingDefinitions is null? // we probably don't run in here, as the initial persisting is done // somewhere else. }
- // entityManager.flush(); - /* * Now update / delete contained groups We need to be careful here, as groups are present in PropertyDefinition * as "backlink" from PropertyDefinition to group @@ -108,6 +111,8 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa
// first look for contained stuff for (PropertyDefinition def : groupedDefinitions) { + log.debug("Removing property [" + def + "] from group [" + group + "]"); + existingPropertyDefinitions.remove(def); existingDefinition.getPropertyDefinitions().remove(def.getName()); def.setPropertyGroupDefinition(null); @@ -115,41 +120,44 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa }
// then remove the definition itself + log.debug("Removing group [" + group + "]"); + existingGroups.remove(group); entityManager.remove(group); }
- // entityManager.flush(); - // update existing groups that stay for (PropertyGroupDefinition group : toUpdate) { String groupName = group.getName();
- // System.out.println("Group to update: " + groupName + ", id=" + group.getId()); List<PropertyDefinition> newGroupedDefinitions = newDefinition.getPropertiesInGroup(groupName); for (PropertyDefinition nDef : newGroupedDefinitions) { PropertyDefinition existingProperty = existingDefinition.getPropertyDefinitions().get(nDef.getName()); if (existingProperty != null) { + log.debug("Updating property [" + nDef + "] in group [" + group + "]"); + updatePropertyDefinition(existingProperty, nDef); updateReport.addUpdatedPropertyDefinition(nDef); + } else { + log.debug("Adding property [" + nDef + "] to group [" + group + "]"); + existingDefinition.put(nDef); updateReport.addNewPropertyDefinition(nDef); } }
// delete outdated properties of this group - removeNoLongerUsedProperties(newDefinition, existingDefinition, + existingDefinition = removeNoLongerUsedProperties(newDefinition, existingDefinition, existingDefinition.getPropertiesInGroup(groupName)); }
- // entityManager.flush(); - // persist new groups for (PropertyGroupDefinition group : toPersist) { - /* - * First persist a new group definition and then link the properties to it - */ + + // First persist a new group definition and then link the properties to it + log.debug("Persisting new group [" + group + "]"); + entityManager.persist(group); existingGroups.add(group); // iterating over this does not update the underlying crap
@@ -185,17 +193,22 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa }
for (String name : toRemove) { + log.debug("Removing template [" + name + "]"); + ConfigurationTemplate template = existingTemplates.remove(name); entityManager.remove(template); }
for (String name : templatesToUpdate) { + log.debug("Updating template [" + name + "]"); + updateTemplate(existingDefinition.getTemplate(name), newTemplates.get(name)); }
for (String name : newTemplates.keySet()) { // add completely new templates if (!existingTemplates.containsKey(name)) { + log.debug("Adding template [" + name + "]");
ConfigurationTemplate newTemplate = newTemplates.get(name);
@@ -279,8 +292,9 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa * @param existingConfigDef existing persisted configuration * @param existingProperties list of existing properties to inspect for potential removal */ - private void removeNoLongerUsedProperties(ConfigurationDefinition newConfigDef, + private ConfigurationDefinition removeNoLongerUsedProperties(ConfigurationDefinition newConfigDef, ConfigurationDefinition existingConfigDef, List<PropertyDefinition> existingProperties) { + List<PropertyDefinition> propDefsToDelete = new ArrayList<PropertyDefinition>(); for (PropertyDefinition existingPropDef : existingProperties) { PropertyDefinition newPropDef = newConfigDef.get(existingPropDef.getName()); @@ -296,8 +310,10 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa existingConfigDef.getPropertyDefinitions().remove(propDef.getName()); existingProperties.remove(propDef); // does not operate on original list!! } - entityManager.merge(existingConfigDef); + existingConfigDef = entityManager.merge(existingConfigDef); } + + return existingConfigDef; }
/** @@ -360,7 +376,7 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa } }
- entityManager.merge(existingProperty); + existingProperty = entityManager.merge(existingProperty);
} else { // different type
@@ -412,7 +428,7 @@ public class ConfigurationMetadataManagerBean implements ConfigurationMetadataMa } } } - entityManager.merge(existingPDS); + existingPDS = entityManager.merge(existingPDS);
// handle <constraint> [0..*]
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java index 032deb3..2c8a925 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java @@ -153,7 +153,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal Set<ResourceType> legitimateChildren = new HashSet<ResourceType>(); for (ResourceType resourceType : nonRunsInsideResourceTypes) { long startTime = System.currentTimeMillis(); - updateType(resourceType); + resourceType = resourceMetadataManager.updateType(resourceType); long endTime = System.currentTimeMillis(); log.debug("Updated resource type [" + toConciseString(resourceType) + "] in " + (endTime - startTime) + " ms"); @@ -181,7 +181,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal resourceMetadataManager.getPluginTypes(subject, pluginName, legitTypes, obsoleteTypes, metadataCache);
if (!obsoleteTypes.isEmpty()) { - log.debug("Removing " + obsoleteTypes.size() + " obsolete types: " + obsoleteTypes + "..."); + log.info("Removing " + obsoleteTypes.size() + " obsolete types: " + obsoleteTypes + "..."); removeResourceTypes(subject, obsoleteTypes, new HashSet<ResourceType>(obsoleteTypes)); }
@@ -361,21 +361,19 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal } }
- private void updateType(ResourceType resourceType) { - entityManager.flush(); + @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) + public ResourceType updateType(ResourceType resourceType) {
// see if there is already an existing type that we need to update - if (log.isDebugEnabled()) { - log.debug("Updating resource type [" + resourceType.getName() + "] from plugin [" - + resourceType.getPlugin() + "]..."); - } + log.info("Updating resource type [" + toConciseString(resourceType) + "]...");
ResourceType existingType; try { existingType = resourceTypeManager.getResourceTypeByNameAndPlugin(resourceType.getName(), resourceType.getPlugin()); + } catch (NonUniqueResultException nure) { - log.debug("Found more than one existing ResourceType for " + resourceType); + log.info("Found more than one existing ResourceType for " + resourceType); // TODO: Delete the redundant ResourceTypes to get the DB into a valid state. throw new IllegalStateException(nure); } @@ -390,6 +388,8 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal } else { mergeExistingType(resourceType, existingType); } + + return resourceType; }
private void mergeExistingType(ResourceType resourceType, ResourceType existingType) { @@ -427,7 +427,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal // Update the type itself if (resourceType.getCategory() != existingType.getCategory()) { log.info("Changing category of Resource type [" + resourceType + "] from " + existingType.getCategory() - + " to " + resourceType.getCategory() + "..."); + + " to " + resourceType.getCategory() + "..."); existingType.setCategory(resourceType.getCategory()); }
@@ -447,7 +447,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal // above already took care of any modifications to the ResourceSubCategories themselves). } else if (newSubCat == null) { if (oldSubCat != null) { - log.debug("Metadata update: Subcategory of ResourceType [" + resourceType.getName() + "] changed from " + log.info("Metadata update: Subcategory of ResourceType [" + resourceType.getName() + "] changed from " + oldSubCat + " to " + newSubCat); existingType.setSubCategory(null); } @@ -459,13 +459,12 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal throw new IllegalStateException("Resource type [" + resourceType.getName() + "] in plugin [" + resourceType.getPlugin() + "] has a subcategory (" + newSubCat.getName() + ") which was not defined as a child subcategory of one of its ancestor resource types."); - log.debug("Metadata update: Subcategory of ResourceType [" + resourceType.getName() + "] changed from " + log.info("Metadata update: Subcategory of ResourceType [" + resourceType.getName() + "] changed from " + oldSubCat + " to " + existingSubCat); existingType.setSubCategory(existingSubCat); }
existingType = entityManager.merge(existingType); - entityManager.flush(); }
@Override @@ -600,7 +599,6 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal MeasurementMetadataManagerBean.getMetricDefinitions(resourceType);
entityManager.persist(resourceType); - entityManager.flush(); }
private void linkSubCategoryToParents(ResourceType resourceType) { @@ -665,8 +663,6 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal obsoleteParentType.removeChildResourceType(existingType); moveResourcesToNewParent(existingType, obsoleteParentType, newParentTypes); } - - entityManager.flush(); }
private static String toConciseString(ResourceType type) { @@ -711,7 +707,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal // children are not handled in this method, update their ancestry now. resourceManager.updateAncestry(subjectManager.getOverlord(), resource.getId()); } else { - log.debug("We were unable to move " + resource + " from invalid parent " + resource.getParentResource() + log.info("We were unable to move " + resource + " from invalid parent " + resource.getParentResource() + " to a new valid parent with one of the following types: " + newParentTypes); } } @@ -842,7 +838,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal // simply use the ones from the new type if ((existingSubCat.getChildSubCategories() == null) || existingSubCat.getChildSubCategories().isEmpty()) { for (ResourceSubCategory newChildSubCategory : newSubCategory.getChildSubCategories()) { - log.debug("Metadata update: Adding new child SubCategory [" + newChildSubCategory.getName() + log.info("Metadata update: Adding new child SubCategory [" + newChildSubCategory.getName() + "] to SubCategory [" + existingSubCat.getName() + "]..."); existingSubCat.addChildSubCategory(newChildSubCategory); entityManager.persist(newChildSubCategory); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerLocal.java index ae96d22..b40bf7a 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerLocal.java @@ -46,6 +46,9 @@ public interface ResourceMetadataManagerLocal {
void updateTypes(Set<ResourceType> resourceTypes) throws Exception;
+ /** Exists only to for transactional boundary reasons. Not for general consumption. */ + ResourceType updateType(ResourceType resourceType) throws Exception; + /** TODO: do we want to create a driftMetadataManager SLSB and put this in there */ void updateDriftMetadata(ResourceType existingType, ResourceType resourceType); } \ No newline at end of file diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/test/UpdateConfigurationSubsystemTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/test/UpdateConfigurationSubsystemTest.java index 20f3b9e..4714f57 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/test/UpdateConfigurationSubsystemTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/metadata/test/UpdateConfigurationSubsystemTest.java @@ -176,6 +176,8 @@ public class UpdateConfigurationSubsystemTest extends UpdatePluginMetadataTestBa } }
+ // This test fails but I'm not sure why. It may be a bad test or it may be a real problem. It should + // be investigated and either enabled or deleted. @Test(enabled = false) public void testBZ_573034() throws Exception { // Note, plugins are registered in new transactions. for tests, this means
commit b86e772ba8569cc2084fac6e1b2a96f7422cc0e8 Author: Heiko W. Rupp hwr@redhat.com Date: Tue Aug 14 15:40:56 2012 -0400
BZ 848030 - jmxName can be null, so act accordingly. Also put the jmxName into the connection properties of the created resource.
diff --git a/modules/plugins/jboss-cache-v3/src/main/java/org/rhq/plugins/jbosscache3/JBossCacheDetailDiscoveryComponent.java b/modules/plugins/jboss-cache-v3/src/main/java/org/rhq/plugins/jbosscache3/JBossCacheDetailDiscoveryComponent.java index 5d522de..5d907da 100644 --- a/modules/plugins/jboss-cache-v3/src/main/java/org/rhq/plugins/jbosscache3/JBossCacheDetailDiscoveryComponent.java +++ b/modules/plugins/jboss-cache-v3/src/main/java/org/rhq/plugins/jbosscache3/JBossCacheDetailDiscoveryComponent.java @@ -40,9 +40,9 @@ import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; import org.rhq.plugins.jbossas5.ProfileServiceComponent;
/** - * + * * @author Filip Drabek - * + * */ public class JBossCacheDetailDiscoveryComponent implements ResourceDiscoveryComponent<ProfileServiceComponent<?>> { @@ -80,7 +80,7 @@ public class JBossCacheDetailDiscoveryComponent implements
String jmxName = defaultConfig.getSimple(CACHE_JMX_NAME).getStringValue();
- beanName += (jmxName.equals("") ? "" : "," + jmxName); + beanName += ((jmxName==null || jmxName.equals("")) ? "" : "," + jmxName);
// This is a singleton ResourceType, so we are only looking for a single MBean. EmsBean emsBean = connection.getBean(beanName); @@ -94,6 +94,8 @@ public class JBossCacheDetailDiscoveryComponent implements conf.put(new PropertySimple( JBossCacheDetailComponent.CACHE_DETAIL_BEAN_NAME, beanName)); + conf.put(new PropertySimple(CACHE_JMX_NAME, jmxName)); + resources.add(new DiscoveredResourceDetails(resourceType, beanName, resourceType.getName(), "", "JBoss Cache", conf, null)); diff --git a/modules/plugins/jboss-cache-v3/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-cache-v3/src/main/resources/META-INF/rhq-plugin.xml index cba79cf..2572f54 100644 --- a/modules/plugins/jboss-cache-v3/src/main/resources/META-INF/rhq-plugin.xml +++ b/modules/plugins/jboss-cache-v3/src/main/resources/META-INF/rhq-plugin.xml @@ -31,7 +31,7 @@ singleton="true">
<plugin-configuration> - <c:simple-property name="jmx-resource" default=""/> + <c:simple-property name="jmx-resource" default="" required="false"/> </plugin-configuration>
<operation name="destroy" displayName="Destroy this cache."/>
commit 9e5352d85ca3b4ee98d52771930b61e72f73f579 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 14 14:35:51 2012 -0500
[BZ 833187] A few more updates to :nullable list parsing and saving code. The original fix did not include the loading of such properties.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java index 0a49bd1..2fdff39 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationLoadDelegate.java @@ -257,7 +257,8 @@ public class ConfigurationLoadDelegate implements ConfigurationFacet { } }
- if (propertyName.endsWith(":expr") || propertyName.endsWith(":collapsed")) { + if (propertyName.endsWith(":expr") || propertyName.endsWith(":collapsed") + || propertyName.endsWith(":nullable")) { String realName = propertyName.substring(0, propertyName.indexOf(":")); valueObject = results.get(realName); } else { diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java index 86ba37a..8286f17 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java @@ -569,7 +569,7 @@ public class ConfigurationWriteDelegate implements ConfigurationFacet { } }
- propertyName = stripNumberIdentifier(property.getName()); + propertyName = stripNumberIdentifier(propertyName);
return new SimpleEntry<String, List<Object>>(propertyName, values); } 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 08c12ba..a1eb285 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 @@ -3734,7 +3734,7 @@ <c:simple-property name="persist-delivery-count-before-delivery" required="false" type="boolean" readOnly="true" defaultValue="false" description="Whether the delivery count is persisted before delivery. False means that this only happens after a message has been cancelled. The default value is false."/> <c:simple-property name="persist-id-cache" required="false" type="boolean" readOnly="true" defaultValue="true" description="Whether IDs are persisted to the journal. The default value is true."/> <c:simple-property name="persistence-enabled" required="false" type="boolean" readOnly="true" defaultValue="true" description="Whether the server will use the file based journal for persistence. The default value is true."/> - <c:list-property name="remoting-interceptors:nullable" required="false" readOnly="true" description="The list of interceptor classes used by this server." > + <c:list-property name="remoting-interceptors:nullable" required="false" readOnly="true" displayName="Remoting Interceptors" description="The list of interceptor classes used by this server." > <c:simple-property name="remoting-interceptors" readOnly="true"/> </c:list-property> <c:simple-property name="run-sync-speed-test" required="false" type="boolean" readOnly="true" defaultValue="false" description="Whether on startup to perform a diagnostic test on how fast your disk can sync. Useful when determining performance issues. The default value is false."/> @@ -4700,7 +4700,7 @@ <c:simple-property name="reconnect-attempts" required="false" type="integer" readOnly="true" defaultValue="-1" description="The total number of reconnect attempts the bridge will make before giving up and shutting down. A value of -1 signifies an unlimited number of attempts. The default value is -1."/> <c:simple-property name="retry-interval" required="false" type="long" readOnly="true" defaultValue="500" description="The period in milliseconds between subsequent reconnection attempts, if the connection to the target server has failed. The default value is 500."/> <c:simple-property name="retry-interval-multiplier" required="false" type="double" readOnly="true" defaultValue="1.0" description="A multiplier to apply to the time since the last retry to compute the time to the next retry. This allows you to implement an exponential backoff between retry attempts. The default value is 1.0."/> - <c:list-property name="static-connectors:nullable" required="false" readOnly="true" description="The statically defined list of connectors to which this cluster connection will make connections. Must be undefined (null) if 'discovery-group-name' is defined." > + <c:list-property name="static-connectors:nullable" required="false" readOnly="true" displayName="Static Connectors" description="The statically defined list of connectors to which this cluster connection will make connections. Must be undefined (null) if 'discovery-group-name' is defined." > <c:simple-property name="static-connectors" readOnly="true"/> </c:list-property> <c:simple-property name="use-duplicate-detection" required="false" type="boolean" readOnly="true" defaultValue="true" description="Whether the bridge will automatically insert a duplicate id property into each message that it forwards. The default value is true."/> @@ -4823,7 +4823,7 @@ <c:simple-property name="reconnect-attempts" required="false" type="integer" readOnly="true" defaultValue="-1" description="The total number of reconnect attempts the bridge will make before giving up and shutting down. A value of -1 signifies an unlimited number of attempts. The default value is -1."/> <c:simple-property name="retry-interval" required="false" type="long" readOnly="true" defaultValue="2000" description="The period in milliseconds between subsequent reconnection attempts, if the connection to the target server has failed. The default value is 2000."/> <c:simple-property name="retry-interval-multiplier" required="false" type="double" readOnly="true" defaultValue="1.0" description="A multiplier to apply to the time since the last retry to compute the time to the next retry. This allows you to implement an exponential backoff between retry attempts. The default value is 1.0."/> - <c:list-property name="static-connectors:nullable" required="false" description="A list of names of statically defined connectors used by this bridge. Must be undefined (null) if 'discovery-group-name' is defined." > + <c:list-property name="static-connectors:nullable" required="false" displayName="Static Connectors" description="A list of names of statically defined connectors used by this bridge. Must be undefined (null) if 'discovery-group-name' is defined." > <c:simple-property name="static-connectors" /> </c:list-property> <c:simple-property name="transformer-class-name" required="false" type="string" readOnly="true" description="The name of a user-defined class which implements the org.hornetq.core.server.cluster.Transformer interface."/> @@ -6373,7 +6373,7 @@ <c:simple-property name="persist-delivery-count-before-delivery" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether the delivery count is persisted before delivery. False means that this only happens after a message has been cancelled. The default value is false."/> <c:simple-property name="persist-id-cache" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether IDs are persisted to the journal. The default value is true."/> <c:simple-property name="persistence-enabled" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether the server will use the file based journal for persistence. The default value is true."/> - <c:list-property name="remoting-interceptors:nullable" required="false" description="The list of interceptor classes used by this server." > + <c:list-property name="remoting-interceptors:nullable" required="false" displayName="Remoting Interceptors" description="The list of interceptor classes used by this server." > <c:simple-property name="remoting-interceptors" /> </c:list-property> <c:simple-property name="run-sync-speed-test" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether on startup to perform a diagnostic test on how fast your disk can sync. Useful when determining performance issues. The default value is false."/> @@ -6829,7 +6829,7 @@ <c:simple-property name="reconnect-attempts" required="false" type="integer" readOnly="false" defaultValue="-1" description="The total number of reconnect attempts the bridge will make before giving up and shutting down. A value of -1 signifies an unlimited number of attempts. The default value is -1."/> <c:simple-property name="retry-interval" required="false" type="long" readOnly="false" defaultValue="500" description="The period in milliseconds between subsequent reconnection attempts, if the connection to the target server has failed. The default value is 500."/> <c:simple-property name="retry-interval-multiplier" required="false" type="double" readOnly="false" defaultValue="1.0" description="A multiplier to apply to the time since the last retry to compute the time to the next retry. This allows you to implement an exponential backoff between retry attempts. The default value is 1.0."/> - <c:list-property name="static-connectors:nullable" required="false" description="The statically defined list of connectors to which this cluster connection will make connections. Must be undefined (null) if 'discovery-group-name' is defined." > + <c:list-property name="static-connectors:nullable" required="false" displayName="Static Connectors" description="The statically defined list of connectors to which this cluster connection will make connections. Must be undefined (null) if 'discovery-group-name' is defined." > <c:simple-property name="static-connectors" /> </c:list-property> <c:simple-property name="use-duplicate-detection" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether the bridge will automatically insert a duplicate id property into each message that it forwards. The default value is true."/> @@ -6918,7 +6918,7 @@ <c:simple-property name="reconnect-attempts" required="false" type="integer" readOnly="false" defaultValue="-1" description="The total number of reconnect attempts the bridge will make before giving up and shutting down. A value of -1 signifies an unlimited number of attempts. The default value is -1."/> <c:simple-property name="retry-interval" required="false" type="long" readOnly="false" defaultValue="2000" description="The period in milliseconds between subsequent reconnection attempts, if the connection to the target server has failed. The default value is 2000."/> <c:simple-property name="retry-interval-multiplier" required="false" type="double" readOnly="false" defaultValue="1.0" description="A multiplier to apply to the time since the last retry to compute the time to the next retry. This allows you to implement an exponential backoff between retry attempts. The default value is 1.0."/> - <c:list-property name="static-connectors:nullable" required="false" description="A list of names of statically defined connectors used by this bridge. Must be undefined (null) if 'discovery-group-name' is defined." > + <c:list-property name="static-connectors:nullable" required="false" displayName="Static Connectors" description="A list of names of statically defined connectors used by this bridge. Must be undefined (null) if 'discovery-group-name' is defined." > <c:simple-property name="static-connectors" /> </c:list-property> <c:simple-property name="transformer-class-name" required="false" type="string" readOnly="false" description="The name of a user-defined class which implements the org.hornetq.core.server.cluster.Transformer interface."/> @@ -9342,7 +9342,7 @@ <c:simple-property name="persist-delivery-count-before-delivery" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether the delivery count is persisted before delivery. False means that this only happens after a message has been cancelled. The default value is false."/> <c:simple-property name="persist-id-cache" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether IDs are persisted to the journal. The default value is true."/> <c:simple-property name="persistence-enabled" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether the server will use the file based journal for persistence. The default value is true."/> - <c:list-property name="remoting-interceptors:nullable" required="false" description="The list of interceptor classes used by this server."> + <c:list-property name="remoting-interceptors:nullable" required="false" displayName="Remoting Interceptors" description="The list of interceptor classes used by this server."> <c:simple-property name="remoting-interceptors"/> </c:list-property> <c:simple-property name="run-sync-speed-test" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether on startup to perform a diagnostic test on how fast your disk can sync. Useful when determining performance issues. The default value is false."/> @@ -11936,7 +11936,7 @@ <c:simple-property name="persist-delivery-count-before-delivery" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether the delivery count is persisted before delivery. False means that this only happens after a message has been cancelled. The default value is false."/> <c:simple-property name="persist-id-cache" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether IDs are persisted to the journal. The default value is true."/> <c:simple-property name="persistence-enabled" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether the server will use the file based journal for persistence. The default value is true."/> - <c:list-property name="remoting-interceptors:nullable" required="false" description="The list of interceptor classes used by this server."> + <c:list-property name="remoting-interceptors:nullable" required="false" displayName="Remoting Interceptors" description="The list of interceptor classes used by this server."> <c:simple-property name="remoting-interceptors"/> </c:list-property> <c:simple-property name="run-sync-speed-test" required="false" type="boolean" readOnly="false" defaultValue="false" description="Whether on startup to perform a diagnostic test on how fast your disk can sync. Useful when determining performance issues. The default value is false."/> @@ -12903,7 +12903,7 @@ <c:simple-property name="reconnect-attempts" required="false" type="integer" readOnly="false" defaultValue="-1" description="The total number of reconnect attempts the bridge will make before giving up and shutting down. A value of -1 signifies an unlimited number of attempts. The default value is -1."/> <c:simple-property name="retry-interval" required="false" type="long" readOnly="false" defaultValue="500" description="The period in milliseconds between subsequent reconnection attempts, if the connection to the target server has failed. The default value is 500."/> <c:simple-property name="retry-interval-multiplier" required="false" type="double" readOnly="false" defaultValue="1.0" description="A multiplier to apply to the time since the last retry to compute the time to the next retry. This allows you to implement an exponential backoff between retry attempts. The default value is 1.0."/> - <c:list-property name="static-connectors:nullable" required="false" description="The statically defined list of connectors to which this cluster connection will make connections. Must be undefined (null) if 'discovery-group-name' is defined."> + <c:list-property name="static-connectors:nullable" required="false" displayName="Static Connectors" description="The statically defined list of connectors to which this cluster connection will make connections. Must be undefined (null) if 'discovery-group-name' is defined."> <c:simple-property name="static-connectors"/> </c:list-property> <c:simple-property name="use-duplicate-detection" required="false" type="boolean" readOnly="false" defaultValue="true" description="Whether the bridge will automatically insert a duplicate id property into each message that it forwards. The default value is true."/> @@ -13026,7 +13026,7 @@ <c:simple-property name="reconnect-attempts" required="false" type="integer" readOnly="false" defaultValue="-1" description="The total number of reconnect attempts the bridge will make before giving up and shutting down. A value of -1 signifies an unlimited number of attempts. The default value is -1."/> <c:simple-property name="retry-interval" required="false" type="long" readOnly="false" defaultValue="2000" description="The period in milliseconds between subsequent reconnection attempts, if the connection to the target server has failed. The default value is 2000."/> <c:simple-property name="retry-interval-multiplier" required="false" type="double" readOnly="false" defaultValue="1.0" description="A multiplier to apply to the time since the last retry to compute the time to the next retry. This allows you to implement an exponential backoff between retry attempts. The default value is 1.0."/> - <c:list-property name="static-connectors:nullable" required="false" description="A list of names of statically defined connectors used by this bridge. Must be undefined (null) if 'discovery-group-name' is defined."> + <c:list-property name="static-connectors:nullable" required="false" displayName="Static Connectors" description="A list of names of statically defined connectors used by this bridge. Must be undefined (null) if 'discovery-group-name' is defined."> <c:simple-property name="static-connectors"/> </c:list-property> <c:simple-property name="transformer-class-name" required="false" type="string" readOnly="false" description="The name of a user-defined class which implements the org.hornetq.core.server.cluster.Transformer interface."/>
commit 15248b7c3099a46a3c41ccf487f391861d03a9bd Author: John Sanda jsanda@redhat.com Date: Tue Aug 14 15:13:24 2012 -0400
[BZ 846715] Taking groovy server plugin out of build
Until we find a new home for the groovy-script-server plugin, I am taking it out of the build to get past errors when building with Java 7.
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml index 4e4a30e..11f3b5c 100644 --- a/modules/enterprise/server/plugins/pom.xml +++ b/modules/enterprise/server/plugins/pom.xml @@ -78,7 +78,6 @@ <module>filetemplate-bundle</module> <module>ant-bundle</module> <module>validate-all-serverplugins</module> - <module>groovy-script</module> <module>packagetype-cli</module> </modules>
commit 19cfeb90dcbf853a5aacf76656b4218af16d642f Author: Lukas Krejci lkrejci@redhat.com Date: Tue Aug 14 15:51:48 2012 +0200
[BZ 848066] - The group resource configuration page shows the config editor again Also made the layout consistent with the single resource config page by moving the button bar to the bottom of the page.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java index f6d6657..c5467b8 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/configuration/GroupResourceConfigurationEditView.java @@ -111,9 +111,8 @@ public class GroupResourceConfigurationEditView extends LocatableVLayout impleme save(); } }); + this.saveButton.disable(); buttonbar.addMember(saveButton); - // The button bar will remain hidden until the configuration has been successfully loaded. - buttonbar.setVisible(false); return buttonbar; }
@@ -125,7 +124,7 @@ public class GroupResourceConfigurationEditView extends LocatableVLayout impleme }
this.refreshing = true; - this.saveButton.disable(); + if (editor != null) { editor.destroy(); removeMember(editor); @@ -146,6 +145,7 @@ public class GroupResourceConfigurationEditView extends LocatableVLayout impleme this.editor.addPropertyValueChangeListener(this); this.editor.setReadOnly(!this.resourcePermission.isConfigureWrite()); addMember(this.editor); + addMember(createButtonBar()); this.refreshing = false; // when we get here, we know we are done the refresh } } @@ -197,7 +197,6 @@ public class GroupResourceConfigurationEditView extends LocatableVLayout impleme "The server did not return the configuration for one or more member resources."); } memberConfigurations.add(memberConfiguration); - addMember(createButtonBar()); } initEditor(); }
commit bbdcaee2ca23717a53277fe0bb479f761f46025e Author: Lukas Krejci lkrejci@redhat.com Date: Tue Aug 14 13:38:06 2012 +0200
[BZ 847804] - make sure to fetch the latest known resource config through the proxy factory.
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java index 10ee612..0199c77 100644 --- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java +++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/client/ResourceClientProxy.java @@ -491,10 +491,13 @@ public class ResourceClientProxy { public Configuration getResourceConfiguration() { if (!LazyLoadScenario.isShouldLoad()) return null; - - return remoteClient.getProxy(ConfigurationManagerRemote.class).getResourceConfiguration( - remoteClient.getSubject(), - resourceClientProxy.resourceId); + + //make sure to fetch the latest known resource config. This ensures that + //the server goes out to the agent if there is no known config yet and thus + //giving the scripting user an always up-to-date info. + ResourceConfigurationUpdate update = remoteClient.getProxy(ConfigurationManagerRemote.class).getLatestResourceConfigurationUpdate( + remoteClient.getSubject(), resourceClientProxy.resourceId); + return update == null ? null : update.getConfiguration(); }
public ConfigurationDefinition getResourceConfigurationDefinition() {
commit 06a05b1371c11563b639d4faf74f27254668cd21 Author: Stefan Negrea snegrea@redhat.com Date: Mon Aug 13 18:20:12 2012 -0500
[BZ 829329] Enable the discovery of server-group deployments after a domain deployment is sent to server groups.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java index ff55c8d..27b1133 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java @@ -552,6 +552,13 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend return result; }
+ /** + * Requests a deferred child resource discovery for sub-resources of this server. + */ + public void requestDeferredChildResourcesDiscovery() { + this.context.getInventoryContext().requestDeferredChildResourcesDiscovery(); + } + @Override public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) throws Exception { Set<MeasurementScheduleRequest> skmRequests = new HashSet<MeasurementScheduleRequest>(requests.size()); diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainDeploymentComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainDeploymentComponent.java index 6192c18..54cffbf 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainDeploymentComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DomainDeploymentComponent.java @@ -77,6 +77,14 @@ public class DomainDeploymentComponent extends DeploymentComponent implements Op Result res = getASConnection().execute(operation, 120); // wait up to 2 minutes if (res.isSuccess()) { operationResult.setSimpleResult("Successfully deployed to server groups " + serverGroups); + + //request the server to discover child resources to allow the discovery of the deployments + //on server groups immediately + if (this.context.getParentResourceComponent().getClass().isInstance(HostControllerComponent.class)) { + HostControllerComponent<?> hostController = (HostControllerComponent<?>) this.context + .getParentResourceComponent(); + hostController.requestDeferredChildResourcesDiscovery(); + } } else { operationResult.setErrorMessage("Deployment to server groups failed: " + res.getFailureDescription()); }
commit 1084a72ad31e8d78529ce8313e9e83c12b264ec7 Author: Stefan Negrea snegrea@redhat.com Date: Mon Aug 13 16:36:03 2012 -0500
[BZ 839643] Removed the property from the profile subsystem definition until the AS7 issue is resolved. The property is not important for profiles since the value is read-only and used only by the managed server. The value can still be read from the managed server itself.
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 d27d432..08c12ba 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 @@ -6471,7 +6471,6 @@ <c:simple-property name="failover-on-server-shutdown" required="false" type="boolean" readOnly="false" description="True to fail over on server shutdown."/> <c:simple-property name="group-id" required="false" type="string" readOnly="false" description="The group id."/> <c:simple-property name="ha" required="true" type="boolean" readOnly="false" defaultValue="false" description="Whether the connection factory supports High Availability. The default value is false."/> - <c:simple-property name="initial-message-packet-size" required="true" type="integer" readOnly="true" description="The initial size of messages created through this factory."/> <c:simple-property name="max-retry-interval" required="false" type="long" readOnly="false" defaultValue="2000" description="The max retry interval. The default value is 2000."/> <c:simple-property name="min-large-message-size" required="false" type="integer" readOnly="false" defaultValue="102400" description="The min large message size. The default value is 102400."/> <c:simple-property name="pre-acknowledge" required="false" type="boolean" readOnly="false" defaultValue="false" description="True to pre-acknowledge. The default value is false."/>
commit 83c2b30289f9b11b2d0e25d02f51b1475ccd9aea Author: Heiko W. Rupp hwr@redhat.com Date: Mon Aug 13 16:34:19 2012 -0400
BZ 846385 - Make sure to use the JDG types only when he product found is JDG and the other way around.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SubsystemDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SubsystemDiscovery.java index deec7a3..18eb274 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SubsystemDiscovery.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SubsystemDiscovery.java @@ -85,8 +85,9 @@ public class SubsystemDiscovery implements ResourceDiscoveryComponent<BaseCompon lookForChildren = true; }
- if (isIspnForJDG(context, confPath)) { - log.debug("We have JDG as child, ignoring the {JBossAS7}Infinispan type"); + // check if the parent is a JDG server. In this case ignore the as7 version + // of the type and vice versa + if (shouldSkipEntryWrtIspn(context, confPath)) { return details; }
@@ -190,40 +191,48 @@ public class SubsystemDiscovery implements ResourceDiscoveryComponent<BaseCompon return details; }
- private boolean isIspnForJDG(ResourceDiscoveryContext<BaseComponent<?>> context, String confPath) { - - // Check if this is ISPN + /** + * The as7 plugin and the JDG plugin both have a subsystem=infinispan. We need to decide + * which one to 'activate' depending on the type, plugin and the detected parent. + * Rules are:<ul> + * <li>If the parent is a host controller or such, there is no jdg available</li> + * <li>If parent is eap/as7, use the type from the as7 plugin</li> + * <li>If parent is a jdg server, use the type from the jdg plugin.</li> + * </ul> + * + * + * @param context The parent's resource component + * @param confPath The subsystem that got fed into discovery. Directly return is not subsystem=infinispan + * @return True if this subsystem should be skipped. + */ + private boolean shouldSkipEntryWrtIspn(ResourceDiscoveryContext<BaseComponent<?>> context, + String confPath) { + + String jdgPluginType = "JDG"; + + // If this is not subsystem=infinispan, we should not skip it at all if (!"subsystem=infinispan".equals(confPath)) return false;
ResourceType ourType = context.getResourceType(); - if (ourType.getPlugin().equals("JDG")) - return false; + boolean ourPluginTypeIsJdg = ourType.getPlugin().equals(jdgPluginType);
- if (!ourType.getName().equals("Infinispan")) - return false; + String productType = context.getParentResourceComponent().pluginConfiguration.getSimpleValue("productType","AS7"); + boolean isJdgProduct = jdgPluginType.equals(productType);
- // So we are {JBossAS7}Infinispan - Set<ResourceType> parentTypes = ourType.getParentResourceTypes(); - ResourceType parent = null; - for (ResourceType type : parentTypes) { - if (type.getName().equals("JBossAS7 Standalone Server") && type.getPlugin().equals("JBossAS7")) { - parent = type; - break; - } - } - if (parent==null) + if (ourPluginTypeIsJdg && isJdgProduct) { + if (log.isDebugEnabled()) + log.debug("Ours is JDG and product is JDG"); return false; + }
- // So we are as7/eap and need to check now if we have a JDG plugin's ISPN resource as child - boolean found = false; - for (ResourceType type: parent.getChildResourceTypes()) { - if (type.getPlugin().equals("JDG") && type.getName().equals("Infinispan")) { - found = true; - } + if (!ourPluginTypeIsJdg && !isJdgProduct) { + if (log.isDebugEnabled()) + log.debug("Ours is not JDG (" + ourType.toString() + ") and product is not JDG (" + productType + ")"); + return false; }
- return found; + return true; }
}
commit 1b2ba60b043c4c9e8feff247dcb0b53f342b9371 Author: Stefan Negrea snegrea@redhat.com Date: Mon Aug 13 15:07:10 2012 -0500
[BZ 847674] Prevent exceptions from bubbling up because that is an indication the server is still down after the restart. Consider a thrown exception just a failed attempt to connect to the server, equivalent to success == false response for the test operation.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java index 9bc01f2..ff55c8d 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java @@ -406,12 +406,19 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend int count = 0; while (!up) { Operation op = new ReadAttribute(new Address(), "release-version"); - Result res = getASConnection().execute(op); - if (res.isSuccess()) { // If op succeeds, server is not down - up = true; - } else if (count > 20) { - break; + try{ + Result res = getASConnection().execute(op); + if (res.isSuccess()) { // If op succeeds, server is not down + up = true; + } else if (count > 20) { + break; + } + } catch (Exception e) { + //do absolutely nothing + //if an exception is thrown that means the server is still down, so consider this + //a single failed attempt, equivalent to res.isSuccess == false } + if (!up) { try { Thread.sleep(1000); // Wait 1s
commit 35d9093ac3c6118d1fc9ad5a8eef3a6bce6fe398 Author: Jay Shaughnessy jshaughn@redhat.com Date: Mon Aug 13 14:18:10 2012 -0400
- Fix issues with Filtering UNCOMMITTED resources in a few NamedQueries. - Remove unnecessary decl of ResourceGroupManager in test class, use the base class var.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/Availability.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/Availability.java index 6158a74..d8a1083 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/Availability.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/Availability.java @@ -104,7 +104,8 @@ import org.rhq.core.domain.resource.Resource; + " WHERE av.resource.id IN ( SELECT ires.id " // + " FROM ResourceGroup rg " // + " JOIN rg.implicitResources ires " // - + " WHERE rg.id = :groupId AND ires.inventoryStatus = 'COMMITTED' ) " // + + " WHERE rg.id = :groupId ) " // + + " AND av.resource.inventoryStatus = 'COMMITTED' " // + " AND ((av.startTime <= :start AND (av.endTime >= :start OR av.endTime IS NULL) ) " /* availability straddles :start */ + " OR (av.startTime BETWEEN :start AND :end)) " /* interval straddles availability.startTime */ + "ORDER BY av.startTime ASC"), // @@ -113,6 +114,7 @@ import org.rhq.core.domain.resource.Resource; + " JOIN av.resource res JOIN res.parentResource parent JOIN res.resourceType type " // + " WHERE parent.id = :parentId " // + " AND type.id = :typeId " // + + " AND av.resource.inventoryStatus = 'COMMITTED' " // + " AND ((av.startTime <= :start AND (av.endTime >= :start OR av.endTime IS NULL)) " /* availability straddles :start */ + " OR (av.startTime BETWEEN :start AND :end)) " /* interval straddles availability.startTime */ + "ORDER BY av.startTime ASC"), // diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java index 7b30aaf..937a891 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java @@ -197,7 +197,8 @@ import org.rhq.core.domain.tagging.Tag; + " AND res.id NOT IN ( SELECT explicitRes.id " // + " FROM ResourceGroup rg " // + " JOIN rg.explicitResources explicitRes " // - + " WHERE rg.id = :groupId AND explicitRes.inventoryStatus = 'COMMITTED') ") }) + + " WHERE rg.id = :groupId ) " // + + " AND res.inventoryStatus = 'COMMITTED' ") }) @SequenceGenerator(name = "id", sequenceName = "RHQ_RESOURCE_GROUP_ID_SEQ") @Table(name = "RHQ_RESOURCE_GROUP") @XmlAccessorType(XmlAccessType.FIELD) diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/GroupWithUncommittedTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/GroupWithUncommittedTest.java index 8ef992d..3c57e5c 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/GroupWithUncommittedTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/group/test/GroupWithUncommittedTest.java @@ -24,7 +24,6 @@ import java.util.List; import javax.persistence.Query;
import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test;
import org.rhq.core.domain.authz.Permission; @@ -39,7 +38,6 @@ import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite; import org.rhq.core.domain.server.PersistenceUtility; import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; -import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal; import org.rhq.enterprise.server.test.LargeGroupTestBase; import org.rhq.enterprise.server.test.TestServerCommunicationsService; import org.rhq.enterprise.server.util.LookupUtil; @@ -49,7 +47,6 @@ import org.rhq.enterprise.server.util.SessionTestHelper; public class GroupWithUncommittedTest extends LargeGroupTestBase {
private static final boolean TESTS_ENABLED = true; - private ResourceGroupManagerLocal rgMgr; private LargeGroupEnvironment env;
private class GroupAvailCounts { @@ -77,11 +74,6 @@ public class GroupWithUncommittedTest extends LargeGroupTestBase { protected void setupMockAgentServices(TestServerCommunicationsService agentServiceContainer) { }
- @BeforeMethod - public void getManagers() { - this.rgMgr = LookupUtil.getResourceGroupManager(); - } - /** * Remove the group and all its members. */ @@ -104,7 +96,8 @@ public class GroupWithUncommittedTest extends LargeGroupTestBase { SessionTestHelper.simulateLogin(env.normalSubject);
// these queries were tweeked to filter uncommitted - see BZ 820981 - PageList<ResourceGroupComposite> results = rgMgr.findResourceGroupComposites(env.normalSubject, null, null, + PageList<ResourceGroupComposite> results = resourceGroupManager.findResourceGroupComposites(env.normalSubject, + null, null, null, null, null, null, env.compatibleGroup.getId(), new PageControl(0, 50)); int count = results.size(); assert count == 1 : "results=" + results; @@ -263,7 +256,7 @@ public class GroupWithUncommittedTest extends LargeGroupTestBase { assert resConfigCount == gac.visibleTotal; assert pluginConfigCount == gac.visibleTotal;
- int groupSize = rgMgr.getExplicitGroupMemberCount(env.compatibleGroup.getId()); + int groupSize = resourceGroupManager.getExplicitGroupMemberCount(env.compatibleGroup.getId()); assert resConfigCount == groupSize; assert pluginConfigCount == groupSize;
commit ef1a7865118a3a76f7ee0ea1e119ba03f28c34ca Author: Stefan Negrea snegrea@redhat.com Date: Fri Aug 10 15:31:52 2012 -0500
[BZ 828329] Adding inventory context to a resource context.
Squashed commit of the following:
commit 14b7dd184880140d74d4658ffa0e62a575f27c4f Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 7 16:03:33 2012 -0500
[BZ 828329] Minor documentation updates and rewording.
commit 7f5aa39c22688ee935b23d2dad767ff03c41dc96 Author: Stefan Negrea snegrea@redhat.com Date: Tue Aug 7 14:45:31 2012 -0500
[BZ 828329] Removed plugin container specific classes. The regular will just block until the discovery processes completes, no data is returned to caller.
commit 2b17808e9bff072776c7ecada992d33c34203155 Author: Stefan Negrea snegrea@redhat.com Date: Mon Aug 6 21:07:00 2012 -0500
[BZ 828329] The inventory context has now a deferred and a blocking method for requesting discovery. Also included are various other updates based on community feedback.
commit 816622e43c88c3b2bf751c1e2d9682d64556fdbb Author: Stefan Negrea snegrea@redhat.com Date: Mon Aug 6 10:38:34 2012 -0500
[BZ 828329] Added the possibility to start discovery scans from a resource context. The code executes a deffered service scan for children of the resource managed by the resource context.
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/InventoryContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/InventoryContext.java new file mode 100644 index 0000000..ec1fab4 --- /dev/null +++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/InventoryContext.java @@ -0,0 +1,65 @@ +/* + * RHQ Management Platform + * Copyright 2012, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.rhq.core.pluginapi.inventory; + + +/** + * @author Stefan Negrea + * + */ +public interface InventoryContext { + + /** + * This method requests a deferred service discovery process for children of the resource. It requests the discovery + * process and returns immediately without waiting for results. The discovery process imports into inventory all discovered + * resources, so no further action is required from the caller. + * + * This method should be used by resources following an action (outside of create/delete children) that results + * in having additional children discoverable. A good example is an operation execution that enables extra functionality + * on the managed resource which in turn translates into having additional children available for management. + * + * Note: All services are discovered by the regular discovery process that runs every 24 hours. This method allows + * a resource to request an immediate run of the discovery process for child resources, rather than wait for the scheduled + * service discovery. + */ + public void requestDeferredChildResourcesDiscovery(); + + + /** + * This method requests a service discovery process for children of the resource. It schedules the discovery + * process and blocks until the discovery finishes. The discovery process imports into inventory all discovered + * resources, so no further action is required from the caller. + * + * This method should be used by resources following an action (outside of create/delete children) that results + * in having additional children discoverable. A good example is an operation execution that enables extra functionality + * on the managed resource which in turn translates into having additional children available for management. This method blocks + * until the discovery processes finishes, this includes committing resources to inventory. For additional processing, + * the calling resource can then request the list of child resources (it will include newly discovered resources too). + * + * Note: All services are discovered by the regular discovery process that runs every 24 hours. This method allows + * a resource to request an immediate run of the discovery process for child resources, rather than wait for the scheduled + * service discovery. + * + * @return discovered child resources + */ + public void requestChildResourcesDiscovery(); + +} diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java index 4b21719..76ccf39 100644 --- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java +++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/inventory/ResourceContext.java @@ -83,6 +83,7 @@ public class ResourceContext<T extends ResourceComponent<?>> { private final OperationContext operationContext; private final ContentContext contentContext; private final AvailabilityContext availabilityContext; + private final InventoryContext inventoryContext; private final PluginContainerDeployment pluginContainerDeployment; private final ResourceTypeProcesses trackedProcesses;
@@ -152,7 +153,7 @@ public class ResourceContext<T extends ResourceComponent<?>> { public ResourceContext(Resource resource, T parentResourceComponent, ResourceContext<?> parentResourceContext, ResourceDiscoveryComponent<T> resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory, File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext, - ContentContext contentContext, AvailabilityContext availabilityContext, + ContentContext contentContext, AvailabilityContext availabilityContext, InventoryContext inventoryContext, PluginContainerDeployment pluginContainerDeployment) {
this.resourceKey = resource.getResourceKey(); @@ -177,6 +178,7 @@ public class ResourceContext<T extends ResourceComponent<?>> { this.operationContext = operationContext; this.contentContext = contentContext; this.availabilityContext = availabilityContext; + this.inventoryContext = inventoryContext;
String parentResourceUuid = ""; if (resource.getParentResource() != null) { @@ -505,6 +507,16 @@ public class ResourceContext<T extends ResourceComponent<?>> { }
/** + * Returns an {@link InventoryContext} that allows the plugin to access inventory related functionality provided by the + * plugin container. + * + * @return the inventory context + */ + public InventoryContext getInventoryContext() { + return inventoryContext; + } + + /** * @deprecated Use {@link AvailabilityContext#createAvailabilityCollectorRunnable(AvailabilityFacet, long)} */ public AvailabilityCollectorRunnable createAvailabilityCollectorRunnable(AvailabilityFacet availChecker, diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java index 3c5b6a2..471978c 100644 --- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java +++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/upgrade/ResourceUpgradeContext.java @@ -23,13 +23,13 @@ package org.rhq.core.pluginapi.upgrade;
import java.io.File; -import java.util.concurrent.Executor;
import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.resource.Resource; import org.rhq.core.pluginapi.availability.AvailabilityContext; import org.rhq.core.pluginapi.content.ContentContext; import org.rhq.core.pluginapi.event.EventContext; +import org.rhq.core.pluginapi.inventory.InventoryContext; import org.rhq.core.pluginapi.inventory.PluginContainerDeployment; import org.rhq.core.pluginapi.inventory.ResourceComponent; import org.rhq.core.pluginapi.inventory.ResourceContext; @@ -60,11 +60,11 @@ public class ResourceUpgradeContext<T extends ResourceComponent<?>> extends Reso T parentResourceComponent, ResourceDiscoveryComponent<T> resourceDiscoveryComponent, SystemInfo systemInfo, File temporaryDirectory, File dataDirectory, String pluginContainerName, EventContext eventContext, OperationContext operationContext, ContentContext contentContext, AvailabilityContext availabilityContext, - PluginContainerDeployment pluginContainerDeployment) { + InventoryContext inventoryContext, PluginContainerDeployment pluginContainerDeployment) {
super(resource, parentResourceComponent, parentResourceContext, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, eventContext, operationContext, contentContext, - availabilityContext, pluginContainerDeployment); + availabilityContext, inventoryContext, pluginContainerDeployment);
this.resourceConfiguration = resource.getResourceConfiguration(); this.name = resource.getName(); diff --git a/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java b/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java index fe194c9..118d514 100644 --- a/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java +++ b/modules/core/plugin-api/src/test/java/org/rhq/core/pluginapi/inventory/ResourceContextTest.java @@ -86,7 +86,7 @@ public class ResourceContextTest {
//create object to test and inject required dependencies ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, - mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); + mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null);
//run code under test File result = objectUnderTest.getResourceDataDirectory(); @@ -152,7 +152,7 @@ public class ResourceContextTest {
//create object to test and inject required dependencies ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parent1ResourceContext, null, - null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); + null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null);
//run code under test File result = objectUnderTest.getResourceDataDirectory(); @@ -206,7 +206,7 @@ public class ResourceContextTest {
//create object to test and inject required dependencies ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, - mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); + mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null);
//run code under test File result = objectUnderTest.getResourceDataDirectory(); @@ -260,7 +260,7 @@ public class ResourceContextTest {
//create object to test and inject required dependencies ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, - mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); + mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null);
//run code under test File result = objectUnderTest.getResourceDataDirectory(); @@ -314,7 +314,7 @@ public class ResourceContextTest {
//create object to test and inject required dependencies ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parentResourceContext, null, null, - mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); + mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null);
//run code under test File result = objectUnderTest.getResourceDataDirectory(); @@ -377,7 +377,7 @@ public class ResourceContextTest {
//create object to test and inject required dependencies ResourceContext<?> objectUnderTest = new ResourceContext(mockResource, null, parent1ResourceContext, null, - null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null); + null, mockTemporaryDirectory, mockDataDirectory, null, null, null, null, null, null, null);
//run code under test File result = objectUnderTest.getFutureChildResourceDataDirectory(inputChildResourceKey); diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryContextImpl.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryContextImpl.java new file mode 100644 index 0000000..460a827 --- /dev/null +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryContextImpl.java @@ -0,0 +1,57 @@ +/* + * RHQ Management Platform + * Copyright 2012, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +package org.rhq.core.pc.inventory; + +import org.rhq.core.domain.resource.Resource; +import org.rhq.core.pc.PluginContainer; +import org.rhq.core.pluginapi.inventory.InventoryContext; + +/** + * @author Stefan Negrea + * + */ +public class InventoryContextImpl implements InventoryContext { + + private final Resource resource; + + /** + * @param resource resource + */ + public InventoryContextImpl(Resource resource) { + this.resource = resource; + } + + /* (non-Javadoc) + * @see org.rhq.core.pluginapi.inventory.InventoryContext#discoverChildResources() + */ + @Override + public void requestDeferredChildResourcesDiscovery() { + PluginContainer.getInstance().getInventoryManager().executeServiceScanDeferred(resource); + } + + /* (non-Javadoc) + * @see org.rhq.core.pluginapi.inventory.InventoryContext#requestChildResourcesDiscovery() + */ + @Override + public void requestChildResourcesDiscovery() { + PluginContainer.getInstance().getInventoryManager().executeServiceScanImmediately(resource); + } +} diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java index 8cd3859..b3f7fa9 100644 --- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java +++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java @@ -108,6 +108,7 @@ import org.rhq.core.pluginapi.event.EventContext; import org.rhq.core.pluginapi.inventory.ClassLoaderFacet; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; +import org.rhq.core.pluginapi.inventory.InventoryContext; import org.rhq.core.pluginapi.inventory.ManualAddFacet; import org.rhq.core.pluginapi.inventory.ProcessScanResult; import org.rhq.core.pluginapi.inventory.ResourceComponent; @@ -575,10 +576,29 @@ public class InventoryManager extends AgentService implements ContainerService, } }
+ @NotNull + public InventoryReport executeServiceScanImmediately(Resource resource) { + try { + RuntimeDiscoveryExecutor discoveryExecutor = new RuntimeDiscoveryExecutor(this, this.configuration, + resource); + return inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) discoveryExecutor).get(); + } catch (InterruptedException e) { + throw new RuntimeException("Service scan execution was interrupted", e); + } catch (ExecutionException e) { + // Should never happen, reports are always generated, even if they're just to report the error + throw new RuntimeException("Unexpected exception", e); + } + } + public void executeServiceScanDeferred() { inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) this.serviceScanExecutor); }
+ public void executeServiceScanDeferred(Resource resource) { + RuntimeDiscoveryExecutor discoveryExecutor = new RuntimeDiscoveryExecutor(this, this.configuration, resource); + inventoryThreadPoolExecutor.submit((Callable<InventoryReport>) discoveryExecutor); + } + /** this will NOT send a availability report up to the server! */ public AvailabilityReport executeAvailabilityScanImmediately(boolean changedOnlyReport) { return executeAvailabilityScanImmediately(changedOnlyReport, false); @@ -1296,7 +1316,7 @@ public class InventoryManager extends AgentService implements ContainerService, /** * Get the parent resource's children, ensuring we use the resource container version of the resource, because * the container's resource is guaranteed to be up to date. - * + * * @param parentResource * @return the children. parentResouce children if there is no container. May be empty. Not null. */ @@ -1304,13 +1324,13 @@ public class InventoryManager extends AgentService implements ContainerService, return getContainerChildren(parentResource, getResourceContainer(parentResource)); }
- /** + /** * Get the parent resource's children, ensuring we use the resource container version of the resource, because * the container's resource is guaranteed to be up to date. - * + * * @param parentResource * @param parentContainer - * @return the children, empty if parentContainer is null or there are no children. not null. + * @return the children, empty if parentContainer is null or there are no children. not null. * @return the children, may be empty, not null. */ public Set<Resource> getContainerChildren(Resource parentResource, ResourceContainer container) { @@ -1784,6 +1804,7 @@ public class InventoryManager extends AgentService implements ContainerService, getOperationContext(resource), // for operation manager access getContentContext(resource), // for content manager access getAvailabilityContext(resource, this.availabilityCollectors), // for components that want to perform async avail checking + getInventoryContext(resource), this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do }
@@ -1803,6 +1824,7 @@ public class InventoryManager extends AgentService implements ContainerService, getOperationContext(resource), // for operation manager access getContentContext(resource), // for content manager access getAvailabilityContext(resource, this.availabilityCollectors), // for components that want avail manager access + getInventoryContext(resource), this.configuration.getPluginContainerDeployment()); // helps components make determinations of what to do }
@@ -1853,7 +1875,7 @@ public class InventoryManager extends AgentService implements ContainerService, return this.platform; } } else { - // don't use container children here, the caller is providing the desired resources + // don't use container children here, the caller is providing the desired resources for (Resource child : parent.getChildResources()) { if (child != null && matches(resource, child)) { return child; @@ -2376,7 +2398,7 @@ public class InventoryManager extends AgentService implements ContainerService, /** * The resource upgrade should only occur during the {@link #initialize()} method and should be * switched off at all other times. - * + * * @return true if resource upgrade is currently active, false otherwise */ public boolean isResourceUpgradeActive() { @@ -2644,6 +2666,21 @@ public class InventoryManager extends AgentService implements ContainerService, return availabilityContext; }
+ /** + * Create inventory context for a resource. + * + * @param resource the resource + * @return the inventory context + */ + private InventoryContext getInventoryContext(Resource resource) { + if (null == resource.getUuid() || resource.getUuid().isEmpty()) { + log.error("RESOURCE UUID IS NOT SET! Inventory features may not work!"); + } + + InventoryContext inventoryContext = new InventoryContextImpl(resource); + return inventoryContext; + } + private void updateResourceVersion(Resource resource, String version) { String existingVersion = resource.getVersion(); boolean versionChanged = (existingVersion != null) ? !existingVersion.equals(version) : version != null; diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java index b6b39e0..4b37c89 100644 --- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java +++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/bundle/BundleManagerTest.java @@ -478,7 +478,7 @@ public class BundleManagerTest { @SuppressWarnings("unchecked") private static class MockResourceContext extends ResourceContext { public MockResourceContext(Resource resource) { - super(resource, null, null, null, null, null, null, null, null, null, null, null, null); + super(resource, null, null, null, null, null, null, null, null, null, null, null, null, null); } } } \ No newline at end of file diff --git a/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java b/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java index 05ebc2f..daf5463 100644 --- a/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java +++ b/modules/plugins/ant-bundle/src/test/java/org/rhq/plugins/ant/AntBundlePluginComponentTest.java @@ -101,7 +101,8 @@ public class AntBundlePluginComponentTest { resource.setUuid(UUID.randomUUID().toString()); @SuppressWarnings({ "rawtypes", "unchecked" }) ResourceContext<?> context = new ResourceContext(resource, null, null, null, - SystemInfoFactory.createJavaSystemInfo(), tmpDir, null, "antBundleTestPC", null, null, null, null, null); + SystemInfoFactory.createJavaSystemInfo(), tmpDir, null, "antBundleTestPC", null, null, null, null, null, + null); this.plugin.start(context); }
diff --git a/modules/plugins/database/src/test/java/org/rhq/plugins/database/ComponentTest.java b/modules/plugins/database/src/test/java/org/rhq/plugins/database/ComponentTest.java index b9622c6..050aa2e 100644 --- a/modules/plugins/database/src/test/java/org/rhq/plugins/database/ComponentTest.java +++ b/modules/plugins/database/src/test/java/org/rhq/plugins/database/ComponentTest.java @@ -52,6 +52,7 @@ import org.rhq.core.pc.availability.AvailabilityContextImpl; import org.rhq.core.pc.content.ContentContextImpl; import org.rhq.core.pc.event.EventContextImpl; import org.rhq.core.pc.event.EventManager; +import org.rhq.core.pc.inventory.InventoryContextImpl; import org.rhq.core.pc.inventory.ResourceContainer; import org.rhq.core.pc.operation.OperationContextImpl; import org.rhq.core.pluginapi.availability.AvailabilityContext; @@ -59,6 +60,7 @@ import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.content.ContentContext; import org.rhq.core.pluginapi.event.EventContext; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; +import org.rhq.core.pluginapi.inventory.InventoryContext; import org.rhq.core.pluginapi.inventory.PluginContainerDeployment; import org.rhq.core.pluginapi.inventory.ProcessScanResult; import org.rhq.core.pluginapi.inventory.ResourceComponent; @@ -141,6 +143,7 @@ public abstract class ComponentTest { private List<ProcessInfo> processInfo = Collections.emptyList(); private PluginDescriptor pluginDescriptor; private AvailabilityContext availabilityContext; + private InventoryContext inventoryContext;
/** @@ -277,11 +280,13 @@ public abstract class ComponentTest { ResourceComponent component = (ResourceComponent) Class.forName(rclassname).newInstance();
availabilityContext = new AvailabilityContextImpl(cresource,availCollectorThreadPool); + inventoryContext = new InventoryContextImpl(cresource); + EventContext eventContext = new EventContextImpl(resource); ResourceContext context = new ResourceContext(cresource, parentComponent, null, rdc, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, eventContext, operationContext, contentContext, - availabilityContext, pluginContainerDeployment); + availabilityContext, inventoryContext, pluginContainerDeployment);
component.start(context); components.put(component, cresource); diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java index 8b85deb..9bc01f2 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java @@ -540,6 +540,7 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend + " server with key [" + context.getResourceKey() + "].");
context.getAvailabilityContext().requestAvailabilityCheck(); + context.getInventoryContext().requestDeferredChildResourcesDiscovery();
return result; } diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java index 8ddb308..28a8688 100644 --- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java +++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/UploadAndDeployTest.java @@ -345,7 +345,8 @@ public class UploadAndDeployTest extends AbstractIntegrationTest { resource.setUuid(UUID.randomUUID().toString()); StandaloneASComponent parentComponent = new StandaloneASComponent(); parentComponent.setConnection(getASConnection()); - ResourceContext context = new ResourceContext(resource,parentComponent,null,null,null,null,null,null,null,null,null,null,null); + ResourceContext context = new ResourceContext(resource, parentComponent, null, null, null, null, null, null, + null, null, null, null, null, null); bc.start(context);
String bytes_value = uploadToAs(TEST_WAR_PATH); @@ -379,7 +380,8 @@ public class UploadAndDeployTest extends AbstractIntegrationTest { resource.setUuid(UUID.randomUUID().toString()); StandaloneASComponent parentComponent = new StandaloneASComponent(); parentComponent.setConnection(getASConnection()); - ResourceContext context = new ResourceContext(resource,parentComponent,null,null,null,null,null,null,null,null,null,null,null); + ResourceContext context = new ResourceContext(resource, parentComponent, null, null, null, null, null, null, + null, null, null, null, null, null); bc.start(context);
String bytes_value = uploadToAs(TEST_WAR_PATH); diff --git a/modules/plugins/mysql/src/test/java/org/rhq/plugins/mysql/ComponentTest.java b/modules/plugins/mysql/src/test/java/org/rhq/plugins/mysql/ComponentTest.java index 511d686..610cb61 100644 --- a/modules/plugins/mysql/src/test/java/org/rhq/plugins/mysql/ComponentTest.java +++ b/modules/plugins/mysql/src/test/java/org/rhq/plugins/mysql/ComponentTest.java @@ -71,6 +71,7 @@ import org.rhq.core.pc.availability.AvailabilityContextImpl; import org.rhq.core.pc.content.ContentContextImpl; import org.rhq.core.pc.event.EventContextImpl; import org.rhq.core.pc.event.EventManager; +import org.rhq.core.pc.inventory.InventoryContextImpl; import org.rhq.core.pc.inventory.ResourceContainer; import org.rhq.core.pc.operation.OperationContextImpl; import org.rhq.core.pluginapi.availability.AvailabilityContext; @@ -78,6 +79,7 @@ import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.content.ContentContext; import org.rhq.core.pluginapi.event.EventContext; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; +import org.rhq.core.pluginapi.inventory.InventoryContext; import org.rhq.core.pluginapi.inventory.PluginContainerDeployment; import org.rhq.core.pluginapi.inventory.ProcessScanResult; import org.rhq.core.pluginapi.inventory.ResourceComponent; @@ -294,12 +296,13 @@ public abstract class ComponentTest { ResourceComponent component = (ResourceComponent) Class.forName(rclassname).newInstance();
AvailabilityContext availContext = new AvailabilityContextImpl(cresource,availCollectorThreadPool); + InventoryContext inventoryContext = new InventoryContextImpl(cresource);
EventContext eventContext = new EventContextImpl(resource); ResourceContext context = new ResourceContext(cresource, parentComponent, null, rdc, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, eventContext, operationContext, contentContext, - availContext, pluginContainerDeployment); + availContext, inventoryContext,pluginContainerDeployment);
component.start(context); components.put(component, cresource); diff --git a/modules/plugins/oracle/src/test/java/org/rhq/plugins/oracle/ComponentTest.java b/modules/plugins/oracle/src/test/java/org/rhq/plugins/oracle/ComponentTest.java index dfee1b6..569bd09 100644 --- a/modules/plugins/oracle/src/test/java/org/rhq/plugins/oracle/ComponentTest.java +++ b/modules/plugins/oracle/src/test/java/org/rhq/plugins/oracle/ComponentTest.java @@ -36,12 +36,14 @@ import org.rhq.core.pc.availability.AvailabilityContextImpl; import org.rhq.core.pc.content.ContentContextImpl; import org.rhq.core.pc.event.EventContextImpl; import org.rhq.core.pc.event.EventManager; +import org.rhq.core.pc.inventory.InventoryContextImpl; import org.rhq.core.pc.operation.OperationContextImpl; import org.rhq.core.pc.upgrade.plugins.multi.base.NothingDiscoveringDiscoveryComponent; import org.rhq.core.pluginapi.availability.AvailabilityContext; import org.rhq.core.pluginapi.content.ContentContext; import org.rhq.core.pluginapi.event.EventContext; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; +import org.rhq.core.pluginapi.inventory.InventoryContext; import org.rhq.core.pluginapi.inventory.PluginContainerDeployment; import org.rhq.core.pluginapi.inventory.ResourceComponent; import org.rhq.core.pluginapi.inventory.ResourceContext; @@ -133,9 +135,11 @@ public abstract class ComponentTest { ResourceDiscoveryComponent resourceDiscoveryComponent = new NothingDiscoveringDiscoveryComponent(); EventContext eventContext = new EventContextImpl(resource); AvailabilityContext availContext = new AvailabilityContextImpl(resource, Executors.newCachedThreadPool()); + InventoryContext inventoryContext = new InventoryContextImpl(resource); ResourceContext context = new ResourceContext(resource, parentResourceComponent, parentResourceContext, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, - eventContext, operationContext, contentContext, availContext, pluginContainerDeployment); + eventContext, operationContext, contentContext, availContext, inventoryContext, + pluginContainerDeployment); component.start(context);
resourceDiscoveryContext = new ResourceDiscoveryContext(resourceType, parentResourceComponent, context, @@ -169,9 +173,10 @@ public abstract class ComponentTest {
EventContext eventContext = new EventContextImpl(resource); AvailabilityContext availContext = new AvailabilityContextImpl(resource, Executors.newCachedThreadPool()); + InventoryContext inventoryContext = new InventoryContextImpl(resource); ResourceContext context = new ResourceContext(resource, component, parentContext, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, eventContext, operationContext, - contentContext, availContext, pluginContainerDeployment); + contentContext, availContext, inventoryContext, pluginContainerDeployment); ResourceDiscoveryContext resourceDiscoveryContext = new ResourceDiscoveryContext(resourceType, component, context, systemInfo, Collections.emptyList(), Collections.emptyList(), pluginContainerName, pluginContainerDeployment); @@ -200,9 +205,10 @@ public abstract class ComponentTest {
EventContext eventContext = new EventContextImpl(resource); AvailabilityContext availContext = new AvailabilityContextImpl(resource, Executors.newCachedThreadPool()); + InventoryContext inventoryContext = new InventoryContextImpl(resource); ResourceContext context = new ResourceContext(cresource, parentComponent, parentContext, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, - eventContext, operationContext, contentContext, availContext, pluginContainerDeployment); + eventContext, operationContext, contentContext, availContext, inventoryContext, pluginContainerDeployment);
component.start(context); components.put(component, cresource); diff --git a/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java b/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java index b023609..cd90737 100644 --- a/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java +++ b/modules/plugins/snmptrapd/src/test/java/org/rhq/plugins/snmptrapd/ComponentTest.java @@ -24,11 +24,13 @@ import org.rhq.core.pc.availability.AvailabilityContextImpl; import org.rhq.core.pc.content.ContentContextImpl; import org.rhq.core.pc.event.EventContextImpl; import org.rhq.core.pc.event.EventManager; +import org.rhq.core.pc.inventory.InventoryContextImpl; import org.rhq.core.pc.operation.OperationContextImpl; import org.rhq.core.pc.upgrade.plugins.multi.base.NothingDiscoveringDiscoveryComponent; import org.rhq.core.pluginapi.availability.AvailabilityContext; import org.rhq.core.pluginapi.content.ContentContext; import org.rhq.core.pluginapi.event.EventContext; +import org.rhq.core.pluginapi.inventory.InventoryContext; import org.rhq.core.pluginapi.inventory.PluginContainerDeployment; import org.rhq.core.pluginapi.inventory.ResourceComponent; import org.rhq.core.pluginapi.inventory.ResourceContext; @@ -97,9 +99,10 @@ public abstract class ComponentTest { ContentContext contentContext = new ContentContextImpl(0); PluginContainerDeployment pluginContainerDeployment = null; AvailabilityContext availContext = new AvailabilityContextImpl(resource, Executors.newCachedThreadPool()); + InventoryContext inventoryContext = new InventoryContextImpl(resource); ResourceContext context = new ResourceContext(resource, parentResourceComponent, parentResourceContext, resourceDiscoveryComponent, systemInfo, temporaryDirectory, dataDirectory, pluginContainerName, - eventContext, operationContext, contentContext, availContext, pluginContainerDeployment); + eventContext, operationContext, contentContext, availContext, inventoryContext, pluginContainerDeployment); Assert.assertNotNull(context.getEventContext()); component.start(context); }
commit 579776f3fe66776d0b013bf13eba8114fe7ff89a Author: Mike Thompson mithomps@redhat.com Date: Thu Aug 9 13:53:35 2012 -0700
Remove unused parameter. Ended up not needing the criteria parameter.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java index 9f640dc..e269475 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java @@ -26,7 +26,6 @@ import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGro import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.PLUGIN; import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.TYPE;
-import java.util.ArrayList; import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback; @@ -126,8 +125,7 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou processResponse(request.getRequestId(), response); }
- private PageList<ResourceGroupComposite> filterEmptyMemberGroups(ResourceGroupCriteria groupCriteria, - PageList<ResourceGroupComposite> result){ + private PageList<ResourceGroupComposite> filterEmptyMemberGroups(PageList<ResourceGroupComposite> result){
PageList<ResourceGroupComposite> pageList = new PageList<ResourceGroupComposite>(result.getPageControl());
@@ -141,7 +139,7 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou }
public void onSuccess(PageList<ResourceGroupComposite> result) { - PageList<ResourceGroupComposite> filteredResult = filterEmptyMemberGroups(criteria,result); + PageList<ResourceGroupComposite> filteredResult = filterEmptyMemberGroups(result); response.setData(buildRecords(filteredResult)); response.setTotalRows(filteredResult.getTotalSize()); // for paging to work we have to specify size of full result set processResponse(request.getRequestId(), response);
commit 901fc3d0ecb9b5f800c6c5c3dc59dabebb61a87c Author: Mike Thompson mithomps@redhat.com Date: Wed Aug 8 17:33:53 2012 -0700
Take out search optimization of not doing a search if the search term is the same as the last search. This is causing some stickiness and sometimes the search doesnt run if it was already cached and it thinks it has done a search but it hasnt (probably because of timing issues).
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java index f56c81e..e0e004d 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/searchbar/BasicSearchStrategy.java @@ -48,7 +48,6 @@ import org.rhq.enterprise.gui.coregui.client.util.message.Message; */ public class BasicSearchStrategy extends AbstractSearchStrategy {
- private String lastExpression;
public BasicSearchStrategy(EnhancedSearchBar searchBar) { super(searchBar); @@ -175,12 +174,9 @@ public class BasicSearchStrategy extends AbstractSearchStrategy { private void getTabAwareSearchSuggestions(final SearchSubsystem searchSubsystem, final String expression, int caretPosition) {
- if (null != expression && expression.equals(lastExpression)) { - // short-circuit if we dont really need to do a search - Log.debug("search tab aware Suggestions: ignoring duplicate search for: " + expression); + if(null == expression || expression.isEmpty()){ return; } - lastExpression = expression;
final long suggestStart = System.currentTimeMillis();
commit 6b621264526d1490d423e14e482ff18b3ea2f85f Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Aug 10 09:24:26 2012 -0400
[Bug 847138 - RFE: Add indication that resource tree is loading or expanding] Replace the default TreeGrid loading message, which was weak and only showed up briefly at initial tree creation, with more robust loading... message display when loading, expanding or updating the tree. This helps situations where fairly large tree load/updates take place, typically due to large numbers of siblings or Autogroup creation/manipulation.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java index 2a5b827..5c58a70 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java @@ -35,6 +35,7 @@ import com.smartgwt.client.data.fields.DataSourceTextField; import com.smartgwt.client.rpc.RPCResponse; import com.smartgwt.client.types.DSDataFormat; import com.smartgwt.client.types.DSProtocol; +import com.smartgwt.client.widgets.Label; import com.smartgwt.client.widgets.tree.Tree; import com.smartgwt.client.widgets.tree.TreeGrid; import com.smartgwt.client.widgets.tree.TreeNode; @@ -71,10 +72,12 @@ public class ResourceTreeDatasource extends DataSource { // the encompassing grid. It's unfortunate to have the DS know about the encompassing TreeGrid // but we have a situation in which a new AG node needs to be able to access its parent TreeNode by ID. private TreeGrid treeGrid; + private Label loadingLabel;
private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
- public ResourceTreeDatasource(List<Resource> initialData, List<Resource> lockedData, TreeGrid treeGrid) { + public ResourceTreeDatasource(List<Resource> initialData, List<Resource> lockedData, TreeGrid treeGrid, + Label loadingLabel) { this.setClientOnly(false); this.setDataProtocol(DSProtocol.CLIENTCUSTOM); this.setDataFormat(DSDataFormat.CUSTOM); @@ -82,6 +85,7 @@ public class ResourceTreeDatasource extends DataSource { this.initialData = initialData; this.lockedData = (null != lockedData) ? lockedData : new ArrayList<Resource>(); this.treeGrid = treeGrid; + this.loadingLabel = loadingLabel;
DataSourceField idDataField = new DataSourceTextField("id", MSG.common_title_id()); idDataField.setPrimaryKey(true); @@ -131,6 +135,8 @@ public class ResourceTreeDatasource extends DataSource { public void executeFetch(final String requestId, final DSRequest request, final DSResponse response) { //final long start = System.currentTimeMillis();
+ loadingLabel.show(); + final String parentResourceId = request.getCriteria().getAttribute("parentId"); //com.allen_sauer.gwt.log.client.Log.info("All attributes: " + Arrays.toString(request.getCriteria().getAttributes()));
@@ -148,6 +154,8 @@ public class ResourceTreeDatasource extends DataSource { processResponse(requestId, response); }
+ loadingLabel.hide(); + } else { Log.debug("ResourceTreeDatasource: Loading Resource [" + parentResourceId + "]...");
@@ -161,6 +169,8 @@ public class ResourceTreeDatasource extends DataSource { CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_children(), caught); response.setStatus(RPCResponse.STATUS_FAILURE); processResponse(requestId, response); + + loadingLabel.hide(); }
public void onSuccess(PageList<Resource> result) { @@ -182,6 +192,8 @@ public class ResourceTreeDatasource extends DataSource { TreeNode[] treeNodes = buildNodes(result, lockedData, treeGrid); response.setData(treeNodes); processResponse(requestId, response); + + loadingLabel.hide(); } }); } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java index 2393f8d..c38e77a 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java @@ -43,6 +43,7 @@ import com.smartgwt.client.data.DSCallback; import com.smartgwt.client.data.DSRequest; import com.smartgwt.client.data.DSResponse; import com.smartgwt.client.types.SelectionStyle; +import com.smartgwt.client.widgets.Label; import com.smartgwt.client.widgets.grid.ListGridRecord; import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler; import com.smartgwt.client.widgets.grid.events.SelectionEvent; @@ -79,6 +80,7 @@ import org.rhq.core.domain.resource.composite.ResourcePermission; import org.rhq.core.domain.resource.group.ResourceGroup; import org.rhq.core.domain.util.PageList; import org.rhq.enterprise.gui.coregui.client.CoreGUI; +import org.rhq.enterprise.gui.coregui.client.ImageManager; import org.rhq.enterprise.gui.coregui.client.LinkManager; import org.rhq.enterprise.gui.coregui.client.UserSessionManager; import org.rhq.enterprise.gui.coregui.client.ViewId; @@ -111,6 +113,7 @@ public class ResourceTreeView extends LocatableVLayout {
private TreeGrid treeGrid; private String selectedNodeId; + private Label loadingLabel;
private Resource rootResource;
@@ -131,11 +134,17 @@ public class ResourceTreeView extends LocatableVLayout {
@Override public void onInit() { + // manually handle a loading... message at initial load and also subsequent fetches + loadingLabel = new Label(MSG.common_msg_loading()); + loadingLabel.setIcon(ImageManager.getLoadingIcon()); + loadingLabel.setHeight(20); + loadingLabel.hide(); + addMember(loadingLabel); + // TODO (ips): Are we intentionally avoiding calling super.onInit() here? If so, why? }
private void buildTree() { - treeGrid = new CustomResourceTreeGrid(getLocatorId());
treeGrid.setOpenerImage("resources/dir.png"); @@ -149,6 +158,8 @@ public class ResourceTreeView extends LocatableVLayout { treeGrid.setShowRollOver(false); treeGrid.setSortField("name"); treeGrid.setShowHeader(false); + // disable what the tree grid may do, defer to loadingLabel to handle all of our cases + treeGrid.setLoadingDataMessage(null);
treeGrid.setLeaveScrollbarGap(false);
@@ -190,12 +201,15 @@ public class ResourceTreeView extends LocatableVLayout { disable();
try { + loadingLabel.show(); getAutoGroupBackingGroup(agNode, new AsyncCallback<ResourceGroup>() { public void onSuccess(ResourceGroup result) { + loadingLabel.hide(); renderAutoGroup(result); }
public void onFailure(Throwable caught) { + loadingLabel.hide(); // Make sure to re-enable ourselves. enable(); CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_selection(), @@ -203,6 +217,7 @@ public class ResourceTreeView extends LocatableVLayout { } }); } catch (RuntimeException re) { + loadingLabel.hide(); // Make sure to re-enable ourselves. enable(); CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_selection(), re); @@ -281,9 +296,11 @@ public class ResourceTreeView extends LocatableVLayout { criteria.addFilterResourceTypeId(agNode.getResourceType().getId()); criteria.addFilterAutoGroupParentResourceId(agNode.getParentResource().getId()); criteria.addFilterVisible(false); + loadingLabel.show(); resourceGroupService.findResourceGroupsByCriteria(criteria, new AsyncCallback<PageList<ResourceGroup>>() {
public void onFailure(Throwable caught) { + loadingLabel.hide(); callback.onFailure(new RuntimeException(MSG.view_tree_common_loadFailed_node(), caught)); }
@@ -299,11 +316,13 @@ public class ResourceTreeView extends LocatableVLayout { resourceGroupService.createPrivateResourceGroup(backingGroup, childIds, new AsyncCallback<ResourceGroup>() { public void onFailure(Throwable caught) { + loadingLabel.hide(); callback.onFailure(new RuntimeException(MSG.view_tree_common_loadFailed_create(), caught)); }
public void onSuccess(ResourceGroup result) { + loadingLabel.hide(); // store a map entry from backingGroupId to AGTreeNode so we can easily // get back to this node given the id of the backing group (from the viewpath) autoGroupNodeMap.put(result.getId(), agNode); @@ -322,11 +341,13 @@ public class ResourceTreeView extends LocatableVLayout { resourceGroupService.setAssignedResources(backingGroup.getId(), childIds, false, new AsyncCallback<Void>() { public void onFailure(Throwable caught) { + loadingLabel.hide(); callback.onFailure(new RuntimeException(MSG.view_tree_common_loadFailed_update(), caught)); }
public void onSuccess(Void result) { + loadingLabel.hide(); callback.onSuccess(backingGroup); } }); @@ -895,7 +916,6 @@ public class ResourceTreeView extends LocatableVLayout { // This is the case where the tree was previously loaded and we get fired to look at a different // node in the same tree and just have to switch the selection updateSelection(isRefresh); - } else { // This is for cases where we have to load the tree fresh including down to the currently visible node loadTree(selectedResourceId, true, null); @@ -913,10 +933,12 @@ public class ResourceTreeView extends LocatableVLayout { final ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
// This is an expensive call, but loads all nodes that are visible in the tree given a selected resource + loadingLabel.show(); resourceService.getResourceLineageAndSiblings(selectedResourceId, new AsyncCallback<List<ResourceLineageComposite>>() {
public void onFailure(Throwable caught) { + loadingLabel.hide(); boolean resourceDoesNotExist = caught.getMessage().contains("ResourceNotFoundException"); // If a Resource with the specified id does not exist, don't emit an error, since // ResourceDetailView.loadSelectedItem() will take care of emitting one. @@ -953,7 +975,8 @@ public class ResourceTreeView extends LocatableVLayout { setRootResource(root);
// seed datasource with initial resource list and which ancestor resources are locked - ResourceTreeDatasource dataSource = new ResourceTreeDatasource(lineage, lockedData, treeGrid); + ResourceTreeDatasource dataSource = new ResourceTreeDatasource(lineage, lockedData, treeGrid, + loadingLabel); treeGrid.setDataSource(dataSource);
addMember(treeGrid); @@ -963,6 +986,8 @@ public class ResourceTreeView extends LocatableVLayout { public void execute(DSResponse response, Object rawData, DSRequest request) { Log.info("Done fetching data for tree.");
+ loadingLabel.hide(); + if (updateSelection) { updateSelection(); } @@ -994,6 +1019,8 @@ public class ResourceTreeView extends LocatableVLayout { treeGrid.getTree().linkNodes( ResourceTreeDatasource.buildNodes(lineage, lockedData, treeGrid));
+ loadingLabel.hide(); + TreeNode selectedNode = treeGrid.getTree().findById(selectedNodeId); if (selectedNode != null && updateSelection) { updateSelection(); @@ -1029,9 +1056,11 @@ public class ResourceTreeView extends LocatableVLayout { criteria.addFilterId(selectedAutoGroupId); criteria.addFilterVisible(false); criteria.fetchResourceType(true); + loadingLabel.show(); resourceGroupService.findResourceGroupsByCriteria(criteria, new AsyncCallback<PageList<ResourceGroup>>() {
public void onFailure(Throwable caught) { + loadingLabel.hide(); CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_node(), caught); }
@@ -1043,6 +1072,7 @@ public class ResourceTreeView extends LocatableVLayout { loadTree(backingGroup.getAutoGroupParentResource().getId(), false, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) { + loadingLabel.hide(); CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_children(), caught); }
@@ -1053,6 +1083,8 @@ public class ResourceTreeView extends LocatableVLayout { AutoGroupTreeNode agNode = (AutoGroupTreeNode) treeGrid.getTree().findById(selectedNodeId); autoGroupNodeMap.put(backingGroup.getId(), agNode); updateSelection(); + + loadingLabel.hide(); } }); } @@ -1061,7 +1093,6 @@ public class ResourceTreeView extends LocatableVLayout { }
public void renderView(ViewPath viewPath) { - ViewId currentViewId = viewPath.getCurrent(); String currentViewIdPath = currentViewId.getPath(); if ("AutoGroup".equals(currentViewIdPath)) {
commit 23b39b07ef79025500b063dd223dc243e12c5004 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Aug 10 09:20:16 2012 -0400
Get rid of annoying maven warning by specifying to use the latest release version.
diff --git a/pom.xml b/pom.xml index 0ae9a07..36b9c62 100644 --- a/pom.xml +++ b/pom.xml @@ -1317,6 +1317,7 @@ <plugin> <groupId>com.googlecode.maven-overview-plugin</groupId> <artifactId>maven-overview-plugin</artifactId> + <version>RELEASE</version> </plugin>
<!--
commit 71dc21ab49b1a986e4364e52e0fa6f817c96bf89 Author: Heiko W. Rupp hwr@redhat.com Date: Thu Aug 9 16:09:41 2012 -0400
BZ 838670 Mark more configuration elements as r/w, as underyling AS allows that now.
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 6a6a40c..d27d432 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 @@ -397,33 +397,34 @@
<!ENTITY datasourceReadWriteConfiguration ' <resource-configuration> - <c:simple-property name="connection-url" required="true" type="string" readOnly="true" description="The JDBC driver connection URL"/> - <c:simple-property name="driver-name" required="true" type="string" description="Name of the (existing) JDBC driver to use" readOnly="true"> + <c:simple-property name="connection-url" required="true" type="string" readOnly="false" description="The JDBC driver connection URL"/> + <c:simple-property name="driver-name" required="true" type="string" description="Name of the (existing) JDBC driver to use" readOnly="false"> <c:option-source target="resource" expression="type=^Deployment$" filter=".*.jar"/> </c:simple-property> - <c:simple-property name="driver-class" required="false" type="string" readOnly="true" description="The fully qualified name of the JDBC driver class"/> - <c:simple-property name="jndi-name" required="true" type="string" readOnly="true" description="Specifies the JNDI name for the datasource"/> + <c:simple-property name="driver-class" required="false" type="string" readOnly="false" description="The fully qualified name of the JDBC driver class"/> + <c:simple-property name="jndi-name" required="true" type="string" readOnly="false" description="Specifies the JNDI name for the datasource"/> <c:simple-property name="driver" required="false" type="string" readOnly="true" description="Defines the JDBC driver the datasource should use with this format: driver-name>#major-version.minor-version where driver-name is the fully qualified name of the JDBC driver class"/> - <c:simple-property name="user-name" type="string" readOnly="true" required="false" description="Specify the username used when creating a new connection."/> - <c:simple-property name="password" type="password" readOnly="true" required="false" description="Specify the password used when creating a new connection."/> - <c:simple-property name="new-connection-sql" type="string" readOnly="true" required="false" description="Specifies an SQL statement to execute whenever a connection is added to the connection pool."/> - <c:simple-property name="url-delimiter" type="string" readOnly="true" description="Specifies the delimiter for URLs in connection-url for HA datasources" required="false"/> - <c:simple-property name="url-selector-strategy-class-name" type="string" readOnly="true" description="A class that implements org.jboss.jca.adapters.jdbc.URLSelectorStrategy" required="false"/> - <c:simple-property name="use-java-context" type="boolean" readOnly="true" required="false" description="Setting this to false will bind the DataSource into global JNDI;"/> + <c:simple-property name="user-name" type="string" readOnly="false" required="false" description="Specify the username used when creating a new connection."/> + <c:simple-property name="password" type="password" readOnly="false" required="false" description="Specify the password used when creating a new connection."/> + <c:simple-property name="new-connection-sql" type="string" readOnly="false" required="false" description="Specifies an SQL statement to execute whenever a connection is added to the connection pool."/> + <c:simple-property name="url-delimiter" type="string" readOnly="false" description="Specifies the delimiter for URLs in connection-url for HA datasources" required="false"/> + <c:simple-property name="url-selector-strategy-class-name" type="string" readOnly="false" description="A class that implements org.jboss.jca.adapters.jdbc.URLSelectorStrategy" required="false"/> + <c:simple-property name="use-java-context" type="boolean" readOnly="false" required="false" default="true" description="Setting this to false will bind the DataSource into global JNDI;"/> <c:simple-property name="enabled" type="boolean" readOnly="true" required="false" description="Specifies if the datasource should be enabled"/> + <c:simple-property name="jta" type="boolean" readOnly="false" required="false" default="true" description="Enable JTA integration"/> <c:simple-property name="max-pool-size" type="integer" readOnly="false" required="false" description="The max-pool-size element indicates the maximum number of connections for a pool. No more connections will be created in each sub-pool."/> <c:simple-property name="min-pool-size" type="integer" readOnly="false" required="false" description="The min-pool-size element indicates the minimum number of connections a pool should hold. These are not created until a Subject is known from a request for a connection."/> - <c:simple-property name="pool-prefill" type="boolean" readOnly="false" required="false" description="Whether to attempt to prefill the connection pool. Changing this value require a server restart."/> - <c:simple-property name="pool-use-strict-min" type="boolean" readOnly="false" required="false" description="Define if the min-pool-size should be considered a strictly."/> - <c:simple-property name="security-domain" required="false" type="string" readOnly="true" description="Indicates Subject (from security domain) are used to distinguish connections in the pool. The content of the security-domain is the name of the JAAS security manager that will handleauthentication. This name correlates to the JAAS login-config.xml descriptor application-policy/name attribute."/> - <c:simple-property name="reauth-plugin-class-name" required="false" type="string" readOnly="true" description="re-authentication plugin implementation provided for specific purpose (i.e vendor)"/> + <c:simple-property name="pool-prefill" type="boolean" readOnly="false" required="false" default="false" description="Whether to attempt to prefill the connection pool. Changing this value require a server restart."/> + <c:simple-property name="pool-use-strict-min" type="boolean" readOnly="false" required="false" default="false" description="Define if the min-pool-size should be considered a strictly."/> + <c:simple-property name="security-domain" required="false" type="string" readOnly="false" description="Indicates Subject (from security domain) are used to distinguish connections in the pool. The content of the security-domain is the name of the JAAS security manager that will handleauthentication. This name correlates to the JAAS login-config.xml descriptor application-policy/name attribute."/> + <c:simple-property name="reauth-plugin-class-name" required="false" type="string" readOnly="false" description="re-authentication plugin implementation provided for specific purpose (i.e vendor)"/> <!-- <c:map-property name="reauth-plugin-properties" description="properties for reauthentication plugin passed to the implementation provided for specific purpose (i.e vendor)"> read-only configuration </c:map-property> --> - <c:simple-property name="flush-strategy" required="false" type="string" readOnly="true" description="Specifies how the pool should be flush in case of an error." default="FailingConnectionOnly" defaultValue="FailingConnectionOnly"> + <c:simple-property name="flush-strategy" required="false" type="string" readOnly="false" description="Specifies how the pool should be flush in case of an error." default="FailingConnectionOnly" defaultValue="FailingConnectionOnly"> <c:property-options> <c:option value="FailingConnectionOnly"/> <c:option value="IdleConnections"/> @@ -431,17 +432,24 @@ </c:property-options> </c:simple-property>
- <c:simple-property name="prepared-statements-cacheSize" type="long" readOnly="true" required="false" description="The number of prepared statements per connection in an LRU cache"/> - <c:simple-property name="share-prepared-statements" type="boolean" readOnly="true" required="false" description="Whether to share prepare statements, i.e. whether asking for same statement twice without closing uses the same underlying prepared statement"/> - <c:simple-property name="track-statements" type="string" readOnly="true" required="false" description="Whether to check for unclosed statements when a connection is returned to the pool and result sets are closed when a statement is closed/return to the prepared statement cache. valid values are: false - do not track statements and results true - track statements and result sets and warn when they are not closed nowarn - track statements but do no warn about them being unclosed"/> - <c:simple-property name="allocation-retry" type="integer" readOnly="true" required="false" description="The allocation retry element indicates the number of times that allocating a connection should be tried before throwing an exception."/> - <c:simple-property name="allocation-retry-wait-millis" type="long" readOnly="true" required="false" description="Indicates the time in milliseconds to wait between retrying to allocate a connection."/> + <c:simple-property name="allow-multiple-users" type="boolean" required="false" readOnly="false" description="Specifies if multiple users will access the datasource through the getConnection(user, password) method and hence if the internal pool type should account for that"/> + <c:simple-property name="prepared-statements-cacheSize" type="long" readOnly="false" required="false" description="The number of prepared statements per connection in an LRU cache"/> + <c:simple-property name="share-prepared-statements" type="boolean" readOnly="false" required="false" default="false" description="Whether to share prepare statements, i.e. whether asking for same statement twice without closing uses the same underlying prepared statement"/> + <c:simple-property name="track-statements" type="string" readOnly="false" required="false" description="Whether to check for unclosed statements when a connection is returned to the pool and result sets are closed when a statement is closed/return to the prepared statement cache. valid values are: false - do not track statements and results true - track statements and result sets and warn when they are not closed nowarn - track statements but do no warn about them being unclosed"> + <c:property-options> + <c:option value="false"/> + <c:option value="true"/> + <c:option value="NOWARN"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="allocation-retry" type="integer" readOnly="false" required="false" description="The allocation retry element indicates the number of times that allocating a connection should be tried before throwing an exception."/> + <c:simple-property name="allocation-retry-wait-millis" type="long" readOnly="false" required="false" description="Indicates the time in milliseconds to wait between retrying to allocate a connection."/> <c:simple-property name="blocking-timeout-wait-millis" type="long" readOnly="false" required="false" description="The blocking-timeout-millis element indicates the maximum time in milliseconds to block while waiting for a connection before throwing an exception. Note that this blocks only while waiting for a permit for a connection, and will never throw an exception if creating a new connection takes an inordinately long time."/> <c:simple-property name="idle-timeout-minutes" type="long" readOnly="false" required="false" description="The idle-timeout-minutes elements indicates 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 1/2 the smallest idle-timeout-minutes of any pool. Changing this value require a server restart."/> - <c:simple-property name="query-timeout" type="long" readOnly="true" required="false" description="Any configured query timeout in seconds The default is no timeout"/> - <c:simple-property name="use-try-lock" type="long" readOnly="true" required="false" description="Any configured timeout for internal locks on the resource adapter objects in seconds"/> - <c:simple-property name="set-tx-query-timeout" type="boolean" readOnly="true" required="false" description="Whether to set the query timeout based on the time remaining until transaction timeout, any configured query timeout will be used if there is no transaction."/> - <c:simple-property name="transaction-isolation" type="string" readOnly="true" required="false" description="Set java.sql.Connection transaction isolation level to use. The constants defined by transaction-isolation-values are the possible transaction isolation levels."> + <c:simple-property name="query-timeout" type="long" readOnly="false" required="false" description="Any configured query timeout in seconds The default is no timeout"/> + <c:simple-property name="use-try-lock" type="long" readOnly="false" required="false" description="Any configured timeout for internal locks on the resource adapter objects in seconds"/> + <c:simple-property name="set-tx-query-timeout" type="boolean" readOnly="false" required="false" default="false" description="Whether to set the query timeout based on the time remaining until transaction timeout, any configured query timeout will be used if there is no transaction."/> + <c:simple-property name="transaction-isolation" type="string" readOnly="false" required="false" description="Set java.sql.Connection transaction isolation level to use. The constants defined by transaction-isolation-values are the possible transaction isolation levels."> <c:property-options> <c:option value="TRANSACTION_READ_UNCOMMITTED"/> <c:option value="TRANSACTION_READ_COMMITTED"/> @@ -450,16 +458,16 @@ <c:option value="TRANSACTION_NONE"/> </c:property-options> </c:simple-property> - <c:simple-property name="check-valid-connection-sql" type="string" readOnly="true" required="false" description="Specify an SQL statement to check validity of a pool connection. This may be called when managed connection is taken from pool for use."/> - <c:simple-property name="exception-sorter-class-name" type="string" readOnly="true" required="false" description="An org.jboss.jca.adapters.jdbc.ExceptionSorter that provides a boolean isExceptionFatal(SQLException e) method to validate is an exception should be broadcast to all javax.resource.spi.ConnectionEventListener as a connectionErrorOccurred"/> - <c:simple-property name="stale-connection-checker-class-name" type="string" readOnly="true" required="false" description="An org.jboss.jca.adapters.jdbc.StaleConnectionChecker that provides a boolean isStaleConnection(SQLException e) method which if it it returns true will wrap the exception in an org.jboss.jca.adapters.jdbc.StaleConnectionException"/> - <c:simple-property name="valid-connection-checker-class-name" type="string" readOnly="true" required="false" description="An org.jboss.jca.adapters.jdbc.ValidConnectionChecker that provides a SQLException isValidConnection(Connection e) method to validate is a connection is valid. An exception means the connection is destroyed. This overrides the check-valid-connection-sql when present."/> - <c:simple-property name="background-validation-minutes" type="long" readOnly="false" required="false" description="The background-validation-minutes element specifies the amount of time, in minutes, that background validation will run. Changing this value require a server restart."/> - <c:simple-property name="background-validation" type="boolean" readOnly="false" required="false" description="An element to specify that connections should be validated on a background thread versus being validated prior to use. Changing this value require a server restart."/> + <c:simple-property name="check-valid-connection-sql" type="string" readOnly="false" required="false" description="Specify an SQL statement to check validity of a pool connection. This may be called when managed connection is taken from pool for use."/> + <c:simple-property name="exception-sorter-class-name" type="string" readOnly="false" required="false" description="An org.jboss.jca.adapters.jdbc.ExceptionSorter that provides a boolean isExceptionFatal(SQLException e) method to validate is an exception should be broadcast to all javax.resource.spi.ConnectionEventListener as a connectionErrorOccurred"/> + <c:simple-property name="stale-connection-checker-class-name" type="string" readOnly="false" required="false" description="An org.jboss.jca.adapters.jdbc.StaleConnectionChecker that provides a boolean isStaleConnection(SQLException e) method which if it it returns true will wrap the exception in an org.jboss.jca.adapters.jdbc.StaleConnectionException"/> + <c:simple-property name="valid-connection-checker-class-name" type="string" readOnly="false" required="false" description="An org.jboss.jca.adapters.jdbc.ValidConnectionChecker that provides a SQLException isValidConnection(Connection e) method to validate is a connection is valid. An exception means the connection is destroyed. This overrides the check-valid-connection-sql when present."/> + <c:simple-property name="background-validation-millis" type="long" readOnly="false" required="false" description="The background-validation-minutes element specifies the amount of time, in minutes, that background validation will run. Changing this value require a server restart."/> + <c:simple-property name="background-validation" type="boolean" readOnly="false" required="false" default="false" description="An element to specify that connections should be validated on a background thread versus being validated prior to use. Changing this value require a server restart."/> <c:simple-property name="use-fast-fail" type="boolean" readOnly="false" required="false" description="Whether fail a connection allocation on the first connection if it is invalid (true) or keep trying until the pool is exhausted of all potential connections (false)"/> - <c:simple-property name="validate-on-match" type="boolean" readOnly="true" required="false" description="The validate-on-match element indicates whether or not connection level validation should be done when a connection factory attempts to match a managed connection for a given set. This is typically exclusive to the use of background validation"/> - <c:simple-property name="spy" type="boolean" readOnly="true" required="false" description="whatever spy or not the jdbc connection"/> - <c:simple-property name="use-ccm" type="boolean" readOnly="true" required="false" description="Enable the use of a cached connection manager"/> + <c:simple-property name="validate-on-match" type="boolean" readOnly="false" required="false" default="false" description="The validate-on-match element indicates whether or not connection level validation should be done when a connection factory attempts to match a managed connection for a given set. This is typically exclusive to the use of background validation"/> + <c:simple-property name="spy" type="boolean" readOnly="false" required="false" defaultValue="false" description="whatever spy or not the jdbc connection"/> + <c:simple-property name="use-ccm" type="boolean" readOnly="false" required="false" description="Enable the use of a cached connection manager"/> <c:group name="children:connection-properties:pname+-" displayName="Connection Properties"> <c:list-property name="*1" displayName="Connection Property" readOnly="false" required="false"> <c:map-property name="*:pname" displayName="Name" readOnly="false">
commit 77cee38075da30754fa6081dcf5cfe239f547a71 Author: Heiko W. Rupp hwr@redhat.com Date: Thu Aug 9 14:20:52 2012 -0400
BZ 839320 When a property is required and the user has not explicitly choosen a value and there is a defaultValue, use this.
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java index 366f840..86ba37a 100644 --- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java +++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ConfigurationWriteDelegate.java @@ -500,7 +500,25 @@ public class ConfigurationWriteDelegate implements ConfigurationFacet { entry = new SimpleEntry<String, Object>(realName, null); } } else { - Object o = getObjectWithType(propertyDefinition,property.getStringValue()); + Object o; +/* + If no value is given in the property and the property is required, + we'll take the default value from the definition. This can e.g. happen + when you have + <c:simple-property name="mode" required="true" type="string" readOnly="false" default="SYNC" defaultValue="SYNC"> + <c:property-options> + <c:option value="SYNC"/> + <c:option value="ASYNC"/> + </c:property-options> + </c:simple-property> + and the user chooses to just keep the default choice in the ui +*/ + + if (property.getStringValue()==null && propertyDefinition.isRequired()) { + o = getObjectWithType(propertyDefinition,propertyDefinition.getDefaultValue()); + } else { + o = getObjectWithType(propertyDefinition,property.getStringValue()); + } entry = new SimpleEntry<String, Object>(name, o); }
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 77bacfb..6a6a40c 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 @@ -11350,7 +11350,7 @@ </c:property-options> </c:simple-property> <c:simple-property name="jndi-name" required="false" type="string" readOnly="false" description="The jndi-name to which to bind this cache instance."/> - <c:simple-property name="mode" required="true" type="string" readOnly="false" default="SYNC" description="Sets the clustered cache mode, ASYNC for asynchronous operation, or SYNC for synchronous operation."> + <c:simple-property name="mode" required="true" type="string" readOnly="false" default="SYNC" defaultValue="SYNC" description="Sets the clustered cache mode, ASYNC for asynchronous operation, or SYNC for synchronous operation."> <c:property-options> <c:option value="SYNC"/> <c:option value="ASYNC"/> diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java index ba2f13c..21e3d5f 100644 --- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java +++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/ConfigurationUpdatingTest.java @@ -862,4 +862,90 @@ public class ConfigurationUpdatingTest extends AbstractConfigurationHandlingTest assert cop.numberOfSteps() == 1 : "One step was expected, but got " + cop.numberOfSteps();
} + + /** + * Test that if a property is required and has a defaultValue and the user just uses this, + * we actually pass this default to the operation, as e.g. the CreateResourceReport may not + * include the default value. + * @throws Exception If anything goes wrong + */ + public void testSimpleWithDefault1() throws Exception { + + ConfigurationDefinition definition = loadDescriptor("simpleWithDefault1"); + + FakeConnection connection = new FakeConnection(); + + ConfigurationWriteDelegate delegate = new ConfigurationWriteDelegate(definition, connection, null); + + Configuration conf = new Configuration(); + PropertySimple ps = new PropertySimple("mode",null); + conf.put(ps); + + CompositeOperation cop = delegate.updateGenerateOperationFromProperties(conf, new Address()); + + assert cop.numberOfSteps() == 1; + Operation step1 = cop.step(0); + assert step1.getOperation().equals("write-attribute"); + Map<String, Object> props = step1.getAdditionalProperties(); + assert props.size() == 2; + assert props.get("name").equals("mode"); + assert props.get("value").equals("SYNC"); // the defaultValue + } + + /** + * Check that if a property is required and has no defaultValue, but the user provides a value, + * that the user provided value ends up in the operation + * @throws Exception + */ + public void testSimpleWithDefault2() throws Exception { + + ConfigurationDefinition definition = loadDescriptor("simpleWithDefault2"); + + FakeConnection connection = new FakeConnection(); + + ConfigurationWriteDelegate delegate = new ConfigurationWriteDelegate(definition, connection, null); + + Configuration conf = new Configuration(); + PropertySimple ps = new PropertySimple("mode","ASYNC"); + conf.put(ps); + + CompositeOperation cop = delegate.updateGenerateOperationFromProperties(conf, new Address()); + + assert cop.numberOfSteps() == 1; + Operation step1 = cop.step(0); + assert step1.getOperation().equals("write-attribute"); + Map<String, Object> props = step1.getAdditionalProperties(); + assert props.size() == 2; + assert props.get("name").equals("mode"); + assert props.get("value").equals("ASYNC"); // the user provided value + } + + /** + * Check that if a property is required and has no defaultValue, and the user provides null + * as value, that we set null + * @throws Exception + */ + public void testSimpleWithDefault3() throws Exception { + + ConfigurationDefinition definition = loadDescriptor("simpleWithDefault2"); + + FakeConnection connection = new FakeConnection(); + + ConfigurationWriteDelegate delegate = new ConfigurationWriteDelegate(definition, connection, null); + + Configuration conf = new Configuration(); + PropertySimple ps = new PropertySimple("mode",null); + conf.put(ps); + + CompositeOperation cop = delegate.updateGenerateOperationFromProperties(conf, new Address()); + + assert cop.numberOfSteps() == 1; + Operation step1 = cop.step(0); + assert step1.getOperation().equals("write-attribute"); + Map<String, Object> props = step1.getAdditionalProperties(); + assert props.size() == 2; + assert props.get("name").equals("mode"); + assert props.get("value")==null; // no value + } + } diff --git a/modules/plugins/jboss-as-7/src/test/resources/test-plugin.xml b/modules/plugins/jboss-as-7/src/test/resources/test-plugin.xml index 4350230..f10f52b 100644 --- a/modules/plugins/jboss-as-7/src/test/resources/test-plugin.xml +++ b/modules/plugins/jboss-as-7/src/test/resources/test-plugin.xml @@ -290,6 +290,37 @@ </resource-configuration> </server>
+ <server name="simpleWithDefault1" + class="BaseComponent" + discovery="SubsystemDiscovery"> + + <resource-configuration> + <c:simple-property name="mode" required="true" type="string" readOnly="false" default="SYNC" defaultValue="SYNC" > + <c:property-options> + <c:option value="SYNC"/> + <c:option value="ASYNC"/> + </c:property-options> + </c:simple-property> + </resource-configuration> + + </server> + + <server name="simpleWithDefault2" + class="BaseComponent" + discovery="SubsystemDiscovery"> + + <resource-configuration> + <c:simple-property name="mode" required="true" type="string" readOnly="false" default="SYNC" > + <c:property-options> + <c:option value="SYNC"/> + <c:option value="ASYNC"/> + </c:property-options> + </c:simple-property> + </resource-configuration> + + </server> + + <!-- Simple c:group entries from descriptor with no special handling. --> <service name="simpleGroupNoSpecial" class="BaseComponent" @@ -327,4 +358,6 @@ </resource-configuration> </service>
+ + </plugin> \ No newline at end of file
commit 396b48fde3613c359b49ca4b776ee18fa39f3865 Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Aug 9 09:12:57 2012 -0400
[Bug 847014 - Resource tree not complete when more than 200 children] Allow an unlimited number of children when expanding the tree node. Although this may create a large vertical expansion, it may also be what the user wants. See BZ comments for more on the approach and alternatives but basically, take this [easy] approach until it's clear that users, or UX, want something else.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java index c072e13..2a5b827 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java @@ -43,6 +43,7 @@ import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceSubCategory; import org.rhq.core.domain.resource.ResourceType; +import org.rhq.core.domain.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.enterprise.gui.coregui.client.CoreGUI; import org.rhq.enterprise.gui.coregui.client.Messages; @@ -152,6 +153,8 @@ public class ResourceTreeDatasource extends DataSource {
ResourceCriteria criteria = new ResourceCriteria(); criteria.addFilterParentResourceId(Integer.parseInt(parentResourceId)); + // we don't need sorting since we get everything and the tree nodes are already sorted + criteria.setPageControl(PageControl.getUnlimitedInstance());
resourceService.findResourcesByCriteria(criteria, new AsyncCallback<PageList<Resource>>() { public void onFailure(Throwable caught) {
commit c1d401ff6c2b495cb599dfb66e0dd157b6442614 Author: Jay Shaughnessy jshaughn@redhat.com Date: Thu Aug 9 09:05:46 2012 -0400
[Bug 838683 - If RHQ server is down, UI shows "Server returned FAILURE with no error message"] More recent versions of Firefox, and possibly other browsers, have changed the request's response code in this situation. Added updated handling. Also, fixed an I18N issue.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/rpc/TrackingRequestCallback.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/rpc/TrackingRequestCallback.java index f461f6e..2702814 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/rpc/TrackingRequestCallback.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/rpc/TrackingRequestCallback.java @@ -18,7 +18,6 @@ */ package org.rhq.enterprise.gui.coregui.client.util.rpc;
-import java.util.logging.Logger; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.Response; @@ -38,6 +37,7 @@ public class TrackingRequestCallback implements RequestCallback { private long start = System.currentTimeMillis();
private static final int STATUS_CODE_OK = 200; + private static final int STATUS_CODE_ERROR_INTERNET_NO_RESPONSE = 0; private static final int STATUS_CODE_ERROR_INTERNET_CANNOT_CONNECT = 12029; private static final int STATUS_CODE_ERROR_INTERNET_CONNECTION_ABORTED = 12030;
@@ -69,7 +69,7 @@ public class TrackingRequestCallback implements RequestCallback { statusCode = response.getStatusCode(); statusText = response.getStatusText(); } catch (Throwable t) { - // If the server is unreachable or has terminated firefox will generate a JavaScript exception + // If the server is unreachable or has terminated firefox may generate a JavaScript exception // when trying to read the response object. Let the user know the server is unreachable. // (http://helpful.knobs-dials.com/index.php/0x80004005_%28NS_ERROR_FAILURE%29_a...)) if (UserSessionManager.isLoggedIn()) { @@ -90,13 +90,15 @@ public class TrackingRequestCallback implements RequestCallback { callback.onResponseReceived(request, response); break;
+ // these status codes are known to be returned from various browsers when the server is lost or not responding + case STATUS_CODE_ERROR_INTERNET_NO_RESPONSE: case STATUS_CODE_ERROR_INTERNET_CANNOT_CONNECT: case STATUS_CODE_ERROR_INTERNET_CONNECTION_ABORTED: RPCTracker.getInstance().failCall(this); // If the server is unreachable or has terminated, and the user is still logged in, // let them know the server is now unreachable. if (UserSessionManager.isLoggedIn()) { - CoreGUI.getErrorHandler().handleError("Server unreachable and may be down"); + CoreGUI.getErrorHandler().handleError(CoreGUI.getMessages().view_core_serverUnreachable()); } break;
commit 58c9ee2d6dd34ebce6b96aed0cbc35da27374165 Author: Jirka Kremser jkremser@redhat.com Date: Thu Aug 9 13:16:53 2012 +0200
Fixing the typo in constructor and bad usage of this constructor in 1 test
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java index 35c9367..84018a8 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java @@ -95,7 +95,7 @@ public class BundleCriteria extends TaggedCriteria { }
public void addFilterBundleTypeName(String filterBundleTypeName) { - this.filterName = filterBundleTypeName; + this.filterBundleTypeName = filterBundleTypeName; }
public void addFilterDescription(String filterDescription) { diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java index a4d43b8..1621dac 100644 --- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java +++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java @@ -952,7 +952,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test { // return bundle "two" using all criteria and with all optional data c.addFilterId(b.getId()); c.addFilterName(b.getName()); - c.addFilterBundleTypeName(b.getName()); + c.addFilterBundleTypeName(b.getBundleType().getName()); c.fetchBundleVersions(true); c.fetchRepo(true); bundles = bundleManager.findBundlesByCriteria(overlord, c);
commit 21e61a1588663c97975580003c00dfd8cbc20798 Author: Jirka Kremser jkremser@redhat.com Date: Thu Aug 9 13:12:03 2012 +0200
[BZ 822795 - Search filter not working in bundle deployment wizard] Added filtering by the name of the bundle.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/BundleSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/BundleSelector.java index 037bc10..eaa4371 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/BundleSelector.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/BundleSelector.java @@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.data.Criteria; +import com.smartgwt.client.data.DSRequest; import com.smartgwt.client.widgets.form.DynamicForm; import com.smartgwt.client.widgets.form.fields.SelectItem; import com.smartgwt.client.widgets.form.fields.TextItem; @@ -76,7 +77,7 @@ public class BundleSelector extends AbstractSelector<Bundle, BundleCriteria> { }
protected RPCDataSource<Bundle, BundleCriteria> getDataSource() { - return new BundlesDataSource(); + return new SelectedBundlesDataSource(); }
protected Criteria getLatestCriteria(DynamicForm availableFilterForm) { @@ -94,4 +95,15 @@ public class BundleSelector extends AbstractSelector<Bundle, BundleCriteria> { protected String getItemTitle() { return MSG.common_title_bundles(); } + + public class SelectedBundlesDataSource extends BundlesDataSource { + @Override + protected BundleCriteria getFetchCriteria(final DSRequest request) { + BundleCriteria result = super.getFetchCriteria(request); + if (null != result) { + result.setStrict(false); + } + return result; + } + } } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesDataSource.java index f8389b4..42a3e0d 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesDataSource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesDataSource.java @@ -90,28 +90,12 @@ public class BundlesDataSource extends RPCDataSource<Bundle, BundleCriteria> { @Override protected BundleCriteria getFetchCriteria(final DSRequest request) { BundleCriteria criteria = new BundleCriteria(); - - if (request.getCriteria().getValues().get("tagNamespace") != null) { - criteria.addFilterTagNamespace((String) request.getCriteria().getValues().get("tagNamespace")); - } - - if (request.getCriteria().getValues().get("tagSemantic") != null) { - criteria.addFilterTagSemantic((String) request.getCriteria().getValues().get("tagSemantic")); - } - - if (request.getCriteria().getValues().get("tagName") != null) { - criteria.addFilterTagName((String) request.getCriteria().getValues().get("tagName")); - } - - if (request.getCriteria().getValues().get("bundleType") != null) { - criteria.addFilterBundleTypeId(Integer.valueOf(request.getCriteria().getValues().get("bundleType") - .toString())); - } - - // TODO: this doesn't work like I think it should, figure out how to search on the name column - // if (request.getCriteria().getValues().get("search") != null) { - // criteria.setSearchExpression(request.getCriteria().getValues().get("search").toString()); - // } + criteria.addFilterTagNamespace(getFilter(request, "tagNamespace", String.class)); + criteria.addFilterTagSemantic(getFilter(request, "tagSemantic", String.class)); + criteria.addFilterTagName(getFilter(request, "tagName", String.class)); + criteria.addFilterBundleTypeId(getFilter(request, "bundleType", Integer.class)); + criteria.addFilterTagSemantic(getFilter(request, "tagSemantic", String.class)); + criteria.addFilterName(getFilter(request, "search", String.class));
return criteria; }
commit 88c286048d73a963eb2e2debd1009d8ed0d595b0 Author: Stefan Negrea snegrea@redhat.com Date: Wed Aug 8 16:04:19 2012 -0500
[BZ 837510] Prevent the edge case by retrieving the clustered property from AS5 only when the first metric collection occurs. Also marked the getter deprecated to prevent further use of the property outside of this component.
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextComponent.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextComponent.java index 6eb7e7e..07708b7 100644 --- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextComponent.java +++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/WebApplicationContextComponent.java @@ -82,7 +82,7 @@ public class WebApplicationContextComponent extends ManagedComponentComponent { private String servletComponentNamesRegex; private ResponseTimeLogParser logParser;
- private boolean clustered; + private Boolean clustered;
@Override public void start(ResourceContext<ProfileServiceComponent<?>> resourceContext) throws Exception { @@ -97,17 +97,6 @@ public class WebApplicationContextComponent extends ManagedComponentComponent { this.logParser.setExcludes(responseTimeConfig.getExcludes()); this.logParser.setTransforms(responseTimeConfig.getTransforms()); } - - try { - ManagedProperty distributableProp = getManagedComponent().getProperty(DISTRIBUTABLE_MANAGED_PROPERTY); - if (distributableProp != null) { - Boolean distributable = (Boolean) getInnerValue(distributableProp.getValue()); - clustered = distributable != null && distributable.booleanValue(); - } - } catch (Exception e) { - log.warn("Failed to determine whether the web app context " + resourceContext.getResourceKey() - + " is clustered or not.", e); - } }
@Override @@ -144,8 +133,14 @@ public class WebApplicationContextComponent extends ManagedComponentComponent { // TODO: Communicate this error back to the server for display in the GUI. } } else if (metricName.equals(CLUSTERED_TRAIT)) { - MeasurementDataTrait trait = new MeasurementDataTrait(request, Boolean.toString(clustered)); - report.addData(trait); + if(clustered == null){ + retrieveClusteredProperty(); + } + + if (clustered != null) { + MeasurementDataTrait trait = new MeasurementDataTrait(request, clustered.toString()); + report.addData(trait); + } } else { String metricNameToUse = metricName; if (clustered && !"runState".equals(metricName)) { @@ -170,10 +165,33 @@ public class WebApplicationContextComponent extends ManagedComponentComponent { } }
+ /** + * @deprecated The clustered property should be retrieved by the individual component in the + * specific use case that requires it. Leaving this method for backwards compatibility + * with plugins that use the AS5 plugin and also use reflection. + */ + @Deprecated public boolean isClustered() { + if (clustered == null) { + return false; + } + return clustered; }
+ private void retrieveClusteredProperty() { + try { + ManagedProperty distributableProp = getManagedComponent().getProperty(DISTRIBUTABLE_MANAGED_PROPERTY); + if (distributableProp != null) { + Boolean distributable = (Boolean) getInnerValue(distributableProp.getValue()); + clustered = distributable != null && distributable.booleanValue(); + } + } catch (Exception e) { + log.warn("Failed to determine whether the web app context " + this.getResourceContext().getResourceKey() + + " is clustered or not.", e); + } + } + private Double getServletMetric(ManagementView managementView, String metricName) throws Exception { ComponentType servletComponentType = MoreKnownComponentTypes.MBean.Servlet.getType(); //Set<ManagedComponent> servletComponents = managementView.getMatchingComponents(this.servletComponentNamesRegex,
commit 15552573391da403073ea1c27a8a9a5ffc969e65 Author: mtho11 mikecthompson@gmail.com Date: Wed Aug 8 11:45:51 2012 -0700
[BZ 845389 - Group without members with unknown status appears in every availability search result] Get rid of superfluous empty groups that show up as unknown availability.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java index 72f25a4..9f640dc 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java @@ -26,6 +26,7 @@ import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGro import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.PLUGIN; import static org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupDataSourceField.TYPE;
+import java.util.ArrayList; import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback; @@ -50,6 +51,7 @@ import org.rhq.enterprise.gui.coregui.client.ImageManager; import org.rhq.enterprise.gui.coregui.client.Messages; import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync; +import org.rhq.enterprise.gui.coregui.client.util.Log; import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource; import org.rhq.enterprise.gui.coregui.client.util.message.Message;
@@ -110,7 +112,7 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou }
@Override - public void executeFetch(final DSRequest request, final DSResponse response, ResourceGroupCriteria criteria) { + public void executeFetch(final DSRequest request, final DSResponse response, final ResourceGroupCriteria criteria ) { groupService.findResourceGroupCompositesByCriteria(criteria, new AsyncCallback<PageList<ResourceGroupComposite>>() { public void onFailure(Throwable caught) { @@ -123,10 +125,25 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou response.setStatus(RPCResponse.STATUS_FAILURE); processResponse(request.getRequestId(), response); } + + private PageList<ResourceGroupComposite> filterEmptyMemberGroups(ResourceGroupCriteria groupCriteria, + PageList<ResourceGroupComposite> result){ + + PageList<ResourceGroupComposite> pageList = new PageList<ResourceGroupComposite>(result.getPageControl()); + + for (ResourceGroupComposite rgc : result) { + if (rgc.getExplicitCount() > 0 ){ + pageList.add(rgc); + } + } + + return pageList; + }
public void onSuccess(PageList<ResourceGroupComposite> result) { - response.setData(buildRecords(result)); - response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set + PageList<ResourceGroupComposite> filteredResult = filterEmptyMemberGroups(criteria,result); + response.setData(buildRecords(filteredResult)); + response.setTotalRows(filteredResult.getTotalSize()); // for paging to work we have to specify size of full result set processResponse(request.getRequestId(), response); } });
commit 8ead20e62a892e10b12ed70c20a8b1c4e55ff024 Author: mtho11 mikecthompson@gmail.com Date: Tue Aug 7 14:27:26 2012 -0700
Add i18n messages for ResourceGroupCompositeDataSource
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java index 2abefa1..72f25a4 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupCompositeDataSource.java @@ -47,6 +47,7 @@ import org.rhq.core.domain.resource.group.composite.ResourceGroupComposite; import org.rhq.core.domain.util.PageList; import org.rhq.enterprise.gui.coregui.client.CoreGUI; import org.rhq.enterprise.gui.coregui.client.ImageManager; +import org.rhq.enterprise.gui.coregui.client.Messages; import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync; import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource; @@ -57,6 +58,8 @@ import org.rhq.enterprise.gui.coregui.client.util.message.Message; */ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGroupComposite, ResourceGroupCriteria> {
+ private static final Messages MSG = CoreGUI.getMessages(); + public static final String FILTER_GROUP_IDS = "resourceGroupIds";
ResourceGroupGWTServiceAsync groupService = GWTServiceLookup.getResourceGroupService(); @@ -112,7 +115,7 @@ public class ResourceGroupCompositeDataSource extends RPCDataSource<ResourceGrou new AsyncCallback<PageList<ResourceGroupComposite>>() { public void onFailure(Throwable caught) { if (caught.getMessage().contains("SearchExpressionException")) { - Message message = new Message("Invalid search expression.", Message.Severity.Error); + Message message = new Message(MSG.search_invalid_search_expression(), Message.Severity.Error); CoreGUI.getMessageCenter().notify(message); } else { CoreGUI.getErrorHandler().handleError(MSG.view_inventory_groups_loadFailed(), caught); diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties index a558db1..f9b75f3 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties @@ -413,6 +413,7 @@ filter_from_date = From filter_to_date = To group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = {0} out of {1} group members have a ''{2}'' resource +search_invalid_search_expression = Invalid search expression. search_failed_to_save_search = Failed to Save Search: {0} search_failed_to_retrieve_saved_search = Failed to retrieve saved search search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties index b146b3d..11c4488 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_cs.properties @@ -432,6 +432,7 @@ filter_from_date = Od filter_to_date = Do group_tree_groupOfResourceType = Skupina: [{0}] group_tree_partialClusterTooltip = {0} z {1} členů skupiny má "{2}" zdroj +##search_invalid_search_expression = Invalid search expression. ##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties index 7b9effe..71d8367 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties @@ -397,6 +397,7 @@ filter_from_date = Von filter_to_date = Bis ##group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = {0} der {1} Gruppenmitglieder haben eine ''{2}'' Ressource +##search_invalid_search_expression = Invalid search expression. ##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties index b7c191e..33e39c8 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ja.properties @@ -410,6 +410,7 @@ filter_from_date = 開始 filter_to_date = 終了 ##group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = {1} の中の {0} グループメンバーが ''{2}'' リソースを持っています +##search_invalid_search_expression = Invalid search expression. ##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties index 72b2f34..2c1af7e 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_pt.properties @@ -416,6 +416,7 @@ favorites_resources = Recursos Favoritos ##filter_to_date = To ##group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = {0} out of {1} group members have a ''{2}'' resource +##search_invalid_search_expression = Invalid search expression. ##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties index 5a44858..29a3fa6 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_ru.properties @@ -403,6 +403,7 @@ #filter_from_date = From #filter_to_date = To #group_tree_partialClusterTooltip = {0} out of {1} group members have a ''{2}'' resource +##search_invalid_search_expression = Invalid search expression. ##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties index 6ae9e47..cd7f97f 100644 --- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties +++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_zh.properties @@ -405,6 +405,7 @@ favorites_resources = \u8d44\u6e90\u6536\u85cf\u5939 ##filter_to_date = To ##group_tree_groupOfResourceType = Group of [{0}] group_tree_partialClusterTooltip = \u9664\u53bb {1},{0}\u7684\u7ec4\u6210\u5458\u62e5\u6709 \u4e00\u4e2a''{2}''\u8d44\u6e90 +##search_invalid_search_expression = Invalid search expression. ##search_failed_to_save_search = Failed to Save Search: {0} ##search_failed_to_retrieve_saved_search = Failed to retrieve saved search ##search_failed_to_retrieve_search_suggestion = Failed to retrieve search suggestion
commit b97ed4379723df4bd78d5a101094ada80097025e Author: Stefan Negrea snegrea@redhat.com Date: Wed Aug 8 11:37:36 2012 -0500
[BZ 836527] Added a create content method for backwards compatiblity with the SOA-P plugin.
diff --git a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java index f82b5ec..6b967b8 100644 --- a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java +++ b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java @@ -84,15 +84,14 @@ public class FileContentDelegate { }
/** - * Creates a new package described by the specified details. The destination of the content in the provided input - * stream will be determined by the package name. + * Creates a new package described by the specified details. The destination of the content in the provided + * file will be determined by the package name. * * @param details describes the package being created - * @param content content to be written for the package. NOTE this Stream will be closed by this method. + * @param sourceContentFile content file to be written for the package. * @param unzip if <code>true</code>, the content stream will be treated like a ZIP file and be unzipped as * it is written, using the package name as the base directory; if <code>false</code> the * @param createBackup If <code>true</code>, the original file will be backed up to file.bak - * @param shaString the SHA-256 of the specified input stream */ public void createContent(PackageDetails details, File sourceContentFile, boolean unzip, boolean createBackup) { File destinationContentFile = getPath(details); @@ -115,6 +114,37 @@ public class FileContentDelegate { }
/** + * Creates a new package described by the specified details. The destination of the content in the provided input + * stream will be determined by the package name. + * + * @param details describes the package being created + * @param content content to be written for the package. NOTE this Stream will be closed by this method. + * @param unzip if <code>true</code>, the content stream will be treated like a ZIP file and be unzipped as + * it is written, using the package name as the base directory; if <code>false</code> the + * @param createBackup If <code>true</code>, the original file will be backed up to file.bak + * @deprecated Method deprecated because of SHA256 computations. Method added only for backwards compatibility with SOA-P plugin. + * Replaced by {@link #createContent(PackageDetails, File, boolean, boolean)} + */ + @Deprecated + public void createContent(PackageDetails details, InputStream content, boolean unzip, boolean createBackup) { + File destinationContentFile = getPath(details); + try { + if (createBackup) { + moveToBackup(destinationContentFile, ".bak"); + } + if (unzip) { + ZipUtil.unzipFile(content, destinationContentFile); + computeAndSaveSHA(destinationContentFile); + } else { + FileUtil.writeFile(content, destinationContentFile); + } + details.setFileName(destinationContentFile.getPath()); + } catch (IOException e) { + throw new RuntimeException("Error creating artifact from details: " + destinationContentFile, e); + } + } + + /** * Try to move the passed contentFile to a backup named contentFile + suffix * @param contentFile File object pointing to the original file * @param suffix the suffix to tack on
commit 581324eeb3d32f4d8879d4749423fbde0f76de8c Author: Lukas Krejci lkrejci@redhat.com Date: Wed Aug 8 13:41:26 2012 +0200
[BZ 846623] - When creating the "child" alert definitions of group or template alert definitions, pass the real user that creates the alert def and circumvent authz. This behaves exactly the same as before but instead of bypassing the authz by passing the overlord when creating the child alert, a new local SLSB method is used that doesn't perform the authz checks and can therefore receive the original user that request the creation of the group/template alert def.
This is good for the CLI alert sender that, when creating an alert script to be run as "myself", checks if the user creating the alert def is the same as the one set to run it.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java index c4fdcda..927ae74 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerBean.java @@ -196,9 +196,23 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal, return results; }
+ @Override + @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) + public int createDependentAlertDefinition(Subject subject, AlertDefinition alertDefinition, int resourceId) + throws InvalidAlertDefinitionException { + + return createAlertDefinitionInternal(subject, alertDefinition, resourceId, false); + } + + @Override @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public int createAlertDefinition(Subject subject, AlertDefinition alertDefinition, Integer resourceId) throws InvalidAlertDefinitionException { + + return createAlertDefinitionInternal(subject, alertDefinition, resourceId, true); + } + + private int createAlertDefinitionInternal(Subject subject, AlertDefinition alertDefinition, Integer resourceId, boolean checkPerms) throws InvalidAlertDefinitionException { checkAlertDefinition(subject, alertDefinition, resourceId);
// if this is an alert definition, set up the link to a resource @@ -212,7 +226,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal, }
// after the resource is set up (in the case of non-templates), we can use the checkPermission on it - if (checkPermission(subject, alertDefinition) == false) { + if (checkPerms && checkPermission(subject, alertDefinition) == false) { if (alertDefinition.getResourceType() != null) { throw new PermissionException("User [" + subject.getName() + "] does not have permission to create alert templates for type [" @@ -265,7 +279,7 @@ public class AlertDefinitionManagerBean implements AlertDefinitionManagerLocal,
return alertDefinition.getId(); } - + private void fixRecoveryId(AlertDefinition definition) { try { if (definition.getParentId() != 0 && definition.getRecoveryId() != 0) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerLocal.java index d663198..81f0ac0 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertDefinitionManagerLocal.java @@ -48,6 +48,25 @@ public interface AlertDefinitionManagerLocal { int createAlertDefinition(Subject subject, AlertDefinition alertDefinition, Integer resourceId) throws InvalidAlertDefinitionException;
+ /** + * This is exactly the same as {@link #createAlertDefinition(Subject, AlertDefinition, Integer)} but + * assumes the resource is part of a group (or has given resource type for templates) for which + * a group or template alert definition is being created. + * <p> + * This method assumes the caller already checked the subject has permissions to create a group or template alert + * definition on a group / resource type the resource is member of. + * <p> + * In another words this method is a helper to + * {@link GroupAlertDefinitionManagerLocal#createGroupAlertDefinitions(Subject, AlertDefinition, Integer)} and + * {@link AlertTemplateManagerLocal#createAlertTemplate(Subject, AlertDefinition, Integer)}. + * + * @param subject the user that is creating the group or template alert definition + * @param alertDefinition the alert definition on the resource + * @param resourceId the resource + * @return the id of the newly created alert definition + */ + int createDependentAlertDefinition(Subject subject, AlertDefinition alertDefinition, int resourceId); + boolean isEnabled(Integer definitionId);
boolean isTemplate(Integer definitionId); diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java index 5b4ad77..cda1e0f 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertTemplateManagerBean.java @@ -128,7 +128,6 @@ public class AlertTemplateManagerBean implements AlertTemplateManagerLocal { + alertTemplate.toSimpleString(), t); }
- Subject overlord = subjectManager.getOverlord(); Throwable firstThrowable = null;
List<Integer> resourceIdsForType = getCommittedResourceIdsNeedingTemplateApplication(user, alertTemplateId, @@ -140,8 +139,8 @@ public class AlertTemplateManagerBean implements AlertTemplateManagerLocal { AlertDefinition childAlertDefinition = new AlertDefinition(alertTemplate); childAlertDefinition.setParentId(alertTemplate.getId());
- // persist the child using overlord - alertDefinitionManager.createAlertDefinition(overlord, childAlertDefinition, resourceId); + // persist the child as a dependent alert definition + alertDefinitionManager.createDependentAlertDefinition(user, childAlertDefinition, resourceId); } catch (Throwable t) { // continue on error, create as many as possible if (firstThrowable == null) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/GroupAlertDefinitionManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/GroupAlertDefinitionManagerBean.java index cde2f04..6df9ae0 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/GroupAlertDefinitionManagerBean.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/GroupAlertDefinitionManagerBean.java @@ -137,6 +137,7 @@ public class GroupAlertDefinitionManagerBean implements GroupAlertDefinitionMana return list; }
+ @Override @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public int createGroupAlertDefinitions(Subject subject, AlertDefinition groupAlertDefinition, Integer resourceGroupId) throws InvalidAlertDefinitionException, AlertDefinitionCreationException { @@ -151,7 +152,6 @@ public class GroupAlertDefinitionManagerBean implements GroupAlertDefinitionMana + " with data " + groupAlertDefinition.toSimpleString(), t); }
- Subject overlord = subjectManager.getOverlord(); Throwable firstThrowable = null;
List<Integer> resourceIdsForGroup = getCommittedResourceIdsNeedingGroupAlertDefinitionApplication(subject, @@ -164,7 +164,7 @@ public class GroupAlertDefinitionManagerBean implements GroupAlertDefinitionMana childAlertDefinition.setGroupAlertDefinition(groupAlertDefinition);
// persist the child - alertDefinitionManager.createAlertDefinition(overlord, childAlertDefinition, resourceId); + alertDefinitionManager.createDependentAlertDefinition(subject, childAlertDefinition, resourceId); } catch (Throwable t) { // continue on error, create as many as possible if (firstThrowable == null) {
rhq-commits@lists.fedorahosted.org